{(() => {
const rawMarkdown = RichText.asText(content.markdown.richText);
@@ -77,7 +77,7 @@ const PrismicDocPost = ({ doc, location }) => {
-
+ {item.isTranslated && (
+
+ )}
{item.tags && item.tags.includes(RESPONSE_TAG) && (
diff --git a/site/gatsby-site/src/utils/Translator.js b/site/gatsby-site/src/scripts/Translator.js
similarity index 76%
rename from site/gatsby-site/src/utils/Translator.js
rename to site/gatsby-site/src/scripts/Translator.js
index e3a1ad72d8..1a2ae362b0 100644
--- a/site/gatsby-site/src/utils/Translator.js
+++ b/site/gatsby-site/src/scripts/Translator.js
@@ -8,7 +8,23 @@ const remarkStrip = require('strip-markdown');
const keys = ['text', 'title'];
+/**
+ * @typedef {Object} Reporter
+ * @property {function(string):void} log
+ * @property {function(string):void} error
+ * @property {function(string):void} warn
+ */
+
class Translator {
+ /**
+ * @param {Object} options
+ * @param {import('mongodb').MongoClient} options.mongoClient
+ * @param {Object} options.translateClient
+ * @param {string[]} options.languages
+ * @param {Reporter} options.reporter
+ * @param {string} [options.submissionDateStart]
+ * @param {boolean} [options.dryRun]
+ */
constructor({
mongoClient,
translateClient,
@@ -18,10 +34,6 @@ class Translator {
dryRun = process.env.TRANSLATE_DRY_RUN !== 'false',
}) {
this.translateClient = translateClient;
- /**
- * @type {import('mongodb').MongoClient}
- * @public
- */
this.mongoClient = mongoClient;
this.reporter = reporter;
this.languages = languages;
@@ -49,9 +61,12 @@ class Translator {
}, concurrency);
q.error((err, task) => {
- this.reporter.log(
+ this.reporter.error(
`Error translating report ${task.entry.report_number}, ${err.code} ${err.message}`
);
+ throw new Error(
+ `Translation process failed for report ${task.entry.report_number}. Error: ${err.code} - ${err.message}`
+ );
});
const alreadyTranslated = await this.getTranslatedReports({ items, language: to });
@@ -72,20 +87,26 @@ class Translator {
async getTranslatedReports({ items, language }) {
const originalIds = items.map((item) => item.report_number);
- const incidents = this.mongoClient.db('translations').collection(`reports_${language}`);
+ const reportsTranslatedCollection = this.mongoClient
+ .db('translations')
+ .collection(`reports_${language}`);
const query = {
report_number: { $in: originalIds },
$and: [...keys, 'plain_text'].map((key) => ({ [key]: { $exists: true } })),
};
- const translated = await incidents.find(query, { projection: { report_number: 1 } }).toArray();
+ const translated = await reportsTranslatedCollection
+ .find(query, { projection: { report_number: 1 } })
+ .toArray();
return translated;
}
async saveTranslatedReports({ items, language }) {
- const incidents = this.mongoClient.db('translations').collection(`reports_${language}`);
+ const reportsTranslatedCollection = this.mongoClient
+ .db('translations')
+ .collection(`reports_${language}`);
const translated = [];
@@ -97,7 +118,7 @@ class Translator {
translated.push({ report_number, text, title, plain_text });
}
- return incidents.insertMany(translated);
+ return reportsTranslatedCollection.insertMany(translated);
}
async translateReport({ entry, to }) {
@@ -125,6 +146,12 @@ class Translator {
}
async run() {
+ if (this.dryRun) {
+ this.reporter.warn(
+ 'Please set `TRANSLATE_DRY_RUN=false` to disable dry running of translation process.'
+ );
+ }
+
await this.mongoClient.connect();
let reportsQuery = {};
@@ -135,7 +162,7 @@ class Translator {
const errorMessage = `Translation process error: Invalid date format for TRANSLATE_SUBMISSION_DATE_START env variable: [${this.submissionDateStart}]`;
this.reporter.error(errorMessage);
- throw errorMessage;
+ throw new Error(errorMessage);
}
this.reporter.log(
@@ -143,7 +170,9 @@ class Translator {
);
reportsQuery = { date_submitted: { $gte: new Date(this.submissionDateStart) } };
} else {
- this.reporter.log(`Translating all incident reports`);
+ this.reporter.log(
+ `Translating all incident reports. (TRANSLATE_SUBMISSION_DATE_START env variable is not defined)`
+ );
}
const reports = await this.mongoClient
diff --git a/site/gatsby-site/src/scripts/translate-incident-reports.js b/site/gatsby-site/src/scripts/translate-incident-reports.js
deleted file mode 100644
index 8f3cf6e916..0000000000
--- a/site/gatsby-site/src/scripts/translate-incident-reports.js
+++ /dev/null
@@ -1,39 +0,0 @@
-/**
- * Invokes translation process without Gatsby build
- * Run with `node ./src/scripts/translate-incident-reports.js`
- */
-
-require('dotenv').config();
-
-const config = require('../../config');
-
-const { MongoClient } = require('mongodb');
-
-const { Translate } = require('@google-cloud/translate').v2;
-
-const Translator = require('../utils/Translator');
-
-const { getLanguages } = require('../../i18n');
-
-const reporter = { log: console.log };
-
-(async () => {
- console.log('Translating incident reports...');
-
- const mongoClient = new MongoClient(config.mongodb.translationsConnectionString);
-
- const translateClient = new Translate({ key: config.i18n.translateApikey });
-
- const translator = new Translator({
- mongoClient,
- translateClient,
- languages: getLanguages(),
- reporter,
- });
-
- await translator.run();
-
- console.log('Done');
-
- process.exit(0);
-})();
diff --git a/site/gatsby-site/src/scripts/translateReports.js b/site/gatsby-site/src/scripts/translateReports.js
new file mode 100644
index 0000000000..9a3448a897
--- /dev/null
+++ b/site/gatsby-site/src/scripts/translateReports.js
@@ -0,0 +1,60 @@
+require('dotenv').config();
+
+const config = require('../../config');
+
+const { MongoClient } = require('mongodb');
+
+const { Translate } = require('@google-cloud/translate').v2;
+
+const Translator = require('./Translator');
+
+const { getLanguages } = require('../../i18n');
+
+const reporter = { log: console.log, error: console.error, warn: console.warn };
+
+(async () => {
+ console.log('Translating incident reports...');
+
+ let mongoClient;
+
+ try {
+ // MongoDB client setup
+ mongoClient = new MongoClient(config.mongodb.translationsConnectionString);
+ try {
+ await mongoClient.connect();
+ } catch (mongoError) {
+ throw new Error(`Error connecting to MongoDB: ${mongoError.message}`);
+ }
+
+ // Google Translate client setup
+ if (!config.i18n.translateApikey) {
+ throw new Error('Google Translate API (GOOGLE_TRANSLATE_API_KEY) key is missing.');
+ }
+ const translateClient = new Translate({ key: config.i18n.translateApikey });
+
+ // Create Translator instance
+ const translator = new Translator({
+ mongoClient,
+ translateClient,
+ languages: getLanguages(),
+ reporter,
+ });
+
+ // Run the translation process
+ await translator.run();
+
+ console.log('Translation completed successfully.');
+ } catch (error) {
+ console.error('Error during the translation process:', error.message);
+ process.exit(1);
+ } finally {
+ if (mongoClient) {
+ try {
+ await mongoClient.close();
+ console.log('MongoDB connection closed gracefully.');
+ } catch (closeError) {
+ console.error('Error closing MongoDB connection:', closeError.message);
+ }
+ }
+ }
+})();
diff --git a/site/gatsby-site/src/templates/doc.js b/site/gatsby-site/src/templates/doc.js
index a11f9edfad..17d38678e7 100644
--- a/site/gatsby-site/src/templates/doc.js
+++ b/site/gatsby-site/src/templates/doc.js
@@ -44,7 +44,7 @@ export default function Doc(props) {
)}
+
{children}
>
diff --git a/site/gatsby-site/src/utils/cite.js b/site/gatsby-site/src/utils/cite.js
index a3b3021224..eee6092350 100644
--- a/site/gatsby-site/src/utils/cite.js
+++ b/site/gatsby-site/src/utils/cite.js
@@ -104,7 +104,14 @@ export const getTranslatedReports = ({ allMongodbAiidprodReports, translations,
(t) => t.report_number === r.report_number
);
- return translation ? { ...r, text: translation.text, title: translation.title } : { ...r };
+ return translation
+ ? {
+ ...r,
+ text: translation.text,
+ title: translation.title,
+ isTranslated: true, // Mark badge to display or not
+ }
+ : { ...r };
});
};