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 if (intval($csvLine['Target Words']) == 0) {
48 $name = $csvLine['Name'];
49 $name = str_replace($reportDelimiter, '', $name);
50 $languages = explode('; ', $csvLine['Languages']);
51 if (isset($reportMap[$name])) {
52 $languages = array_unique(array_merge($languages, $reportMap[$name]));
54 $reportMap[$name] = $languages;
58 function loadExistingReportIntoMap($reportDelimiter, $reportLocation) {
60 $reportData = file_get_contents($reportLocation);
61 } catch (Exception $exception) {
64 $reportLines = explode("\n", $reportData);
66 foreach ($reportLines as $reportLine) {
67 if (empty($reportLine)) continue;
68 [$name, $langs] = explode($reportDelimiter, $reportLine);
69 $splitLangs = explode('; ', $langs);
70 $reportMap[$name] = $splitLangs;
75 function exportTopMembersReport($key) {
76 $result = makeMemberExportReport($key);
78 $exportHash = $result->data->identifier;
79 echo "Waiting for Crowdin report to be generated...\n";
81 echo "Downloading Crowdin report...\n";
82 $csv = downloadMemberReport($exportHash, $key);
87 function makeMemberExportReport(string $key) {
88 $url = 'https://api.crowdin.com/api/v2/projects/377219/reports';
90 'name' => 'top-members',
92 'dateFrom' => '2019-10-01T00:00:00Z',
93 'dateTo' => date('Y-m-d') . 'T23:59:59Z',
99 curl_setopt($ch, CURLOPT_URL, $url);
100 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
101 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
102 curl_setopt($ch, CURLOPT_POST, true);
103 curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($postData));
104 curl_setopt($ch, CURLOPT_HTTPHEADER, [
105 'Content-Type: application/json',
106 'Authorization: Bearer ' . $key,
109 $result = curl_exec($ch);
110 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
111 $error = curl_error($ch);
113 throw new Exception($error);
118 $data = json_decode($result);
123 function downloadMemberReport(string $exportHash, string $key) {
125 'hash' => $exportHash,
128 $url = "https://api.crowdin.com/api/v2/projects/377219/reports/{$exportHash}/download";
130 curl_setopt($ch, CURLOPT_URL, $url);
131 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
132 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
133 curl_setopt($ch, CURLOPT_HTTPHEADER, [
134 'Content-Type: application/json',
135 'Authorization: Bearer ' . $key,
138 $result = curl_exec($ch);
140 $data = json_decode($result);
142 $downloadUrl = $data->data->url ?? null;
144 throw new Exception("Could not get report download URL. Download response data:\n" . $result);
147 return file_get_contents($downloadUrl);
151 * Convert a comma separated string into an associated array.
152 * @link http://gist.github.com/385876 (Modified)
153 * @author Jay Williams <http://myd3.com/> (Modified)
154 * @copyright Copyright (c) 2010, Jay Williams (Modified)
155 * @license http://www.opensource.org/licenses/mit-license.php MIT License
157 function csv_to_array(string $csvString): array
162 $lines = explode("\n", trim($csvString));
163 foreach ($lines as $line) {
164 $csvLine = str_getcsv($line);
168 $data[] = array_combine($header, $csvLine);