Skip to content

Commit cd257ba

Browse files
authored
feat(i18n): add server-side i18n for notification agents (#2731)
1 parent 7861db4 commit cd257ba

32 files changed

Lines changed: 971 additions & 320 deletions

File tree

bin/check-i18n.js

Lines changed: 27 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,44 @@
11
#!/usr/bin/env node
2-
2+
/* eslint-disable @typescript-eslint/no-require-imports, no-console */
33
/**
44
* Check that i18n locale files are in sync with extracted messages.
5-
* Runs `pnpm i18n:extract` and compares en.json; exits 1 if they differ.
5+
* Runs extract script and compares en.json files; exits 1 if they differ.
66
*/
77
const { execSync } = require('child_process');
88
const fs = require('fs');
99
const path = require('path');
1010

11-
const localePath = path.join(
12-
__dirname,
13-
'..',
14-
'src',
15-
'i18n',
16-
'locale',
17-
'en.json'
18-
);
19-
const backupPath = `${localePath}.bak`;
11+
const targets = [
12+
path.join(__dirname, '..', 'src', 'i18n', 'locale', 'en.json'),
13+
path.join(__dirname, '..', 'server', 'i18n', 'locale', 'en.json'),
14+
];
15+
16+
const backups = targets.map((p) => `${p}.bak`);
2017

2118
try {
22-
fs.copyFileSync(localePath, backupPath);
19+
targets.forEach((p, i) => fs.copyFileSync(p, backups[i]));
2320
execSync('pnpm i18n:extract', { stdio: 'inherit' });
24-
const original = fs.readFileSync(backupPath, 'utf8');
25-
const extracted = fs.readFileSync(localePath, 'utf8');
26-
fs.unlinkSync(backupPath);
2721

28-
if (original !== extracted) {
29-
console.error(
30-
"i18n messages are out of sync. Please run 'pnpm i18n:extract' and commit the changes."
31-
);
22+
let outOfSync = false;
23+
for (let i = 0; i < targets.length; i++) {
24+
const original = fs.readFileSync(backups[i], 'utf8');
25+
const extracted = fs.readFileSync(targets[i], 'utf8');
26+
fs.unlinkSync(backups[i]);
27+
28+
if (original !== extracted) {
29+
console.error(
30+
`i18n messages are out of sync for ${path.basename(path.dirname(path.dirname(targets[i])))}. Please run 'pnpm i18n:extract' and commit the changes.`
31+
);
32+
outOfSync = true;
33+
}
34+
}
35+
36+
if (outOfSync) {
3237
process.exit(1);
3338
}
3439
} catch (err) {
35-
if (fs.existsSync(backupPath)) {
36-
fs.unlinkSync(backupPath);
37-
}
40+
backups.forEach((b) => {
41+
if (fs.existsSync(b)) fs.unlinkSync(b);
42+
});
3843
throw err;
3944
}

docs/using-seerr/notifications/discord.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,3 +29,11 @@ If you would like to override the name you configured for your bot in Discord, y
2929
### Bot Avatar URL (optional)
3030

3131
Similar to the bot username, you can override the avatar for your bot.
32+
33+
### Use Notification Recipient Locale
34+
35+
When enabled, notifications will be sent in the language of the user who triggered the notification (e.g., the user who made the request or reported the issue) based on their display language setting. When disabled, the **Notification Language** setting below is used instead.
36+
37+
### Notification Language
38+
39+
Sets the language for all notifications sent to this Discord channel. This option is only available when **Use Notification Recipient Locale** is disabled.

docs/using-seerr/notifications/email.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ sidebar_position: 1
1212
If the [Application URL](/using-seerr/settings/general#application-title) setting is configured in **Settings → General**, Seerr will explicitly set the origin server hostname when connecting to the SMTP host.
1313
:::
1414

15+
### Require User Email
16+
17+
When enabled, users will be required to provide a valid email address in their user settings. This is useful if you want to ensure all users can receive email notifications.
18+
1519
### Sender Name (optional)
1620

1721
Configure a friendly name for the email sender (e.g., "Seerr").

docs/using-seerr/notifications/gotify.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,7 @@ Add an application to your Gotify server, and set this field to the generated ap
1919
:::info
2020
Please refer to the [Gotify API documentation](https://gotify.net/docs) for more details on configuring these notifications.
2121
:::
22+
23+
### Notification Language
24+
25+
Sets the language for notifications sent to this Gotify server.

docs/using-seerr/notifications/ntfy.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,7 @@ Set the priority level for notifications. Options range from Minimum (1) to Urge
3131
:::info
3232
Please refer to the [ntfy.sh API documentation](https://docs.ntfy.sh/) for more details on configuring these notifications.
3333
:::
34+
35+
### Notification Language
36+
37+
Sets the language for notifications sent to this ntfy server.

docs/using-seerr/notifications/slack.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,7 @@ Simply [create a webhook](https://my.slack.com/services/new/incoming-webhook/) a
1515
:::info
1616
Please refer to the [Slack API documentation](https://api.slack.com/messaging/webhooks) for more details on configuring these notifications.
1717
:::
18+
19+
### Notification Language
20+
21+
Sets the language for notifications sent to this Slack channel.

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,14 @@
77
"preinstall": "npx only-allow pnpm",
88
"postinstall": "next telemetry disable",
99
"dev": "nodemon -e ts --watch server --watch seerr-api.yml -e .json,.ts,.yml -x ts-node -r tsconfig-paths/register --files --project server/tsconfig.json server/index.ts",
10-
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates && tsc-alias -p server/tsconfig.json",
10+
"build:server": "tsc --project server/tsconfig.json && copyfiles -u 2 server/templates/**/*.{html,pug} dist/templates && copyfiles -u 2 \"server/i18n/locale/*.json\" dist/i18n && tsc-alias -p server/tsconfig.json",
1111
"build:next": "next build",
1212
"build": "pnpm build:next && pnpm build:server",
1313
"lint": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\" --cache",
1414
"lintfix": "eslint \"./server/**/*.{ts,tsx}\" \"./src/**/*.{ts,tsx}\" --fix",
1515
"test": "node server/test/index.mts",
1616
"start": "NODE_ENV=production node dist/index.js",
17-
"i18n:extract": "ts-node --project server/tsconfig.json src/i18n/extractMessages.ts",
17+
"i18n:extract": "ts-node --project server/tsconfig.json server/i18n/extractMessages.ts",
1818
"migration:generate": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:generate -d server/datasource.ts",
1919
"migration:create": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:create -d server/datasource.ts",
2020
"migration:run": "ts-node -r tsconfig-paths/register --project server/tsconfig.json ./node_modules/typeorm/cli.js migration:run -d server/datasource.ts",
@@ -36,6 +36,7 @@
3636
"dependencies": {
3737
"@dr.pogodin/csurf": "^1.16.6",
3838
"@fontsource-variable/inter": "^5.2.8",
39+
"@formatjs/intl": "^4.1.4",
3940
"@formatjs/intl-displaynames": "6.8.13",
4041
"@formatjs/intl-locale": "3.1.1",
4142
"@formatjs/intl-pluralrules": "5.4.6",

pnpm-lock.yaml

Lines changed: 70 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)