Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Implement international language support #1494

Open
wants to merge 23 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
---
github: abraunegg
5 changes: 2 additions & 3 deletions Makefile.in
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ SOURCES = \
src/upload.d \
src/util.d \
src/progress.d \
src/arsd/cgi.d
src/arsd/cgi.d \
src/translations.d

ifeq ($(NOTIFICATIONS),yes)
SOURCES += src/notifications/notify.d src/notifications/dnotify.d
Expand Down Expand Up @@ -156,5 +157,3 @@ ifeq ($(COMPLETIONS),yes)
rm -f $(DESTDIR)$(BASH_COMPLETION_DIR)/onedrive
rm -f $(DESTDIR)$(FISH_COMPLETION_DIR)/onedrive.fish
endif


28 changes: 28 additions & 0 deletions contrib/translations/DE.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"language": "DE",
"list": [
{
"1": "Keine Benutzer- oder Systemkonfigurationsdatei gefunden, die Anwendungsstandardwerte verwendet",
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi,
I just saw this PR, did you by chance create the german translation automatically?
I think at least the first log message sounds a bit off.
I think this sounds better:
"Keine Benutzer- oder Systemkonfigurationsdatei gefunden, es werden die Standardwerte verwendet"

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@oohjio
Many thanks for looking at this PR in its very early stage of development.

This is a WIP at the moment. The DE.json is just a 'google' translate of the first few messages, so that I can ensure, when building the PR (as it is not complete), is able to provide the right 'translations' for the language being selected. I could have also used dummy text (eg 'asdfasdfasfdasfdasdf') .. but I didnt.

When this PR is ready, there will only be the EN-US.json file, with the community able to provide a language.json file, which then can be used / loaded into the application for folks to use.

Please keep an eye on this, and if you are interested in providing the DE.json when the main code changes are done, please create / update the file so that this feature can launch with accurate & correct language translations for Deutsche.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@abraunegg
Thanks for the reply.
I see, that makes sense,
Will keep an eye on this.

"2": "Systemkonfigurationsdatei erfolgreich geladen",
"3": "Die Systemkonfigurationsdatei weist Fehler auf. Bitte überprüfen Sie Ihre Konfiguration",
"4": "Konfigurationsdatei erfolgreich geladen",
"5": "Konfigurationsdatei hat Fehler - bitte überprüfen Sie Ihre Konfiguration",
"6": "Verwenden der Konfigurationsoption für globale Azure AD-Endpunkte",
"7": "Verwenden der Konfigurationsoption für Azure AD für Endpunkte der US-Regierung",
"8": "Verwenden der Konfigurationsoption für Azure AD für US Government Endpoints (DOD)",
"9": "Verwenden der Konfigurationsoption für Azure AD Germany",
"10": "Verwenden der Konfigurationsoption für Azure AD China, das von 21Vianet betrieben wird",
"11": "Unbekannter Azure AD-Endpunkt – mit globalen Azure AD-Endpunkten",
"12": "Unbekannter Schlüssel in der Konfigurationsdatei: ",
"13": "Fehlerhafte Konfigurationszeile: ",
"14": "Die Konfigurationsdatei wurde aktualisiert und überprüft, ob --resync erforderlich ist",
"15": "Eine Änderung der Anwendungskonfiguration wurde festgestellt, wenn eine --resync erforderlich ist",
"16": "DRY-RUN Konfiguriert. Die folgende Ausgabe zeigt, was passiert wäre",
"17": "Verwenden des Protokolldateiverzeichnisses: ",
"18": "Datenbankschema geändert, Resync erforderlich",
"19": "Gespeicherten Status löschen ...",
"20": "FEHLER: Microsoft OneDrive-API-Dienst kann nicht erreicht werden, Anwendung kann nicht initialisiert werden"

}
]
}
28 changes: 28 additions & 0 deletions contrib/translations/EN-US.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"language": "EN-US",
"list": [
{
"1": "No user or system config file found, using application defaults",
"2": "System configuration file successfully loaded",
"3": "System configuration file has errors - please check your configuration",
"4": "Configuration file successfully loaded",
"5": "Configuration file has errors - please check your configuration",
"6": "Using config option for Global Azure AD Endpoints",
"7": "Using config option for Azure AD for US Government Endpoints",
"8": "Using config option for Azure AD for US Government Endpoints (DOD)",
"9": "Using config option for Azure AD Germany",
"10": "Using config option for Azure AD China operated by 21Vianet",
"11": "Unknown Azure AD Endpoint - using Global Azure AD Endpoints",
"12": "Unknown key in config file: ",
"13": "Malformed config line: ",
"14": "config file has been updated, checking if --resync needed",
"15": "An application configuration change has been detected where a --resync is required",
"16": "DRY-RUN Configured. Output below shows what 'would' have occurred",
"17": "Using logfile dir: ",
"18": "Database schema changed, resync needed",
"19": "Deleting the saved status ...",
"20": "ERROR: Unable to reach Microsoft OneDrive API service, unable to initialize application"

}
]
}
70 changes: 51 additions & 19 deletions src/config.d
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import core.stdc.stdlib: EXIT_SUCCESS, EXIT_FAILURE, exit;
import std.file, std.string, std.regex, std.stdio, std.process, std.algorithm.searching, std.getopt, std.conv, std.path;
import std.algorithm.sorting: sort;
import selective;
import translations;
static import log;

