4 // Script to fetch translators from crowdin via the API
5 // and format into a BookStack attribution file.
6 $key = getenv('CROWDIN_ACCESS_TOKEN');
8 echo "A Crowdin access token with relevant report permissions needs to be set on [CROWDIN_ACCESS_TOKEN] environment variable to run this script";
12 // Get the location of the attribution report.
13 $reportLocation = getcwd() . '/.github/translators.txt';
14 if (!file_exists($reportLocation)) {
15 echo "Could not find the translators file at [{$reportLocation}]";
16 echo "Are you running this script from the BookStack root folder?";
20 $reportDelimiter = ' :: ';
22 echo "Loading existing data...\n";
23 $reportMap = loadExistingReportIntoMap($reportDelimiter, $reportLocation);
24 echo "Exporting members from Crowdin...\n";
25 $csvReport = exportTopMembersReport($key);
26 $csvData = csv_to_array($csvReport);
27 echo "Merging, formatting and writing report...\n";
28 mergeCsvDataIntoReportMap($reportMap, $csvData, $reportDelimiter);
29 formatAndWriteOutput($reportLocation, $reportMap, $reportDelimiter);
32 function formatAndWriteOutput(string $reportLocation, array $reportMap, string $reportDelimiter) {
33 $output = "Name :: Languages\n";
34 foreach ($reportMap as $name => $languages) {
35 if (count($languages) === 0 || (count($languages) === 1 && empty($languages[0]))) continue;
36 if ($name === 'Dan Brown (ssddanbrown)' || $name === 'Name') continue;
37 $output .= $name . $reportDelimiter . implode('; ', $languages) . "\n";
40 file_put_contents($reportLocation, $output);
43 function mergeCsvDataIntoReportMap(array &$reportMap, array $csvData, string $reportDelimiter) {
44 foreach ($csvData as $csvLine) {
45 $name = $csvLine['Name'];
46 $name = str_replace($reportDelimiter, '', $name);
47 $languages = explode('; ', $csvLine['Languages']);
48 if (isset($reportMap[$name])) {
49 $languages = array_unique(array_merge($languages, $reportMap[$name]));
51 $reportMap[$name] = $languages;
55 function loadExistingReportIntoMap($reportDelimiter, $reportLocation) {
57 $reportData = file_get_contents($reportLocation);
58 } catch (Exception $exception) {
61 $reportLines = explode("\n", $reportData);
63 foreach ($reportLines as $reportLine) {
64 if (empty($reportLine)) continue;
65 [$name, $langs] = explode($reportDelimiter, $reportLine);
66 $splitLangs = explode('; ', $langs);
67 $reportMap[$name] = $splitLangs;
72 function exportTopMembersReport($key) {
73 $result = makeMemberExportReport($key);
75 $exportHash = $result->data->identifier;
76 echo "Waiting for Crowdin report to be generated...\n";
78 echo "Downloading Crowdin report...\n";
79 $csv = downloadMemberReport($exportHash, $key);
84 function makeMemberExportReport(string $key) {
85 $url = 'https://api.crowdin.com/api/v2/projects/377219/reports';
87 'name' => 'top-members',
89 'dateFrom' => '2019-10-01T00:00:00Z',
90 'dateTo' => date('Y-m-d') . 'T23:59:59Z',
96 curl_setopt($ch, CURLOPT_URL, $url);
97 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
98 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
99 curl_setopt($ch, CURLOPT_POST, true);
100 curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
101 curl_setopt($ch, CURLOPT_HTTPHEADER, [
102 'Content-Type: application/json',
103 'Authorization: Bearer ' . $key,
106 $result = curl_exec($ch);
107 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
108 $error = curl_error($ch);
110 throw new Exception($error);
115 $data = json_decode($result);
120 function downloadMemberReport(string $exportHash, string $key) {
122 'hash' => $exportHash,
125 $url = "https://api.crowdin.com/api/v2/projects/377219/reports/{$exportHash}/download";
127 curl_setopt($ch, CURLOPT_URL, $url);
128 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
129 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
130 curl_setopt($ch, CURLOPT_HTTPHEADER, [
131 'Content-Type: application/json',
132 'Authorization: Bearer ' . $key,
135 $result = curl_exec($ch);
137 $data = json_decode($result);
139 $downloadUrl = $data->data->url ?? null;
141 throw new Exception("Could not get report download URL. Download response data:\n" . $result);
144 return file_get_contents($downloadUrl);
148 * Convert a comma separated string into an associated array.
149 * @link http://gist.github.com/385876 (Modified)
150 * @author Jay Williams <http://myd3.com/> (Modified)
151 * @copyright Copyright (c) 2010, Jay Williams (Modified)
152 * @license http://www.opensource.org/licenses/mit-license.php MIT License
154 function csv_to_array(string $csvString): array
159 $lines = explode("\n", trim($csvString));
160 foreach ($lines as $line) {
161 $csvLine = str_getcsv($line);
165 $data[] = array_combine($header, $csvLine);