4 // Script to fetch translators from crowdin via the API
5 // and format into a BookStack attribution file.
6 $key = getenv('CROWDIN_PROJECT_KEY');
8 echo "Crowdin project key needs to be set on [CROWDIN_PROJECT_KEY] 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 $reportMap = loadExistingReportIntoMap($reportDelimiter, $reportLocation);
23 $csvReport = exportTopMembersReport($key);
24 $csvData = csv_to_array($csvReport);
25 mergeCsvDataIntoReportMap($reportMap, $csvData, $reportDelimiter);
26 formatAndWriteOutput($reportLocation, $reportMap, $reportDelimiter);
28 function formatAndWriteOutput(string $reportLocation, array $reportMap, string $reportDelimiter) {
29 $output = "Name :: Languages\n";
30 foreach ($reportMap as $name => $languages) {
31 if (count($languages) === 0 || (count($languages) === 1 && empty($languages[0]))) continue;
32 if ($name === 'Dan Brown (ssddanbrown)' || $name === 'Name') continue;
33 $output .= $name . $reportDelimiter . implode('; ', $languages) . "\n";
36 file_put_contents($reportLocation, $output);
39 function mergeCsvDataIntoReportMap(array &$reportMap, array $csvData, string $reportDelimiter) {
40 foreach ($csvData as $csvLine) {
41 $name = $csvLine['Name'];
42 $name = str_replace($reportDelimiter, '', $name);
43 $languages = explode('; ', $csvLine['Languages']);
44 if (isset($reportMap[$name])) {
45 $languages = array_unique(array_merge($languages, $reportMap[$name]));
47 $reportMap[$name] = $languages;
51 function loadExistingReportIntoMap($reportDelimiter, $reportLocation) {
53 $reportData = file_get_contents($reportLocation);
54 } catch (Exception $exception) {
57 $reportLines = explode("\n", $reportData);
59 foreach ($reportLines as $reportLine) {
60 if (empty($reportLine)) continue;
61 [$name, $langs] = explode($reportDelimiter, $reportLine);
62 $splitLangs = explode('; ', $langs);
63 $reportMap[$name] = $splitLangs;
68 function exportTopMembersReport($key) {
69 $result = makeMemberExportReport($key);
71 $exportHash = $result->hash;
72 $csv = downloadMemberReport($exportHash, $key);
77 function makeMemberExportReport(string $key) {
78 $url = 'https://api.crowdin.com/api/project/bookstack/reports/top-members/export';
80 'date_from' => '2019-10-01',
81 'date_to' => date('Y-m-d'),
88 curl_setopt($ch, CURLOPT_URL, $url);
89 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
90 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
91 curl_setopt($ch, CURLOPT_POST, true);
92 curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
94 $result = curl_exec($ch);
95 $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
96 $error = curl_error($ch);
98 throw new Exception($error);
103 $data = json_decode($result);
108 function downloadMemberReport(string $exportHash, string $key) {
110 'hash' => $exportHash,
113 $url = 'https://api.crowdin.com/api/project/bookstack/reports/top-members/download';
114 $url .= '?' . http_build_query($params);
116 curl_setopt($ch, CURLOPT_URL, $url);
117 curl_setopt($ch, CURLOPT_TIMEOUT, 15);
118 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
120 $result = curl_exec($ch);
127 * Convert a comma separated string into an associated array.
128 * @link http://gist.github.com/385876 (Modified)
129 * @author Jay Williams <http://myd3.com/> (Modified)
130 * @copyright Copyright (c) 2010, Jay Williams (Modified)
131 * @license http://www.opensource.org/licenses/mit-license.php MIT License
133 function csv_to_array(string $csvString): array
138 $lines = explode("\n", trim($csvString));
139 foreach ($lines as $line) {
140 $csvLine = str_getcsv($line);
144 $data[] = array_combine($header, $csvLine);