final class Config
Expand Down Expand Up @@ -124,14 +125,15 @@ final class Config
// maximum time an operation is allowed to take
// This includes dns resolution, connecting, data transfer, etc.
longValues["operation_timeout"] = 3600;

// Webhook options
boolValues["webhook_enabled"] = false;
stringValues["webhook_public_url"] = "";
stringValues["webhook_listening_host"] = "";
longValues["webhook_listening_port"] = 8888;
longValues["webhook_expiration_interval"] = 3600 * 24;
longValues["webhook_renewal_interval"] = 3600 * 12;
// What language will be used for application output messaging - default EN-AU
stringValues["language_identifier"] = "EN-AU";

// DEVELOPER OPTIONS
// display_memory = true | false
Expand All @@ -146,7 +148,7 @@ final class Config
// - It may be desirable to see what options are being passed in to performSync() without enabling the full verbose debug logging
boolValues["display_sync_options"] = false;

// Determine the users home directory.
// Determine the users home directory.
// Need to avoid using ~ here as expandTilde() below does not interpret correctly when running under init.d or systemd scripts
// Check for HOME environment variable
if (environment.get("HOME") != ""){
Expand Down Expand Up @@ -213,8 +215,11 @@ final class Config
// Configure the applicable permissions for the folder
configDirName.setAttributes(returnRequiredDirectoryPermisions());
}

// Initialise the default language output as early as possible
translations.initialize();

// configDirName has a trailing /
// What has been determined as the 'user' and 'system' config directories?
if (!configDirName.empty) log.vlog("Using 'user' Config Dir: ", configDirName);
if (!systemConfigDirName.empty) log.vlog("Using 'system' Config Dir: ", systemConfigDirName);

