mirror of
https://github.com/hrfee/jfa-go.git
synced 2024-12-29 12:30:11 +00:00
Compare commits
6 Commits
fe62422a2a
...
75796a3981
Author | SHA1 | Date | |
---|---|---|---|
75796a3981 | |||
781047058f | |||
0ac61a59b2 | |||
732ed5b0b8 | |||
42ddbab6cf | |||
432d795880 |
3
.gitignore
vendored
3
.gitignore
vendored
@ -9,3 +9,6 @@ docs/*
|
||||
lang/langtostruct.py
|
||||
config-payload.json
|
||||
!docs/go.mod
|
||||
server.key
|
||||
server.pem
|
||||
server.crt
|
||||
|
@ -1,5 +1,5 @@
|
||||
#### Translation
|
||||
Currently only the account creation form can be translated. Strings are defined in `lang/form/<country-code>.json` (country code as in `en-us`, `fr-fr`, e.g). You can see the existing ones [here](https://github.com/hrfee/jfa-go/tree/main/lang/form).
|
||||
Currently the admin page, account creation form and emails can be translated. Strings are defined in `lang/<admin/form/email>/<country-code>.json` (country code as in `en-us`, `fr-fr`, e.g). You can see the existing ones [here](https://github.com/hrfee/jfa-go/tree/main/lang).
|
||||
Make sure to define `name` in the `meta` section, and you can optionally add an `author` value there as well. If you can, make a pull request with your new file. If not, email me or create an issue.
|
||||
|
||||
#### Code
|
||||
|
27
api.go
27
api.go
@ -1087,7 +1087,7 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
||||
// Load language options
|
||||
loadLangs := func(langs *map[string]map[string]interface{}, settingsKey string) (string, []string) {
|
||||
langOptions := make([]string, len(*langs))
|
||||
chosenLang := app.config.Section("ui").Key("language-" + settingsKey).MustString("en-us")
|
||||
chosenLang := app.config.Section("ui").Key("language" + settingsKey).MustString("en-us")
|
||||
chosenLangName := (*langs)[chosenLang]["meta"].(map[string]interface{})["name"].(string)
|
||||
i := 0
|
||||
for _, lang := range *langs {
|
||||
@ -1096,14 +1096,25 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
||||
}
|
||||
return chosenLangName, langOptions
|
||||
}
|
||||
formChosen, formOptions := loadLangs(&app.storage.lang.Form, "form")
|
||||
formChosen, formOptions := loadLangs(&app.storage.lang.Form, "-form")
|
||||
fl := resp.Sections["ui"].Settings["language-form"]
|
||||
fl.Options = formOptions
|
||||
fl.Value = formChosen
|
||||
adminChosen, adminOptions := loadLangs(&app.storage.lang.Admin, "admin")
|
||||
adminChosen, adminOptions := loadLangs(&app.storage.lang.Admin, "-admin")
|
||||
al := resp.Sections["ui"].Settings["language-admin"]
|
||||
al.Options = adminOptions
|
||||
al.Value = adminChosen
|
||||
emailOptions := make([]string, len(app.storage.lang.Email))
|
||||
chosenLang := app.config.Section("email").Key("language").MustString("en-us")
|
||||
emailChosen := app.storage.lang.Email.get(chosenLang, "meta", "name")
|
||||
i := 0
|
||||
for langName := range app.storage.lang.Email {
|
||||
emailOptions[i] = app.storage.lang.Email.get(langName, "meta", "name")
|
||||
i++
|
||||
}
|
||||
el := resp.Sections["email"].Settings["language"]
|
||||
el.Options = emailOptions
|
||||
el.Value = emailChosen
|
||||
for sectName, section := range resp.Sections {
|
||||
for settingName, setting := range section.Settings {
|
||||
val := app.config.Section(sectName).Key(settingName)
|
||||
@ -1121,10 +1132,11 @@ func (app *appContext) GetConfig(gc *gin.Context) {
|
||||
}
|
||||
resp.Sections["ui"].Settings["language-form"] = fl
|
||||
resp.Sections["ui"].Settings["language-admin"] = al
|
||||
resp.Sections["email"].Settings["language"] = el
|
||||
|
||||
t := resp.Sections["jellyfin"].Settings["type"]
|
||||
opts := make([]string, len(serverTypes))
|
||||
i := 0
|
||||
i = 0
|
||||
for _, v := range serverTypes {
|
||||
opts[i] = v
|
||||
i++
|
||||
@ -1169,6 +1181,13 @@ func (app *appContext) ModifyConfig(gc *gin.Context) {
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if section == "email" && setting == "language" {
|
||||
for key := range app.storage.lang.Email {
|
||||
if app.storage.lang.Email.get(key, "meta", "name") == value.(string) {
|
||||
tempConfig.Section("email").Key("language").SetValue(key)
|
||||
break
|
||||
}
|
||||
}
|
||||
} else if section == "jellyfin" && setting == "type" {
|
||||
for k, v := range serverTypes {
|
||||
if v == value.(string) {
|
||||
|
@ -219,6 +219,50 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"advanced": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
"name": "Advanced",
|
||||
"description": "Advanced settings."
|
||||
},
|
||||
"settings": {
|
||||
"tls": {
|
||||
"name": "TLS/HTTP2",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Enable TLS, and by extension HTTP2. This enables server push, where required files are pushed to the web browser before they request them, allowing quicker page loads."
|
||||
},
|
||||
"tls_port": {
|
||||
"name": "TLS Port",
|
||||
"depends_true": "tls",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "number",
|
||||
"value": 8057,
|
||||
"description": "Port to run TLS server on"
|
||||
},
|
||||
"tls_cert": {
|
||||
"name": "Path to TLS Certificate",
|
||||
"depends_true": "tls",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Path to .crt file. See jfa-go wiki for more info."
|
||||
},
|
||||
"tls_key": {
|
||||
"name": "Path to TLS Key file",
|
||||
"depends_true": "tls",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Path to .key file. See jfa-go wiki for more info."
|
||||
}
|
||||
}
|
||||
},
|
||||
"password_validation": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
|
@ -8,7 +8,7 @@
|
||||
window.notificationsEnabled = {{ .notifications }};
|
||||
window.emailEnabled = {{ .email_enabled }};
|
||||
window.ombiEnabled = {{ .ombiEnabled }};
|
||||
window.usernamesEnabled = {{ .username }};
|
||||
window.usernameEnabled = {{ .username }};
|
||||
window.langFile = JSON.parse({{ .language }});
|
||||
</script>
|
||||
{{ template "header.html" . }}
|
||||
@ -99,7 +99,7 @@
|
||||
<span class="heading">{{ .strings.settingsRestartRequired }} <span class="modal-close">×</span></span>
|
||||
<p class="content pb-1">{{ .strings.settingsRestartRequiredDescription }}</p>
|
||||
<div class="fr">
|
||||
<span class="button ~info !normal" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
|
||||
<span class="button ~info !normal mb-half" id="settings-apply-no-restart">{{ .strings.settingsApplyRestartLater }}</span>
|
||||
<span class="button ~critical !normal" id="settings-apply-restart">{{ .strings.settingsApplyRestartNow }}</span>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -22,17 +22,21 @@
|
||||
"delete": "Effacer",
|
||||
"submit": "Soumettre",
|
||||
"name": "Nom",
|
||||
"date": "Date",
|
||||
"username": "Nom d'utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"emailAddress": "Addresse Email",
|
||||
"lastActiveTime": "Dernière activité",
|
||||
"from": "De",
|
||||
"user": "Utilisateur",
|
||||
"aboutProgram": "A propros",
|
||||
"aboutProgram": "A propos",
|
||||
"version": "Version",
|
||||
"commitNoun": "Commettre",
|
||||
"newUser": "Nouvel utilisateur",
|
||||
"profile": "Profil",
|
||||
"success": "Succès",
|
||||
"error": "Erreur",
|
||||
"unknown": "Inconnu",
|
||||
"modifySettings": "Modifier les paramètres",
|
||||
"modifySettingsDescription": "Appliquez les paramètres à partir d'un profil existant ou obtenez-les directement auprès d'un utilisateur.",
|
||||
"applyHomescreenLayout": "Appliquer la disposition de l'écran d'accueil",
|
||||
@ -55,7 +59,47 @@
|
||||
"addProfile": "Ajouter un profil",
|
||||
"addProfileDescription": "Créez un utilisateur Jellyfin et configurez-le, puis sélectionnez-le ci-dessous. Lorsque ce profil est appliqué à une invitation, de nouveaux utilisateurs seront créés avec les paramètres. ",
|
||||
"addProfileNameOf": "Nom de profil",
|
||||
"addProfileStoreHomescreenLayout": "Enregistrer la disposition de l'écran d'accueil"
|
||||
"addProfileStoreHomescreenLayout": "Enregistrer la disposition de l'écran d'accueil",
|
||||
|
||||
"inviteNoUsersCreated": "Aucun pour l'instant!",
|
||||
"inviteUsersCreated": "Utilisateurs créer",
|
||||
"inviteNoProfile": "Aucun profil",
|
||||
"copy": "Copier",
|
||||
"inviteDateCreated": "Créer",
|
||||
"inviteRemainingUses": "Utilisations restantes",
|
||||
"inviteNoInvites": "Aucune",
|
||||
"inviteExpiresInTime": "Expires dans {n}",
|
||||
|
||||
"notifyEvent": "Notifier sur:",
|
||||
"notifyInviteExpiry": "À l'expiration",
|
||||
"notifyUserCreation": "à la création de l'utilisateur"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Adresse e-mail modifiée de {n}.",
|
||||
"userCreated": "L'utilisateur {n} a été créé.",
|
||||
"createProfile": "Profil créé {n}.",
|
||||
"saveSettings": "Les paramètres ont été enregistrés",
|
||||
"setOmbiDefaults": "Valeurs par défaut de Ombi.",
|
||||
"errorConnection": "Impossible de se connecter à jfa-go.",
|
||||
"error401Unauthorized": "Non autorisé. Essayez d'actualiser la page.",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "Les paramètres ont été appliqués, mais l'application de la disposition de l'écran d'accueil a peut-être échoué.",
|
||||
"errorHomescreenAppliedNoSettings": "La disposition de l'écran d'accueil a été appliquée, mais l'application des paramètres a peut-être échoué.",
|
||||
"errorSettingsFailed": "L'application a échoué.",
|
||||
"errorLoginBlank": "Le nom d'utilisateur et / ou le mot de passe sont vides",
|
||||
"errorUnknown": "Erreur inconnue.",
|
||||
"errorBlankFields": "Les champs sont vides",
|
||||
"errorDeleteProfile": "Échec de la suppression du profil {n}",
|
||||
"errorLoadProfiles": "Échec du chargement des profils.",
|
||||
"errorCreateProfile": "Échec de la création du profil {n}",
|
||||
"errorSetDefaultProfile": "Échec de la définition du profil par défaut",
|
||||
"errorLoadUsers": "Échec du chargement des utilisateurs.",
|
||||
"errorSaveSettings": "Impossible d'enregistrer les paramètres.",
|
||||
"errorLoadSettings": "Échec du chargement des paramètres.",
|
||||
"errorSetOmbiDefaults": "Impossible de stocker les valeurs par défaut d'Ombi.",
|
||||
"errorLoadOmbiUsers": "Échec du chargement des utilisateurs Ombi.",
|
||||
"errorChangedEmailAddress": "Impossible de modifier l'adresse e-mail de {n}.",
|
||||
"errorFailureCheckLogs": "Échec (vérifier la console / les journaux)",
|
||||
"errorPartialFailureCheckLogs": "Panne partielle (vérifier la console / les journaux)"
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@ -73,6 +117,14 @@
|
||||
"deleteUser": {
|
||||
"singular": "Supprimer l'utilisateur",
|
||||
"plural": "Supprimer les utilisateurs"
|
||||
},
|
||||
"deletedUser": {
|
||||
"singular": "Supprimer {n} utilisateur.",
|
||||
"plural": "Supprimer {n} utilisateurs."
|
||||
},
|
||||
"appliedSettings": {
|
||||
"singular": "Appliquer le paramètre {n} utilisteur.",
|
||||
"plural": "Appliquer les paramètres {n} utilisteurs."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,21 @@
|
||||
"author": "https://github.com/Cornichon420"
|
||||
},
|
||||
"userCreated": {
|
||||
"title": "Notification : Utilisateur créé",
|
||||
"aUserWasCreated": "Un utilisateur a été créé avec ce code {n}",
|
||||
"name": "Nom",
|
||||
"emailAddress": "Adresse",
|
||||
"time": "Date",
|
||||
"notificationNotice": ""
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"title": "Notification : Invitation expirée",
|
||||
"inviteExpired": "Invitation expirée.",
|
||||
"expiredAt": "Le code {n} a expiré à {n}.",
|
||||
"notificationNotice": ""
|
||||
},
|
||||
"passwordReset": {
|
||||
"title": "Réinitialisation de mot du passe demandée - Jellyfin",
|
||||
"helloUser": "Salut {n},",
|
||||
"someoneHasRequestedReset": "Quelqu'un vient de demander une réinitialisation du mot de passe via Jellyfin.",
|
||||
"ifItWasYou": "Si c'était bien toi, renseigne le code PIN en dessous.",
|
||||
@ -19,14 +27,16 @@
|
||||
"pin": "PIN"
|
||||
},
|
||||
"userDeleted": {
|
||||
"title": "Ton compte a été désactivé - Jellyfin",
|
||||
"yourAccountWasDeleted": "Ton compte Jellyfin a été supprimé.",
|
||||
"reason": "Motif"
|
||||
},
|
||||
"inviteEmail": {
|
||||
"title": "Invitation - Jellyfin",
|
||||
"hello": "Salut",
|
||||
"youHaveBeenInvited": "Tu a été invité à rejoindre Jellyfin.",
|
||||
"youHaveBeenInvited": "Tu as été invité à rejoindre Jellyfin.",
|
||||
"toJoin": "Pour continuer, suis le lien en dessous.",
|
||||
"inviteExpiry": "L'invitation expirera le {n}, à {n}, sout dans {n}, alors fais vite !",
|
||||
"inviteExpiry": "L'invitation expirera le {n}, à {n}, soit dans {n}, alors fais vite !",
|
||||
"linkButton": "Lien"
|
||||
}
|
||||
}
|
||||
|
20
main.go
20
main.go
@ -331,7 +331,12 @@ func start(asDaemon, firstCall bool) {
|
||||
|
||||
if !firstRun {
|
||||
app.host = app.config.Section("ui").Key("host").String()
|
||||
app.port = app.config.Section("ui").Key("port").MustInt(8056)
|
||||
if app.config.Section("advanced").Key("tls").MustBool(false) {
|
||||
app.info.Println("Using TLS/HTTP2")
|
||||
app.port = app.config.Section("advanced").Key("tls_port").MustInt(8057)
|
||||
} else {
|
||||
app.port = app.config.Section("ui").Key("port").MustInt(8056)
|
||||
}
|
||||
|
||||
if *HOST != app.host && *HOST != "" {
|
||||
app.host = *HOST
|
||||
@ -350,7 +355,6 @@ func start(asDaemon, firstCall bool) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
address = fmt.Sprintf("%s:%d", app.host, app.port)
|
||||
|
||||
app.debug.Printf("Loaded config file \"%s\"", app.configPath)
|
||||
@ -625,8 +629,16 @@ func start(asDaemon, firstCall bool) {
|
||||
Handler: router,
|
||||
}
|
||||
go func() {
|
||||
if err := SRV.ListenAndServe(); err != nil {
|
||||
app.err.Printf("Failure serving: %s", err)
|
||||
if app.config.Section("advanced").Key("tls").MustBool(false) {
|
||||
cert := app.config.Section("advanced").Key("tls_cert").MustString("")
|
||||
key := app.config.Section("advanced").Key("tls_key").MustString("")
|
||||
if err := SRV.ListenAndServeTLS(cert, key); err != nil {
|
||||
app.err.Printf("Failure serving: %s", err)
|
||||
}
|
||||
} else {
|
||||
if err := SRV.ListenAndServe(); err != nil {
|
||||
app.err.Printf("Failure serving: %s", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
app.quit = make(chan os.Signal)
|
||||
|
Loading…
Reference in New Issue
Block a user