Expand Down Expand Up @@ -249,18 +254,25 @@ final class Config
// Is there a system configuration file?
if (!exists(systemConfigFilePath)) {
// 'system' configuration file does not exist
log.vlog("No user or system config file found, using application defaults");
// "No user or system config file found, using application defaults"
log.vlog(provideLanguageTranslation(getValueString("language_identifier"),1));
return true;
} else {
// 'system' configuration file exists
// can we load the configuration file without error?
if (load(systemConfigFilePath)) {
// configuration file loaded without error
log.log("System configuration file successfully loaded");
// Load the User Language File if this was updated from the default
if (getValueString("language_identifier") != "EN-AU") {
translations.initializeUserConfiguredLanguageTranslations(getValueString("language_identifier"));
}
// "System configuration file successfully loaded"
log.log(provideLanguageTranslation(getValueString("language_identifier"),2));
return true;
} else {
// there was a problem loading the configuration file
log.log("System configuration file has errors - please check your configuration");
// "System configuration file has errors - please check your configuration"
log.log(provideLanguageTranslation(getValueString("language_identifier"),3));
return false;
}
}
Expand All @@ -269,11 +281,17 @@ final class Config
// can we load the configuration file without error?
if (load(userConfigFilePath)) {
// configuration file loaded without error
log.log("Configuration file successfully loaded");
// Load the User Language File if this was updated from the default
if (getValueString("language_identifier") != "EN-AU") {
translations.initializeUserConfiguredLanguageTranslations(getValueString("language_identifier"));
}
// "Configuration file successfully loaded"
log.log(provideLanguageTranslation(getValueString("language_identifier"),4));
return true;
} else {
// there was a problem loading the configuration file
log.log("Configuration file has errors - please check your configuration");
// "Configuration file has errors - please check your configuration",
log.log(provideLanguageTranslation(getValueString("language_identifier"),5));
return false;
}
}
Expand Down Expand Up @@ -473,20 +491,26 @@ final class Config
&boolValues["list_business_shared_folders"],
"sync-shared-folders",
"Sync OneDrive Business Shared Folders",
&boolValues["sync_business_shared_folders"]
&boolValues["sync_business_shared_folders"],
"export-translations",
"Export existing default application messages in JSON format",
&tmpBol

);
if (opt.helpWanted) {
outputLongHelp(opt.options);
exit(EXIT_SUCCESS);
}
} catch (GetOptException e) {
log.error(e.msg);
log.error("Try 'onedrive -h' for more information");
// "Please use 'onedrive --help' for further assistance in regards to running this application"
log.error(provideLanguageTranslation(getValueString("language_identifier"),27));
exit(EXIT_FAILURE);
} catch (Exception e) {
// error
log.error(e.msg);
log.error("Try 'onedrive -h' for more information");
// "Please use 'onedrive --help' for further assistance in regards to running this application"
log.error(provideLanguageTranslation(getValueString("language_identifier"),27));
exit(EXIT_FAILURE);
}
}
Expand Down Expand Up @@ -614,23 +638,29 @@ final class Config
string azureConfigValue = c.front.dup;
switch(azureConfigValue) {
case "":
log.log("Using config option for Global Azure AD Endpoints");
// "Using config option for Global Azure AD Endpoints"
log.log(provideLanguageTranslation(getValueString("language_identifier"),6));
break;
case "USL4":
log.log("Using config option for Azure AD for US Government Endpoints");
// "Using config option for Azure AD for US Government Endpoints"
log.log(provideLanguageTranslation(getValueString("language_identifier"),7));
break;
case "USL5":
log.log("Using config option for Azure AD for US Government Endpoints (DOD)");
// "Using config option for Azure AD for US Government Endpoints (DOD)"
log.log(provideLanguageTranslation(getValueString("language_identifier"),8));
break;
case "DE":
log.log("Using config option for Azure AD Germany");
// "Using config option for Azure AD Germany"
log.log(provideLanguageTranslation(getValueString("language_identifier"),9));
break;
case "CN":
log.log("Using config option for Azure AD China operated by 21Vianet");
// "Using config option for Azure AD China operated by 21Vianet"
log.log(provideLanguageTranslation(getValueString("language_identifier"),10));
break;
// Default - all other entries
default:
log.log("Unknown Azure AD Endpoint - using Global Azure AD Endpoints");
// "Unknown Azure AD Endpoint - using Global Azure AD Endpoints"
log.log(provideLanguageTranslation(getValueString("language_identifier"),11));
}
}
} else {
Expand All @@ -639,13 +669,15 @@ final class Config
c.popFront();
setValueLong(key, to!long(c.front.dup));
} else {
log.log("Unknown key in config file: ", key);
// "Unknown key in config file: "
log.log(provideLanguageTranslation(getValueString("language_identifier"),12), key);
return false;
}
}
}
} else {
log.log("Malformed config line: ", lineBuffer);
// "Malformed config line: "
log.log(provideLanguageTranslation(getValueString("language_identifier"),13), lineBuffer);
return false;
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/itemdb.d
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import std.stdio;
import std.algorithm.searching;
import core.stdc.stdlib;
import sqlite;
import translations;
static import log;

enum ItemType {
Expand Down Expand Up @@ -42,23 +43,30 @@ final class ItemDatabase
string selectItemByIdStmt;
string selectItemByParentIdStmt;
string deleteItemByIdStmt;

string languageIdentifier;

this(const(char)[] filename)
{
languageIdentifier = getConfigLanguageIdentifier();

writeln("itemdb.d languageIdentifier: ", languageIdentifier);

db = Database(filename);
int dbVersion;

try {
dbVersion = db.getVersion();
} catch (SqliteException e) {
// An error was generated - what was the error?
log.error("\nAn internal database error occurred: " ~ e.msg ~ "\n");
log.error(provideLanguageTranslation(languageIdentifier,331) ~ e.msg ~ "\n");
exit(-1);
}

if (dbVersion == 0) {
createTable();
} else if (db.getVersion() != itemDatabaseVersion) {
log.log("The item database is incompatible, re-creating database table structures");
// "The item database is incompatible, re-creating database table structures"
log.log(provideLanguageTranslation(languageIdentifier,332));
db.exec("DROP TABLE item");
createTable();
}
Expand Down
Loading