mirror of
https://github.com/hrfee/jfa-go.git
synced 2026-03-18 21:50:33 +01:00
Compare commits
190 Commits
v0.4.0
...
accounts-l
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf12016315 | ||
|
|
b544931ee5 | ||
|
|
9cef626b28 | ||
|
|
708d382a3f | ||
|
|
f24ea4a5f8 | ||
|
|
6ddd09ff1f | ||
|
|
ddc560e862 | ||
|
|
6f452c62de | ||
|
|
76bb95098c | ||
|
|
0e241f56fb | ||
|
|
8ac3bb9711 | ||
|
|
ff62f8821a | ||
|
|
90c433443f | ||
|
|
8a37663c89 | ||
|
|
bc4015ac50 | ||
|
|
f13c0d78a8 | ||
|
|
cc3871adf6 | ||
|
|
3e52beef14 | ||
|
|
48403ce940 | ||
|
|
6564df8082 | ||
|
|
73202e1483 | ||
|
|
dc60e97415 | ||
|
|
ad40d7d8a9 | ||
|
|
f88f71d933 | ||
|
|
d688dd02c8 | ||
|
|
456c99d7db | ||
|
|
e4f03fac4b | ||
|
|
2cb72e1f48 | ||
|
|
d800b97f69 | ||
|
|
0674e04ee1 | ||
|
|
d56f321aad | ||
|
|
bedd2bbb23 | ||
|
|
27ef7ce560 | ||
|
|
775ebd3b1e | ||
|
|
49c7d83840 | ||
|
|
a30469f6ec | ||
|
|
045f9ef827 | ||
|
|
abc13575c9 | ||
|
|
958b824dbc | ||
|
|
7b5f5abd22 | ||
|
|
5b7060c6a3 | ||
|
|
bbcba005c0 | ||
|
|
11d8b90f88 | ||
|
|
b531ec9b50 | ||
|
|
79790303a9 | ||
|
|
11c45a67b3 | ||
|
|
413ea07cbd | ||
|
|
890148051f | ||
|
|
3ba5d1f3fd | ||
|
|
ef5a0c3f75 | ||
|
|
0323b2783b | ||
|
|
b1e8bc4a46 | ||
|
|
e3a33d102e | ||
|
|
b9a3ed1d74 | ||
|
|
cb0d4e8bd7 | ||
|
|
5ee7bdc55e | ||
|
|
35ed4e20f0 | ||
|
|
a5faf0699a | ||
|
|
cb249b30af | ||
|
|
bb1e3a2c72 | ||
|
|
540b8d7c13 | ||
|
|
99e524589c | ||
|
|
295343be85 | ||
|
|
6f61d2246d | ||
|
|
e0cd4ed379 | ||
|
|
9f3269bce7 | ||
|
|
464fabc3bb | ||
|
|
c187b948d9 | ||
|
|
eb85ee4d35 | ||
|
|
de6bc02ad8 | ||
|
|
d355b3167f | ||
|
|
6cd846dfd8 | ||
|
|
0c102f5324 | ||
|
|
f50596c4a1 | ||
|
|
5d289ce023 | ||
|
|
2722e8482d | ||
|
|
895dcf5a30 | ||
|
|
ac25c9cd7f | ||
|
|
47d00d1f27 | ||
|
|
6bab805528 | ||
|
|
6efd28d904 | ||
|
|
04329bf171 | ||
|
|
3d56b6864e | ||
|
|
e2e675e469 | ||
|
|
aceb98b4a0 | ||
|
|
b848faa2c0 | ||
|
|
ea04f5391e | ||
|
|
58e61e514a | ||
|
|
b91918b04d | ||
|
|
8032fa0bcc | ||
|
|
1f0c641610 | ||
|
|
37fa9345cf | ||
|
|
2c31032a1c | ||
|
|
aeb85486c4 | ||
|
|
4f5fe6723b | ||
|
|
53a8e6df51 | ||
|
|
f45409e456 | ||
|
|
34df600350 | ||
|
|
255640a385 | ||
|
|
442bcf7e4f | ||
|
|
3a8540a439 | ||
|
|
681038cbd4 | ||
|
|
bb8c450452 | ||
|
|
5e41de8edd | ||
|
|
47f7987210 | ||
|
|
3515aee8e8 | ||
|
|
23223f3925 | ||
|
|
f049973349 | ||
|
|
2cdef91d11 | ||
|
|
297ec33e8e | ||
|
|
dc55959df4 | ||
|
|
311b64acd1 | ||
|
|
89f11ab630 | ||
|
|
9c68a7970d | ||
|
|
18d619efa1 | ||
|
|
6490c67a6c | ||
|
|
8cdf87d72b | ||
|
|
46da6d0ddc | ||
|
|
89b9f0a4f9 | ||
|
|
887f1f7c71 | ||
|
|
c1f7b665d5 | ||
|
|
26fc6b7056 | ||
|
|
3d45db2606 | ||
|
|
91603945ef | ||
|
|
d6df3b980c | ||
|
|
d1185d0f5f | ||
|
|
f35132e182 | ||
|
|
09d22a9f2d | ||
|
|
b0ee05f07d | ||
|
|
bb33c11a6b | ||
|
|
728152a31c | ||
|
|
048f4bdf90 | ||
|
|
8c405b251f | ||
|
|
53ba09a2fe | ||
|
|
0d62c5ecfa | ||
|
|
44bb1e6803 | ||
|
|
6f69f3b8f5 | ||
|
|
d97576678d | ||
|
|
88bf4f9903 | ||
|
|
f07227e560 | ||
|
|
b197c678ef | ||
|
|
d13981b489 | ||
|
|
90d4681ae8 | ||
|
|
ce228630ce | ||
|
|
855fdee332 | ||
|
|
f8745636f2 | ||
|
|
aa07ff1682 | ||
|
|
4c3e310634 | ||
|
|
8b52330304 | ||
|
|
200dc1c91a | ||
|
|
531d4aaefc | ||
|
|
f8d98fb66f | ||
|
|
5b2472853b | ||
|
|
2dc234a94d | ||
|
|
fdb43b2c53 | ||
|
|
2161d1aa2f | ||
|
|
08c8534d39 | ||
|
|
9e7914e0b6 | ||
|
|
daebfec0a2 | ||
|
|
e81411cb9b | ||
|
|
6cdae16752 | ||
|
|
65a0c6cb23 | ||
|
|
36d0550bf9 | ||
|
|
92aee997da | ||
|
|
63e6f3a3fa | ||
|
|
bfafbad9dc | ||
|
|
4435fead5a | ||
|
|
e73715f30e | ||
|
|
f31e9c0d81 | ||
|
|
2d1a4737db | ||
|
|
91f89793da | ||
|
|
d201644a5b | ||
|
|
982dd001ef | ||
|
|
80bd4d134e | ||
|
|
92fda348cd | ||
|
|
ef3fdb7555 | ||
|
|
9eb30ffab3 | ||
|
|
0bf6c25a14 | ||
|
|
5bb7a7d30c | ||
|
|
85c9319dfd | ||
|
|
3fea051691 | ||
|
|
7826fdffeb | ||
|
|
1105605370 | ||
|
|
3de3dd426b | ||
|
|
0c7187d53f | ||
|
|
12db53d1eb | ||
|
|
cebde9d4c0 | ||
|
|
9395165916 | ||
|
|
a8daa2c77e | ||
|
|
49c873c858 |
@@ -39,7 +39,7 @@ before:
|
||||
- rm data/bundle.css
|
||||
- npx tailwindcss -i data/web/css/bundle.css -o data/web/css/bundle.css
|
||||
- mv data/crash.html data/html/
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- go install github.com/swaggo/swag/cmd/swag@latest
|
||||
- swag init -g main.go
|
||||
- mv data/web/css/bundle.css data/web/css/{{.Env.JFA_GO_CSS_VERSION}}bundle.css
|
||||
builds:
|
||||
|
||||
2
LICENSE
2
LICENSE
@@ -2,7 +2,7 @@
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Harvey Tindall
|
||||
Copyright (c) 2023 Harvey Tindall
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
30
Makefile
30
Makefile
@@ -52,11 +52,11 @@ endif
|
||||
DEBUG ?= off
|
||||
ifeq ($(DEBUG), on)
|
||||
SOURCEMAP := --sourcemap
|
||||
TYPECHECK := tsc -noEmit --project ts/tsconfig.json
|
||||
TYPECHECK := npx tsc -noEmit --project ts/tsconfig.json
|
||||
# jank
|
||||
COPYTS := rm -r $(DATA)/web/js/ts; cp -r tempts $(DATA)/web/js/ts
|
||||
UNCSS := cp $(DATA)/web/css/bundle.css $(DATA)/bundle.css
|
||||
TAILWIND := --content ""
|
||||
# TAILWIND := --content ""
|
||||
else
|
||||
LDFLAGS := -s -w $(LDFLAGS)
|
||||
SOURCEMAP :=
|
||||
@@ -80,7 +80,7 @@ npm:
|
||||
@if [ "$(GOESBUILD)" = "off" ]; then\
|
||||
npm install esbuild;\
|
||||
else\
|
||||
go get -u github.com/evanw/esbuild/cmd/esbuild;\
|
||||
go install github.com/evanw/esbuild/cmd/esbuild@latest;\
|
||||
fi
|
||||
|
||||
configuration:
|
||||
@@ -97,21 +97,21 @@ email:
|
||||
typescript:
|
||||
$(TYPECHECK)
|
||||
$(adding dark variants to typescript)
|
||||
-rm -r tempts
|
||||
rm -rf tempts
|
||||
cp -r ts tempts
|
||||
scripts/dark-variant.sh tempts
|
||||
scripts/dark-variant.sh tempts/modules
|
||||
$(info compiling typescript)
|
||||
-mkdir -p $(DATA)/web/js
|
||||
-$(ESBUILD) --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||
-$(ESBUILD) --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||
-$(ESBUILD) --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||
-$(ESBUILD) --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||
-$(ESBUILD) --bundle tempts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||
mkdir -p $(DATA)/web/js
|
||||
$(ESBUILD) --target=es6 --bundle tempts/admin.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/admin.js --minify
|
||||
$(ESBUILD) --target=es6 --bundle tempts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||
$(ESBUILD) --target=es6 --bundle tempts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||
$(ESBUILD) --target=es6 --bundle tempts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||
$(ESBUILD) --target=es6 --bundle tempts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||
$(COPYTS)
|
||||
|
||||
swagger:
|
||||
$(GOBINARY) install github.com/swaggo/swag/cmd/swag
|
||||
$(GOBINARY) install github.com/swaggo/swag/cmd/swag@latest
|
||||
swag init -g main.go
|
||||
|
||||
compile:
|
||||
@@ -125,7 +125,9 @@ compress:
|
||||
upx --lzma build/jfa-go
|
||||
|
||||
bundle-css:
|
||||
-mkdir -p $(DATA)/web/css
|
||||
mkdir -p $(DATA)/web/css
|
||||
$(info copying fonts)
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/
|
||||
$(info bundling css)
|
||||
$(ESBUILD) --bundle css/base.css --outfile=$(DATA)/web/css/bundle.css --external:remixicon.css --minify
|
||||
npx tailwindcss -i $(DATA)/web/css/bundle.css -o $(DATA)/web/css/bundle.css $(TAILWIND)
|
||||
@@ -144,12 +146,10 @@ variants-html:
|
||||
node scripts/missing-colors.js html $(DATA)/html
|
||||
|
||||
copy:
|
||||
$(info copying fonts)
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/
|
||||
$(info copying crash page)
|
||||
mv $(DATA)/crash.html $(DATA)/html/
|
||||
$(info copying static data)
|
||||
-mkdir -p $(DATA)/web
|
||||
mkdir -p $(DATA)/web
|
||||
cp -r static/* $(DATA)/web/
|
||||
$(info copying systemd service)
|
||||
cp jfa-go.service $(DATA)/
|
||||
|
||||
22
README.md
22
README.md
@@ -7,6 +7,21 @@
|
||||
|
||||
##### Downloads:
|
||||
##### [docker](#docker) | [debian/ubuntu](#debian) | [arch (aur)](#aur) | [other platforms](#other-platforms)
|
||||
|
||||
---
|
||||
|
||||
## Project Status
|
||||
Due to studies and general lack of enthusiasm for work on this project, new features are unlikely, and while occasionally I might fix a bug or two, I won't be supporting the project a lot.
|
||||
|
||||
#### Does it still work?
|
||||
jfa-go still appears to work on the latest version of Jellyfin (10.8.9), and unless any large architectural changes occur to it, functionality should still remain.
|
||||
|
||||
#### Alternatives
|
||||
None of these have been tested by myself, but I have seen them mentioned quite frequently.
|
||||
|
||||
* [Wizarr](https://github.com/Wizarrrr/wizarr) focuses on invites, and also includes some Discord & Ombi integration.
|
||||
* [Jellyseerr](https://github.com/Fallenbagel/jellyseerr) is a fork of Overseerr, which can manage users and mainly acts as an Ombi alternative.
|
||||
* [Organizr](https://github.com/causefx/Organizr) doesn't focus on Jellyfin, but allows putting self-hosted services into "tabs" on a central page, and allows creating users, which lets one control who can access what.
|
||||
---
|
||||
jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jellyfin) (and now [Emby](https://emby.media/)) that provides invite-based account creation as well as other features that make one's instance much easier to manage.
|
||||
|
||||
@@ -19,14 +34,15 @@ a rewrite of [jellyfin-accounts](https://github.com/hrfee/jellyfin-accounts) (or
|
||||
* Granular control over invites: Validity period as well as number of uses can be specified.
|
||||
* Account profiles: Assign settings profiles to invites so new users have your predefined permissions, homescreen layout, etc. applied to their account on creation.
|
||||
* Password validation: Ensure users choose a strong password.
|
||||
* CAPTCHAs can be enabled to avoid bots
|
||||
* ⌛ User expiry: Specify a validity period, and new users accounts will be disabled/deleted after it. The period can be manually extended too.
|
||||
* 🔗 Ombi Integration: Automatically creates Ombi accounts for new users using their email address and login details, and your own defined set of permissions.
|
||||
* Account management: Apply settings to your users individually or en masse, and delete users, optionally sending them an email notification with a reason.
|
||||
* Telegram/Discord/Matrix Integration: Verify users via a chat bot, and send Password Resets, Announcements, etc. through it.
|
||||
* 📨 Email storage: Add your existing users email addresses through the UI, and jfa-go will ask new users for them on account creation.
|
||||
* Email addresses can optionally be used instead of usernames
|
||||
* 🔑 Password resets: When users forget their passwords and request a change in Jellyfin, jfa-go reads the PIN from the created file and sends it straight to the user via email/telegram.
|
||||
* Notifications: Get notified when someone creates an account, or an invite expires.
|
||||
* 🔑 Password resets: When users forget their passwords and request a change in Jellyfin, jfa-go reads the PIN from the created file and sends it straight to them via email/telegram.
|
||||
* Admin Notifications: Get notified when someone creates an account, or an invite expires.
|
||||
* 📣 Announcements: Bulk message your users with announcements about your server.
|
||||
* Authentication via Jellyfin: Instead of using separate credentials for jfa-go and Jellyfin, jfa-go can use it as the authentication provider.
|
||||
* Enables the usage of jfa-go by multiple people
|
||||
@@ -150,7 +166,7 @@ If you're switching from jellyfin-accounts, copy your existing `~/.jf-accounts`
|
||||
(or specify config/data path with `-config/-data` respectively.)
|
||||
|
||||
#### Contributing
|
||||
See [CONTRIBUTING.md](https://github.com/hrfee/jfa-go/blob/main/CONTRIBUTING.md).
|
||||
See [the wiki page](https://wiki.jfa-go.com/docs/dev/) or [CONTRIBUTING.md](https://github.com/hrfee/jfa-go/blob/main/CONTRIBUTING.md).
|
||||
##### Translation
|
||||
[](https://weblate.jfa-go.com/engage/jfa-go/)
|
||||
|
||||
|
||||
432
api-invites.go
Normal file
432
api-invites.go
Normal file
@@ -0,0 +1,432 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/itchyny/timefmt-go"
|
||||
"github.com/lithammer/shortuuid/v3"
|
||||
)
|
||||
|
||||
func (app *appContext) checkInvites() {
|
||||
currentTime := time.Now()
|
||||
app.storage.loadInvites()
|
||||
changed := false
|
||||
for code, data := range app.storage.invites {
|
||||
expiry := data.ValidTill
|
||||
if !currentTime.After(expiry) {
|
||||
continue
|
||||
}
|
||||
app.debug.Printf("Housekeeping: Deleting old invite %s", code)
|
||||
notify := data.Notify
|
||||
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) && len(notify) != 0 {
|
||||
app.debug.Printf("%s: Expiry notification", code)
|
||||
var wait sync.WaitGroup
|
||||
for address, settings := range notify {
|
||||
if !settings["notify-expiry"] {
|
||||
continue
|
||||
}
|
||||
wait.Add(1)
|
||||
go func(addr string) {
|
||||
defer wait.Done()
|
||||
msg, err := app.email.constructExpiry(code, data, app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("%s: Failed to construct expiry notification: %v", code, err)
|
||||
} else {
|
||||
// Check whether notify "address" is an email address of Jellyfin ID
|
||||
if strings.Contains(addr, "@") {
|
||||
err = app.email.send(msg, addr)
|
||||
} else {
|
||||
err = app.sendByID(msg, addr)
|
||||
}
|
||||
if err != nil {
|
||||
app.err.Printf("%s: Failed to send expiry notification: %v", code, err)
|
||||
} else {
|
||||
app.info.Printf("Sent expiry notification to %s", addr)
|
||||
}
|
||||
}
|
||||
}(address)
|
||||
}
|
||||
wait.Wait()
|
||||
}
|
||||
changed = true
|
||||
delete(app.storage.invites, code)
|
||||
}
|
||||
if changed {
|
||||
app.storage.storeInvites()
|
||||
}
|
||||
}
|
||||
|
||||
func (app *appContext) checkInvite(code string, used bool, username string) bool {
|
||||
currentTime := time.Now()
|
||||
app.storage.loadInvites()
|
||||
changed := false
|
||||
inv, match := app.storage.invites[code]
|
||||
if !match {
|
||||
return false
|
||||
}
|
||||
expiry := inv.ValidTill
|
||||
if currentTime.After(expiry) {
|
||||
app.debug.Printf("Housekeeping: Deleting old invite %s", code)
|
||||
notify := inv.Notify
|
||||
if emailEnabled && app.config.Section("notifications").Key("enabled").MustBool(false) && len(notify) != 0 {
|
||||
app.debug.Printf("%s: Expiry notification", code)
|
||||
var wait sync.WaitGroup
|
||||
for address, settings := range notify {
|
||||
if !settings["notify-expiry"] {
|
||||
continue
|
||||
}
|
||||
wait.Add(1)
|
||||
go func(addr string) {
|
||||
defer wait.Done()
|
||||
msg, err := app.email.constructExpiry(code, inv, app, false)
|
||||
if err != nil {
|
||||
app.err.Printf("%s: Failed to construct expiry notification: %v", code, err)
|
||||
} else {
|
||||
// Check whether notify "address" is an email address of Jellyfin ID
|
||||
if strings.Contains(addr, "@") {
|
||||
err = app.email.send(msg, addr)
|
||||
} else {
|
||||
err = app.sendByID(msg, addr)
|
||||
}
|
||||
if err != nil {
|
||||
app.err.Printf("%s: Failed to send expiry notification: %v", code, err)
|
||||
} else {
|
||||
app.info.Printf("Sent expiry notification to %s", addr)
|
||||
}
|
||||
}
|
||||
}(address)
|
||||
}
|
||||
wait.Wait()
|
||||
}
|
||||
changed = true
|
||||
match = false
|
||||
delete(app.storage.invites, code)
|
||||
} else if used {
|
||||
changed = true
|
||||
del := false
|
||||
newInv := inv
|
||||
if newInv.RemainingUses == 1 {
|
||||
del = true
|
||||
delete(app.storage.invites, code)
|
||||
} else if newInv.RemainingUses != 0 {
|
||||
// 0 means infinite i guess?
|
||||
newInv.RemainingUses--
|
||||
}
|
||||
newInv.UsedBy = append(newInv.UsedBy, []string{username, strconv.FormatInt(currentTime.Unix(), 10)})
|
||||
if !del {
|
||||
app.storage.invites[code] = newInv
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
app.storage.storeInvites()
|
||||
}
|
||||
return match
|
||||
}
|
||||
|
||||
// @Summary Create a new invite.
|
||||
// @Produce json
|
||||
// @Param generateInviteDTO body generateInviteDTO true "New invite request object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Router /invites [post]
|
||||
// @Security Bearer
|
||||
// @tags Invites
|
||||
func (app *appContext) GenerateInvite(gc *gin.Context) {
|
||||
var req generateInviteDTO
|
||||
app.debug.Println("Generating new invite")
|
||||
app.storage.loadInvites()
|
||||
gc.BindJSON(&req)
|
||||
currentTime := time.Now()
|
||||
validTill := currentTime.AddDate(0, req.Months, req.Days)
|
||||
validTill = validTill.Add(time.Hour*time.Duration(req.Hours) + time.Minute*time.Duration(req.Minutes))
|
||||
// make sure code doesn't begin with number
|
||||
inviteCode := shortuuid.New()
|
||||
_, err := strconv.Atoi(string(inviteCode[0]))
|
||||
for err == nil {
|
||||
inviteCode = shortuuid.New()
|
||||
_, err = strconv.Atoi(string(inviteCode[0]))
|
||||
}
|
||||
var invite Invite
|
||||
if req.Label != "" {
|
||||
invite.Label = req.Label
|
||||
}
|
||||
invite.Created = currentTime
|
||||
if req.MultipleUses {
|
||||
if req.NoLimit {
|
||||
invite.NoLimit = true
|
||||
} else {
|
||||
invite.RemainingUses = req.RemainingUses
|
||||
}
|
||||
} else {
|
||||
invite.RemainingUses = 1
|
||||
}
|
||||
invite.UserExpiry = req.UserExpiry
|
||||
if invite.UserExpiry {
|
||||
invite.UserMonths = req.UserMonths
|
||||
invite.UserDays = req.UserDays
|
||||
invite.UserHours = req.UserHours
|
||||
invite.UserMinutes = req.UserMinutes
|
||||
}
|
||||
invite.ValidTill = validTill
|
||||
if req.SendTo != "" && app.config.Section("invite_emails").Key("enabled").MustBool(false) {
|
||||
addressValid := false
|
||||
discord := ""
|
||||
app.debug.Printf("%s: Sending invite message", inviteCode)
|
||||
if discordEnabled && !strings.Contains(req.SendTo, "@") {
|
||||
users := app.discord.GetUsers(req.SendTo)
|
||||
if len(users) == 0 {
|
||||
invite.SendTo = fmt.Sprintf("Failed: User not found: \"%s\"", req.SendTo)
|
||||
} else if len(users) > 1 {
|
||||
invite.SendTo = fmt.Sprintf("Failed: Multiple users found: \"%s\"", req.SendTo)
|
||||
} else {
|
||||
invite.SendTo = req.SendTo
|
||||
addressValid = true
|
||||
discord = users[0].User.ID
|
||||
}
|
||||
} else if emailEnabled {
|
||||
addressValid = true
|
||||
invite.SendTo = req.SendTo
|
||||
}
|
||||
if addressValid {
|
||||
msg, err := app.email.constructInvite(inviteCode, invite, app, false)
|
||||
if err != nil {
|
||||
invite.SendTo = fmt.Sprintf("Failed to send to %s", req.SendTo)
|
||||
app.err.Printf("%s: Failed to construct invite message: %v", inviteCode, err)
|
||||
} else {
|
||||
var err error
|
||||
if discord != "" {
|
||||
err = app.discord.SendDM(msg, discord)
|
||||
} else {
|
||||
err = app.email.send(msg, req.SendTo)
|
||||
}
|
||||
if err != nil {
|
||||
invite.SendTo = fmt.Sprintf("Failed to send to %s", req.SendTo)
|
||||
app.err.Printf("%s: %s: %v", inviteCode, invite.SendTo, err)
|
||||
} else {
|
||||
app.info.Printf("%s: Sent invite email to \"%s\"", inviteCode, req.SendTo)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if req.Profile != "" {
|
||||
if _, ok := app.storage.profiles[req.Profile]; ok {
|
||||
invite.Profile = req.Profile
|
||||
} else {
|
||||
invite.Profile = "Default"
|
||||
}
|
||||
}
|
||||
app.storage.invites[inviteCode] = invite
|
||||
app.storage.storeInvites()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Get invites.
|
||||
// @Produce json
|
||||
// @Success 200 {object} getInvitesDTO
|
||||
// @Router /invites [get]
|
||||
// @Security Bearer
|
||||
// @tags Invites
|
||||
func (app *appContext) GetInvites(gc *gin.Context) {
|
||||
app.debug.Println("Invites requested")
|
||||
currentTime := time.Now()
|
||||
app.storage.loadInvites()
|
||||
app.checkInvites()
|
||||
var invites []inviteDTO
|
||||
for code, inv := range app.storage.invites {
|
||||
_, months, days, hours, minutes, _ := timeDiff(inv.ValidTill, currentTime)
|
||||
invite := inviteDTO{
|
||||
Code: code,
|
||||
Months: months,
|
||||
Days: days,
|
||||
Hours: hours,
|
||||
Minutes: minutes,
|
||||
UserExpiry: inv.UserExpiry,
|
||||
UserMonths: inv.UserMonths,
|
||||
UserDays: inv.UserDays,
|
||||
UserHours: inv.UserHours,
|
||||
UserMinutes: inv.UserMinutes,
|
||||
Created: inv.Created.Unix(),
|
||||
Profile: inv.Profile,
|
||||
NoLimit: inv.NoLimit,
|
||||
Label: inv.Label,
|
||||
}
|
||||
if len(inv.UsedBy) != 0 {
|
||||
invite.UsedBy = map[string]int64{}
|
||||
for _, pair := range inv.UsedBy {
|
||||
// These used to be stored formatted instead of as a unix timestamp.
|
||||
unix, err := strconv.ParseInt(pair[1], 10, 64)
|
||||
if err != nil {
|
||||
date, err := timefmt.Parse(pair[1], app.datePattern+" "+app.timePattern)
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to parse usedBy time: %v", err)
|
||||
}
|
||||
unix = date.Unix()
|
||||
}
|
||||
invite.UsedBy[pair[0]] = unix
|
||||
}
|
||||
}
|
||||
invite.RemainingUses = 1
|
||||
if inv.RemainingUses != 0 {
|
||||
invite.RemainingUses = inv.RemainingUses
|
||||
}
|
||||
if inv.SendTo != "" {
|
||||
invite.SendTo = inv.SendTo
|
||||
}
|
||||
if len(inv.Notify) != 0 {
|
||||
var address string
|
||||
if app.config.Section("ui").Key("jellyfin_login").MustBool(false) {
|
||||
app.storage.loadEmails()
|
||||
if addr, ok := app.storage.emails[gc.GetString("jfId")]; ok && addr.Addr != "" {
|
||||
address = addr.Addr
|
||||
}
|
||||
} else {
|
||||
address = app.config.Section("ui").Key("email").String()
|
||||
}
|
||||
if _, ok := inv.Notify[address]; ok {
|
||||
if _, ok = inv.Notify[address]["notify-expiry"]; ok {
|
||||
invite.NotifyExpiry = inv.Notify[address]["notify-expiry"]
|
||||
}
|
||||
if _, ok = inv.Notify[address]["notify-creation"]; ok {
|
||||
invite.NotifyCreation = inv.Notify[address]["notify-creation"]
|
||||
}
|
||||
}
|
||||
}
|
||||
invites = append(invites, invite)
|
||||
}
|
||||
profiles := make([]string, len(app.storage.profiles))
|
||||
if len(app.storage.profiles) != 0 {
|
||||
profiles[0] = app.storage.defaultProfile
|
||||
i := 1
|
||||
if len(app.storage.profiles) > 1 {
|
||||
for p := range app.storage.profiles {
|
||||
if p != app.storage.defaultProfile {
|
||||
profiles[i] = p
|
||||
i++
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resp := getInvitesDTO{
|
||||
Profiles: profiles,
|
||||
Invites: invites,
|
||||
}
|
||||
gc.JSON(200, resp)
|
||||
}
|
||||
|
||||
// @Summary Set profile for an invite
|
||||
// @Produce json
|
||||
// @Param inviteProfileDTO body inviteProfileDTO true "Invite profile object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /invites/profile [post]
|
||||
// @Security Bearer
|
||||
// @tags Profiles & Settings
|
||||
func (app *appContext) SetProfile(gc *gin.Context) {
|
||||
var req inviteProfileDTO
|
||||
gc.BindJSON(&req)
|
||||
app.debug.Printf("%s: Setting profile to \"%s\"", req.Invite, req.Profile)
|
||||
// "" means "Don't apply profile"
|
||||
if _, ok := app.storage.profiles[req.Profile]; !ok && req.Profile != "" {
|
||||
app.err.Printf("%s: Profile \"%s\" not found", req.Invite, req.Profile)
|
||||
respond(500, "Profile not found", gc)
|
||||
return
|
||||
}
|
||||
inv := app.storage.invites[req.Invite]
|
||||
inv.Profile = req.Profile
|
||||
app.storage.invites[req.Invite] = inv
|
||||
app.storage.storeInvites()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Set notification preferences for an invite.
|
||||
// @Produce json
|
||||
// @Param setNotifyDTO body setNotifyDTO true "Map of invite codes to notification settings objects"
|
||||
// @Success 200
|
||||
// @Failure 400 {object} stringResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /invites/notify [post]
|
||||
// @Security Bearer
|
||||
// @tags Other
|
||||
func (app *appContext) SetNotify(gc *gin.Context) {
|
||||
var req map[string]map[string]bool
|
||||
gc.BindJSON(&req)
|
||||
changed := false
|
||||
for code, settings := range req {
|
||||
app.debug.Printf("%s: Notification settings change requested", code)
|
||||
app.storage.loadInvites()
|
||||
app.storage.loadEmails()
|
||||
invite, ok := app.storage.invites[code]
|
||||
if !ok {
|
||||
app.err.Printf("%s Notification setting change failed: Invalid code", code)
|
||||
respond(400, "Invalid invite code", gc)
|
||||
return
|
||||
}
|
||||
var address string
|
||||
jellyfinLogin := app.config.Section("ui").Key("jellyfin_login").MustBool(false)
|
||||
if jellyfinLogin {
|
||||
var addressAvailable bool = app.getAddressOrName(gc.GetString("jfId")) != ""
|
||||
if !addressAvailable {
|
||||
app.err.Printf("%s: Couldn't find contact method for admin. Make sure one is set.", code)
|
||||
app.debug.Printf("%s: User ID \"%s\"", code, gc.GetString("jfId"))
|
||||
respond(500, "Missing user contact method", gc)
|
||||
return
|
||||
}
|
||||
address = gc.GetString("jfId")
|
||||
} else {
|
||||
address = app.config.Section("ui").Key("email").String()
|
||||
}
|
||||
if invite.Notify == nil {
|
||||
invite.Notify = map[string]map[string]bool{}
|
||||
}
|
||||
if _, ok := invite.Notify[address]; !ok {
|
||||
invite.Notify[address] = map[string]bool{}
|
||||
} /*else {
|
||||
if _, ok := invite.Notify[address]["notify-expiry"]; !ok {
|
||||
*/
|
||||
if _, ok := settings["notify-expiry"]; ok && invite.Notify[address]["notify-expiry"] != settings["notify-expiry"] {
|
||||
invite.Notify[address]["notify-expiry"] = settings["notify-expiry"]
|
||||
app.debug.Printf("%s: Set \"notify-expiry\" to %t for %s", code, settings["notify-expiry"], address)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := settings["notify-creation"]; ok && invite.Notify[address]["notify-creation"] != settings["notify-creation"] {
|
||||
invite.Notify[address]["notify-creation"] = settings["notify-creation"]
|
||||
app.debug.Printf("%s: Set \"notify-creation\" to %t for %s", code, settings["notify-creation"], address)
|
||||
changed = true
|
||||
}
|
||||
if changed {
|
||||
app.storage.invites[code] = invite
|
||||
}
|
||||
}
|
||||
if changed {
|
||||
app.storage.storeInvites()
|
||||
}
|
||||
}
|
||||
|
||||
// @Summary Delete an invite.
|
||||
// @Produce json
|
||||
// @Param deleteInviteDTO body deleteInviteDTO true "Delete invite object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} stringResponse
|
||||
// @Router /invites [delete]
|
||||
// @Security Bearer
|
||||
// @tags Invites
|
||||
func (app *appContext) DeleteInvite(gc *gin.Context) {
|
||||
var req deleteInviteDTO
|
||||
gc.BindJSON(&req)
|
||||
app.debug.Printf("%s: Deletion requested", req.Code)
|
||||
var ok bool
|
||||
_, ok = app.storage.invites[req.Code]
|
||||
if ok {
|
||||
delete(app.storage.invites, req.Code)
|
||||
app.storage.storeInvites()
|
||||
app.info.Printf("%s: Invite deleted", req.Code)
|
||||
respondBool(200, true, gc)
|
||||
return
|
||||
}
|
||||
app.err.Printf("%s: Deletion failed: Invalid code", req.Code)
|
||||
respond(400, "Code doesn't exist", gc)
|
||||
}
|
||||
783
api-messages.go
Normal file
783
api-messages.go
Normal file
@@ -0,0 +1,783 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
// @Summary Get a list of email names and IDs.
|
||||
// @Produce json
|
||||
// @Param lang query string false "Language for email titles."
|
||||
// @Success 200 {object} emailListDTO
|
||||
// @Router /config/emails [get]
|
||||
// @Security Bearer
|
||||
// @tags Configuration
|
||||
func (app *appContext) GetCustomEmails(gc *gin.Context) {
|
||||
lang := gc.Query("lang")
|
||||
if _, ok := app.storage.lang.Email[lang]; !ok {
|
||||
lang = app.storage.lang.chosenEmailLang
|
||||
}
|
||||
gc.JSON(200, emailListDTO{
|
||||
"UserCreated": {Name: app.storage.lang.Email[lang].UserCreated["name"], Enabled: app.storage.customEmails.UserCreated.Enabled},
|
||||
"InviteExpiry": {Name: app.storage.lang.Email[lang].InviteExpiry["name"], Enabled: app.storage.customEmails.InviteExpiry.Enabled},
|
||||
"PasswordReset": {Name: app.storage.lang.Email[lang].PasswordReset["name"], Enabled: app.storage.customEmails.PasswordReset.Enabled},
|
||||
"UserDeleted": {Name: app.storage.lang.Email[lang].UserDeleted["name"], Enabled: app.storage.customEmails.UserDeleted.Enabled},
|
||||
"UserDisabled": {Name: app.storage.lang.Email[lang].UserDisabled["name"], Enabled: app.storage.customEmails.UserDisabled.Enabled},
|
||||
"UserEnabled": {Name: app.storage.lang.Email[lang].UserEnabled["name"], Enabled: app.storage.customEmails.UserEnabled.Enabled},
|
||||
"InviteEmail": {Name: app.storage.lang.Email[lang].InviteEmail["name"], Enabled: app.storage.customEmails.InviteEmail.Enabled},
|
||||
"WelcomeEmail": {Name: app.storage.lang.Email[lang].WelcomeEmail["name"], Enabled: app.storage.customEmails.WelcomeEmail.Enabled},
|
||||
"EmailConfirmation": {Name: app.storage.lang.Email[lang].EmailConfirmation["name"], Enabled: app.storage.customEmails.EmailConfirmation.Enabled},
|
||||
"UserExpired": {Name: app.storage.lang.Email[lang].UserExpired["name"], Enabled: app.storage.customEmails.UserExpired.Enabled},
|
||||
})
|
||||
}
|
||||
|
||||
func (app *appContext) getCustomEmail(id string) *customEmail {
|
||||
switch id {
|
||||
case "Announcement":
|
||||
return &customEmail{}
|
||||
case "UserCreated":
|
||||
return &app.storage.customEmails.UserCreated
|
||||
case "InviteExpiry":
|
||||
return &app.storage.customEmails.InviteExpiry
|
||||
case "PasswordReset":
|
||||
return &app.storage.customEmails.PasswordReset
|
||||
case "UserDeleted":
|
||||
return &app.storage.customEmails.UserDeleted
|
||||
case "UserDisabled":
|
||||
return &app.storage.customEmails.UserDisabled
|
||||
case "UserEnabled":
|
||||
return &app.storage.customEmails.UserEnabled
|
||||
case "InviteEmail":
|
||||
return &app.storage.customEmails.InviteEmail
|
||||
case "WelcomeEmail":
|
||||
return &app.storage.customEmails.WelcomeEmail
|
||||
case "EmailConfirmation":
|
||||
return &app.storage.customEmails.EmailConfirmation
|
||||
case "UserExpired":
|
||||
return &app.storage.customEmails.UserExpired
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// @Summary Sets the corresponding custom email.
|
||||
// @Produce json
|
||||
// @Param customEmail body customEmail true "Content = email (in markdown)."
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param id path string true "ID of email"
|
||||
// @Router /config/emails/{id} [post]
|
||||
// @Security Bearer
|
||||
// @tags Configuration
|
||||
func (app *appContext) SetCustomEmail(gc *gin.Context) {
|
||||
var req customEmail
|
||||
gc.BindJSON(&req)
|
||||
id := gc.Param("id")
|
||||
if req.Content == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
email := app.getCustomEmail(id)
|
||||
if email == nil {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
email.Content = req.Content
|
||||
email.Enabled = true
|
||||
if app.storage.storeCustomEmails() != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Enable/Disable custom email.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param enable/disable path string true "enable/disable"
|
||||
// @Param id path string true "ID of email"
|
||||
// @Router /config/emails/{id}/state/{enable/disable} [post]
|
||||
// @Security Bearer
|
||||
// @tags Configuration
|
||||
func (app *appContext) SetCustomEmailState(gc *gin.Context) {
|
||||
id := gc.Param("id")
|
||||
s := gc.Param("state")
|
||||
enabled := false
|
||||
if s == "enable" {
|
||||
enabled = true
|
||||
} else if s != "disable" {
|
||||
respondBool(400, false, gc)
|
||||
}
|
||||
email := app.getCustomEmail(id)
|
||||
if email == nil {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
email.Enabled = enabled
|
||||
if app.storage.storeCustomEmails() != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns the custom email (generating it if not set) and list of used variables in it.
|
||||
// @Produce json
|
||||
// @Success 200 {object} customEmailDTO
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param id path string true "ID of email"
|
||||
// @Router /config/emails/{id} [get]
|
||||
// @Security Bearer
|
||||
// @tags Configuration
|
||||
func (app *appContext) GetCustomEmailTemplate(gc *gin.Context) {
|
||||
lang := app.storage.lang.chosenEmailLang
|
||||
id := gc.Param("id")
|
||||
var content string
|
||||
var err error
|
||||
var msg *Message
|
||||
var variables []string
|
||||
var conditionals []string
|
||||
var values map[string]interface{}
|
||||
username := app.storage.lang.Email[lang].Strings.get("username")
|
||||
emailAddress := app.storage.lang.Email[lang].Strings.get("emailAddress")
|
||||
email := app.getCustomEmail(id)
|
||||
if email == nil {
|
||||
app.err.Printf("Failed to get custom email with ID \"%s\"", id)
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
if id == "WelcomeEmail" {
|
||||
conditionals = []string{"{yourAccountWillExpire}"}
|
||||
email.Conditionals = conditionals
|
||||
}
|
||||
content = email.Content
|
||||
noContent := content == ""
|
||||
if !noContent {
|
||||
variables = email.Variables
|
||||
}
|
||||
switch id {
|
||||
case "Announcement":
|
||||
// Just send the email html
|
||||
content = ""
|
||||
case "UserCreated":
|
||||
if noContent {
|
||||
msg, err = app.email.constructCreated("", "", "", Invite{}, app, true)
|
||||
}
|
||||
values = app.email.createdValues("xxxxxx", username, emailAddress, Invite{}, app, false)
|
||||
case "InviteExpiry":
|
||||
if noContent {
|
||||
msg, err = app.email.constructExpiry("", Invite{}, app, true)
|
||||
}
|
||||
values = app.email.expiryValues("xxxxxx", Invite{}, app, false)
|
||||
case "PasswordReset":
|
||||
if noContent {
|
||||
msg, err = app.email.constructReset(PasswordReset{}, app, true)
|
||||
}
|
||||
values = app.email.resetValues(PasswordReset{Pin: "12-34-56", Username: username}, app, false)
|
||||
case "UserDeleted":
|
||||
if noContent {
|
||||
msg, err = app.email.constructDeleted("", app, true)
|
||||
}
|
||||
values = app.email.deletedValues(app.storage.lang.Email[lang].Strings.get("reason"), app, false)
|
||||
case "UserDisabled":
|
||||
if noContent {
|
||||
msg, err = app.email.constructDisabled("", app, true)
|
||||
}
|
||||
values = app.email.deletedValues(app.storage.lang.Email[lang].Strings.get("reason"), app, false)
|
||||
case "UserEnabled":
|
||||
if noContent {
|
||||
msg, err = app.email.constructEnabled("", app, true)
|
||||
}
|
||||
values = app.email.deletedValues(app.storage.lang.Email[lang].Strings.get("reason"), app, false)
|
||||
case "InviteEmail":
|
||||
if noContent {
|
||||
msg, err = app.email.constructInvite("", Invite{}, app, true)
|
||||
}
|
||||
values = app.email.inviteValues("xxxxxx", Invite{}, app, false)
|
||||
case "WelcomeEmail":
|
||||
if noContent {
|
||||
msg, err = app.email.constructWelcome("", time.Time{}, app, true)
|
||||
}
|
||||
values = app.email.welcomeValues(username, time.Now(), app, false, true)
|
||||
case "EmailConfirmation":
|
||||
if noContent {
|
||||
msg, err = app.email.constructConfirmation("", "", "", app, true)
|
||||
}
|
||||
values = app.email.confirmationValues("xxxxxx", username, "xxxxxx", app, false)
|
||||
case "UserExpired":
|
||||
if noContent {
|
||||
msg, err = app.email.constructUserExpired(app, true)
|
||||
}
|
||||
values = app.email.userExpiredValues(app, false)
|
||||
}
|
||||
if err != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
if noContent && id != "Announcement" {
|
||||
content = msg.Text
|
||||
variables = make([]string, strings.Count(content, "{"))
|
||||
i := 0
|
||||
found := false
|
||||
buf := ""
|
||||
for _, c := range content {
|
||||
if !found && c != '{' && c != '}' {
|
||||
continue
|
||||
}
|
||||
found = true
|
||||
buf += string(c)
|
||||
if c == '}' {
|
||||
found = false
|
||||
variables[i] = buf
|
||||
buf = ""
|
||||
i++
|
||||
}
|
||||
}
|
||||
email.Variables = variables
|
||||
}
|
||||
if variables == nil {
|
||||
variables = []string{}
|
||||
}
|
||||
if app.storage.storeCustomEmails() != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
mail, err := app.email.constructTemplate("", "<div class=\"preview-content\"></div>", app)
|
||||
if err != nil {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
gc.JSON(200, customEmailDTO{Content: content, Variables: variables, Conditionals: conditionals, Values: values, HTML: mail.HTML, Plaintext: mail.Text})
|
||||
}
|
||||
|
||||
// @Summary Returns a new Telegram verification PIN, and the bot username.
|
||||
// @Produce json
|
||||
// @Success 200 {object} telegramPinDTO
|
||||
// @Router /telegram/pin [get]
|
||||
// @Security Bearer
|
||||
// @tags Other
|
||||
func (app *appContext) TelegramGetPin(gc *gin.Context) {
|
||||
gc.JSON(200, telegramPinDTO{
|
||||
Token: app.telegram.NewAuthToken(),
|
||||
Username: app.telegram.username,
|
||||
})
|
||||
}
|
||||
|
||||
// @Summary Link a Jellyfin & Telegram user together via a verification PIN.
|
||||
// @Produce json
|
||||
// @Param telegramSetDTO body telegramSetDTO true "Token and user's Jellyfin ID."
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Router /users/telegram [post]
|
||||
// @Security Bearer
|
||||
// @tags Other
|
||||
func (app *appContext) TelegramAddUser(gc *gin.Context) {
|
||||
var req telegramSetDTO
|
||||
gc.BindJSON(&req)
|
||||
if req.Token == "" || req.ID == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
tokenIndex := -1
|
||||
for i, v := range app.telegram.verifiedTokens {
|
||||
if v.Token == req.Token {
|
||||
tokenIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if tokenIndex == -1 {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
tgToken := app.telegram.verifiedTokens[tokenIndex]
|
||||
tgUser := TelegramUser{
|
||||
ChatID: tgToken.ChatID,
|
||||
Username: tgToken.Username,
|
||||
Contact: true,
|
||||
}
|
||||
if lang, ok := app.telegram.languages[tgToken.ChatID]; ok {
|
||||
tgUser.Lang = lang
|
||||
}
|
||||
if app.storage.telegram == nil {
|
||||
app.storage.telegram = map[string]TelegramUser{}
|
||||
}
|
||||
app.storage.telegram[req.ID] = tgUser
|
||||
err := app.storage.storeTelegramUsers()
|
||||
if err != nil {
|
||||
app.err.Printf("Failed to store Telegram users: %v", err)
|
||||
} else {
|
||||
app.telegram.verifiedTokens[len(app.telegram.verifiedTokens)-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[len(app.telegram.verifiedTokens)-1]
|
||||
app.telegram.verifiedTokens = app.telegram.verifiedTokens[:len(app.telegram.verifiedTokens)-1]
|
||||
}
|
||||
linkExistingOmbiDiscordTelegram(app)
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Sets whether to notify a user through telegram/discord/matrix/email or not.
|
||||
// @Produce json
|
||||
// @Param SetContactMethodsDTO body SetContactMethodsDTO true "User's Jellyfin ID and whether or not to notify then through Telegram."
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Success 400 {object} boolResponse
|
||||
// @Success 500 {object} boolResponse
|
||||
// @Router /users/contact [post]
|
||||
// @Security Bearer
|
||||
// @tags Other
|
||||
func (app *appContext) SetContactMethods(gc *gin.Context) {
|
||||
var req SetContactMethodsDTO
|
||||
gc.BindJSON(&req)
|
||||
if req.ID == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
if tgUser, ok := app.storage.telegram[req.ID]; ok {
|
||||
change := tgUser.Contact != req.Telegram
|
||||
tgUser.Contact = req.Telegram
|
||||
app.storage.telegram[req.ID] = tgUser
|
||||
if err := app.storage.storeTelegramUsers(); err != nil {
|
||||
respondBool(500, false, gc)
|
||||
app.err.Printf("Telegram: Failed to store users: %v", err)
|
||||
return
|
||||
}
|
||||
if change {
|
||||
msg := ""
|
||||
if !req.Telegram {
|
||||
msg = " not"
|
||||
}
|
||||
app.debug.Printf("Telegram: User \"%s\" will%s be notified through Telegram.", tgUser.Username, msg)
|
||||
}
|
||||
}
|
||||
if dcUser, ok := app.storage.discord[req.ID]; ok {
|
||||
change := dcUser.Contact != req.Discord
|
||||
dcUser.Contact = req.Discord
|
||||
app.storage.discord[req.ID] = dcUser
|
||||
if err := app.storage.storeDiscordUsers(); err != nil {
|
||||
respondBool(500, false, gc)
|
||||
app.err.Printf("Discord: Failed to store users: %v", err)
|
||||
return
|
||||
}
|
||||
if change {
|
||||
msg := ""
|
||||
if !req.Discord {
|
||||
msg = " not"
|
||||
}
|
||||
app.debug.Printf("Discord: User \"%s\" will%s be notified through Discord.", dcUser.Username, msg)
|
||||
}
|
||||
}
|
||||
if mxUser, ok := app.storage.matrix[req.ID]; ok {
|
||||
change := mxUser.Contact != req.Matrix
|
||||
mxUser.Contact = req.Matrix
|
||||
app.storage.matrix[req.ID] = mxUser
|
||||
if err := app.storage.storeMatrixUsers(); err != nil {
|
||||
respondBool(500, false, gc)
|
||||
app.err.Printf("Matrix: Failed to store users: %v", err)
|
||||
return
|
||||
}
|
||||
if change {
|
||||
msg := ""
|
||||
if !req.Matrix {
|
||||
msg = " not"
|
||||
}
|
||||
app.debug.Printf("Matrix: User \"%s\" will%s be notified through Matrix.", mxUser.UserID, msg)
|
||||
}
|
||||
}
|
||||
if email, ok := app.storage.emails[req.ID]; ok {
|
||||
change := email.Contact != req.Email
|
||||
email.Contact = req.Email
|
||||
app.storage.emails[req.ID] = email
|
||||
if err := app.storage.storeEmails(); err != nil {
|
||||
respondBool(500, false, gc)
|
||||
app.err.Printf("Failed to store emails: %v", err)
|
||||
return
|
||||
}
|
||||
if change {
|
||||
msg := ""
|
||||
if !req.Email {
|
||||
msg = " not"
|
||||
}
|
||||
app.debug.Printf("\"%s\" will%s be notified via Email.", email.Addr, msg)
|
||||
}
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns true/false on whether or not a telegram PIN was verified. Requires bearer auth.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Param pin path string true "PIN code to check"
|
||||
// @Router /telegram/verified/{pin} [get]
|
||||
// @Security Bearer
|
||||
// @tags Other
|
||||
func (app *appContext) TelegramVerified(gc *gin.Context) {
|
||||
pin := gc.Param("pin")
|
||||
tokenIndex := -1
|
||||
for i, v := range app.telegram.verifiedTokens {
|
||||
if v.Token == pin {
|
||||
tokenIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
// if tokenIndex != -1 {
|
||||
// length := len(app.telegram.verifiedTokens)
|
||||
// app.telegram.verifiedTokens[length-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[length-1]
|
||||
// app.telegram.verifiedTokens = app.telegram.verifiedTokens[:length-1]
|
||||
// }
|
||||
respondBool(200, tokenIndex != -1, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns true/false on whether or not a telegram PIN was verified. Requires invite code.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Success 401 {object} boolResponse
|
||||
// @Param pin path string true "PIN code to check"
|
||||
// @Param invCode path string true "invite Code"
|
||||
// @Router /invite/{invCode}/telegram/verified/{pin} [get]
|
||||
// @tags Other
|
||||
func (app *appContext) TelegramVerifiedInvite(gc *gin.Context) {
|
||||
code := gc.Param("invCode")
|
||||
if _, ok := app.storage.invites[code]; !ok {
|
||||
respondBool(401, false, gc)
|
||||
return
|
||||
}
|
||||
pin := gc.Param("pin")
|
||||
tokenIndex := -1
|
||||
for i, v := range app.telegram.verifiedTokens {
|
||||
if v.Token == pin {
|
||||
tokenIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if app.config.Section("telegram").Key("require_unique").MustBool(false) {
|
||||
for _, u := range app.storage.telegram {
|
||||
if app.telegram.verifiedTokens[tokenIndex].Username == u.Username {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
// if tokenIndex != -1 {
|
||||
// length := len(app.telegram.verifiedTokens)
|
||||
// app.telegram.verifiedTokens[length-1], app.telegram.verifiedTokens[tokenIndex] = app.telegram.verifiedTokens[tokenIndex], app.telegram.verifiedTokens[length-1]
|
||||
// app.telegram.verifiedTokens = app.telegram.verifiedTokens[:length-1]
|
||||
// }
|
||||
respondBool(200, tokenIndex != -1, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns true/false on whether or not a discord PIN was verified. Requires invite code.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 401 {object} boolResponse
|
||||
// @Param pin path string true "PIN code to check"
|
||||
// @Param invCode path string true "invite Code"
|
||||
// @Router /invite/{invCode}/discord/verified/{pin} [get]
|
||||
// @tags Other
|
||||
func (app *appContext) DiscordVerifiedInvite(gc *gin.Context) {
|
||||
code := gc.Param("invCode")
|
||||
if _, ok := app.storage.invites[code]; !ok {
|
||||
respondBool(401, false, gc)
|
||||
return
|
||||
}
|
||||
pin := gc.Param("pin")
|
||||
_, ok := app.discord.verifiedTokens[pin]
|
||||
if app.config.Section("discord").Key("require_unique").MustBool(false) {
|
||||
for _, u := range app.storage.discord {
|
||||
if app.discord.verifiedTokens[pin].ID == u.ID {
|
||||
delete(app.discord.verifiedTokens, pin)
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
respondBool(200, ok, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns a 10-minute, one-use Discord server invite
|
||||
// @Produce json
|
||||
// @Success 200 {object} DiscordInviteDTO
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 401 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param invCode path string true "invite Code"
|
||||
// @Router /invite/{invCode}/discord/invite [get]
|
||||
// @tags Other
|
||||
func (app *appContext) DiscordServerInvite(gc *gin.Context) {
|
||||
if app.discord.inviteChannelName == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
code := gc.Param("invCode")
|
||||
if _, ok := app.storage.invites[code]; !ok {
|
||||
respondBool(401, false, gc)
|
||||
return
|
||||
}
|
||||
invURL, iconURL := app.discord.NewTempInvite(10*60, 1)
|
||||
if invURL == "" {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
gc.JSON(200, DiscordInviteDTO{invURL, iconURL})
|
||||
}
|
||||
|
||||
// @Summary Generate and send a new PIN to a specified Matrix user.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} stringResponse
|
||||
// @Failure 401 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param invCode path string true "invite Code"
|
||||
// @Param MatrixSendPINDTO body MatrixSendPINDTO true "User's Matrix ID."
|
||||
// @Router /invite/{invCode}/matrix/user [post]
|
||||
// @tags Other
|
||||
func (app *appContext) MatrixSendPIN(gc *gin.Context) {
|
||||
code := gc.Param("invCode")
|
||||
if _, ok := app.storage.invites[code]; !ok {
|
||||
respondBool(401, false, gc)
|
||||
return
|
||||
}
|
||||
var req MatrixSendPINDTO
|
||||
gc.BindJSON(&req)
|
||||
if req.UserID == "" {
|
||||
respond(400, "errorNoUserID", gc)
|
||||
return
|
||||
}
|
||||
if app.config.Section("matrix").Key("require_unique").MustBool(false) {
|
||||
for _, u := range app.storage.matrix {
|
||||
if req.UserID == u.UserID {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ok := app.matrix.SendStart(req.UserID)
|
||||
if !ok {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Check whether a matrix PIN is valid, and mark the token as verified if so. Requires invite code.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 401 {object} boolResponse
|
||||
// @Param pin path string true "PIN code to check"
|
||||
// @Param invCode path string true "invite Code"
|
||||
// @Param userID path string true "Matrix User ID"
|
||||
// @Router /invite/{invCode}/matrix/verified/{userID}/{pin} [get]
|
||||
// @tags Other
|
||||
func (app *appContext) MatrixCheckPIN(gc *gin.Context) {
|
||||
code := gc.Param("invCode")
|
||||
if _, ok := app.storage.invites[code]; !ok {
|
||||
app.debug.Println("Matrix: Invite code was invalid")
|
||||
respondBool(401, false, gc)
|
||||
return
|
||||
}
|
||||
userID := gc.Param("userID")
|
||||
pin := gc.Param("pin")
|
||||
user, ok := app.matrix.tokens[pin]
|
||||
if !ok {
|
||||
app.debug.Println("Matrix: PIN not found")
|
||||
respondBool(200, false, gc)
|
||||
return
|
||||
}
|
||||
if user.User.UserID != userID {
|
||||
app.debug.Println("Matrix: User ID of PIN didn't match")
|
||||
respondBool(200, false, gc)
|
||||
return
|
||||
}
|
||||
user.Verified = true
|
||||
app.matrix.tokens[pin] = user
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Generates a Matrix access token from a username and password.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} stringResponse
|
||||
// @Failure 401 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param MatrixLoginDTO body MatrixLoginDTO true "Username & password."
|
||||
// @Router /matrix/login [post]
|
||||
// @tags Other
|
||||
func (app *appContext) MatrixLogin(gc *gin.Context) {
|
||||
var req MatrixLoginDTO
|
||||
gc.BindJSON(&req)
|
||||
if req.Username == "" || req.Password == "" {
|
||||
respond(400, "errorLoginBlank", gc)
|
||||
return
|
||||
}
|
||||
token, err := app.matrix.generateAccessToken(req.Homeserver, req.Username, req.Password)
|
||||
if err != nil {
|
||||
app.err.Printf("Matrix: Failed to generate token: %v", err)
|
||||
respond(401, "Unauthorized", gc)
|
||||
return
|
||||
}
|
||||
tempConfig, _ := ini.Load(app.configPath)
|
||||
matrix := tempConfig.Section("matrix")
|
||||
matrix.Key("enabled").SetValue("true")
|
||||
matrix.Key("homeserver").SetValue(req.Homeserver)
|
||||
matrix.Key("token").SetValue(token)
|
||||
matrix.Key("user_id").SetValue(req.Username)
|
||||
if err := tempConfig.SaveTo(app.configPath); err != nil {
|
||||
app.err.Printf("Failed to save config to \"%s\": %v", app.configPath, err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Links a Matrix user to a Jellyfin account via user IDs. Notifications are turned on by default.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param MatrixConnectUserDTO body MatrixConnectUserDTO true "User's Jellyfin ID & Matrix user ID."
|
||||
// @Router /users/matrix [post]
|
||||
// @tags Other
|
||||
func (app *appContext) MatrixConnect(gc *gin.Context) {
|
||||
var req MatrixConnectUserDTO
|
||||
gc.BindJSON(&req)
|
||||
if app.storage.matrix == nil {
|
||||
app.storage.matrix = map[string]MatrixUser{}
|
||||
}
|
||||
roomID, encrypted, err := app.matrix.CreateRoom(req.UserID)
|
||||
if err != nil {
|
||||
app.err.Printf("Matrix: Failed to create room: %v", err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
app.storage.matrix[req.JellyfinID] = MatrixUser{
|
||||
UserID: req.UserID,
|
||||
RoomID: string(roomID),
|
||||
Lang: "en-us",
|
||||
Contact: true,
|
||||
Encrypted: encrypted,
|
||||
}
|
||||
app.matrix.isEncrypted[roomID] = encrypted
|
||||
if err := app.storage.storeMatrixUsers(); err != nil {
|
||||
app.err.Printf("Failed to store Matrix users: %v", err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Returns a list of matching users from a Discord guild, given a username (discriminator optional).
|
||||
// @Produce json
|
||||
// @Success 200 {object} DiscordUsersDTO
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param username path string true "username to search."
|
||||
// @Router /users/discord/{username} [get]
|
||||
// @tags Other
|
||||
func (app *appContext) DiscordGetUsers(gc *gin.Context) {
|
||||
name := gc.Param("username")
|
||||
if name == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
users := app.discord.GetUsers(name)
|
||||
resp := DiscordUsersDTO{Users: make([]DiscordUserDTO, len(users))}
|
||||
for i, u := range users {
|
||||
resp.Users[i] = DiscordUserDTO{
|
||||
Name: RenderDiscordUsername(u.User),
|
||||
ID: u.User.ID,
|
||||
AvatarURL: u.User.AvatarURL("32"),
|
||||
}
|
||||
}
|
||||
gc.JSON(200, resp)
|
||||
}
|
||||
|
||||
// @Summary Links a Discord account to a Jellyfin account via user IDs. Notifications are turned on by default.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} boolResponse
|
||||
// @Param DiscordConnectUserDTO body DiscordConnectUserDTO true "User's Jellyfin ID & Discord ID."
|
||||
// @Router /users/discord [post]
|
||||
// @tags Other
|
||||
func (app *appContext) DiscordConnect(gc *gin.Context) {
|
||||
var req DiscordConnectUserDTO
|
||||
gc.BindJSON(&req)
|
||||
if req.JellyfinID == "" || req.DiscordID == "" {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
user, ok := app.discord.NewUser(req.DiscordID)
|
||||
if !ok {
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
app.storage.discord[req.JellyfinID] = user
|
||||
if err := app.storage.storeDiscordUsers(); err != nil {
|
||||
app.err.Printf("Failed to store Discord users: %v", err)
|
||||
respondBool(500, false, gc)
|
||||
return
|
||||
}
|
||||
linkExistingOmbiDiscordTelegram(app)
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary unlink a Discord account from a Jellyfin user. Always succeeds.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Param forUserDTO body forUserDTO true "User's Jellyfin ID."
|
||||
// @Router /users/discord [delete]
|
||||
// @Tags Users
|
||||
func (app *appContext) UnlinkDiscord(gc *gin.Context) {
|
||||
var req forUserDTO
|
||||
gc.BindJSON(&req)
|
||||
/* user, status, err := app.jf.UserByID(req.ID, false)
|
||||
if req.ID == "" || status != 200 || err != nil {
|
||||
respond(400, "User not found", gc)
|
||||
return
|
||||
} */
|
||||
delete(app.storage.discord, req.ID)
|
||||
app.storage.storeDiscordUsers()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary unlink a Telegram account from a Jellyfin user. Always succeeds.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Param forUserDTO body forUserDTO true "User's Jellyfin ID."
|
||||
// @Router /users/telegram [delete]
|
||||
// @Tags Users
|
||||
func (app *appContext) UnlinkTelegram(gc *gin.Context) {
|
||||
var req forUserDTO
|
||||
gc.BindJSON(&req)
|
||||
/* user, status, err := app.jf.UserByID(req.ID, false)
|
||||
if req.ID == "" || status != 200 || err != nil {
|
||||
respond(400, "User not found", gc)
|
||||
return
|
||||
} */
|
||||
delete(app.storage.telegram, req.ID)
|
||||
app.storage.storeTelegramUsers()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary unlink a Matrix account from a Jellyfin user. Always succeeds.
|
||||
// @Produce json
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Param forUserDTO body forUserDTO true "User's Jellyfin ID."
|
||||
// @Router /users/matrix [delete]
|
||||
// @Tags Users
|
||||
func (app *appContext) UnlinkMatrix(gc *gin.Context) {
|
||||
var req forUserDTO
|
||||
gc.BindJSON(&req)
|
||||
/* user, status, err := app.jf.UserByID(req.ID, false)
|
||||
if req.ID == "" || status != 200 || err != nil {
|
||||
respond(400, "User not found", gc)
|
||||
return
|
||||
} */
|
||||
delete(app.storage.matrix, req.ID)
|
||||
app.storage.storeMatrixUsers()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
119
api-ombi.go
Normal file
119
api-ombi.go
Normal file
@@ -0,0 +1,119 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func (app *appContext) getOmbiUser(jfID string) (map[string]interface{}, int, error) {
|
||||
ombiUsers, code, err := app.ombi.GetUsers()
|
||||
if err != nil || code != 200 {
|
||||
return nil, code, err
|
||||
}
|
||||
jfUser, code, err := app.jf.UserByID(jfID, false)
|
||||
if err != nil || code != 200 {
|
||||
return nil, code, err
|
||||
}
|
||||
username := jfUser.Name
|
||||
email := ""
|
||||
if e, ok := app.storage.emails[jfID]; ok {
|
||||
email = e.Addr
|
||||
}
|
||||
for _, ombiUser := range ombiUsers {
|
||||
ombiAddr := ""
|
||||
if a, ok := ombiUser["emailAddress"]; ok && a != nil {
|
||||
ombiAddr = a.(string)
|
||||
}
|
||||
if ombiUser["userName"].(string) == username || (ombiAddr == email && email != "") {
|
||||
return ombiUser, code, err
|
||||
}
|
||||
}
|
||||
return nil, 400, fmt.Errorf("Couldn't find user")
|
||||
}
|
||||
|
||||
// @Summary Get a list of Ombi users.
|
||||
// @Produce json
|
||||
// @Success 200 {object} ombiUsersDTO
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /ombi/users [get]
|
||||
// @Security Bearer
|
||||
// @tags Ombi
|
||||
func (app *appContext) OmbiUsers(gc *gin.Context) {
|
||||
app.debug.Println("Ombi users requested")
|
||||
users, status, err := app.ombi.GetUsers()
|
||||
if err != nil || status != 200 {
|
||||
app.err.Printf("Failed to get users from Ombi (%d): %v", status, err)
|
||||
respond(500, "Couldn't get users", gc)
|
||||
return
|
||||
}
|
||||
userlist := make([]ombiUser, len(users))
|
||||
for i, data := range users {
|
||||
userlist[i] = ombiUser{
|
||||
Name: data["userName"].(string),
|
||||
ID: data["id"].(string),
|
||||
}
|
||||
}
|
||||
gc.JSON(200, ombiUsersDTO{Users: userlist})
|
||||
}
|
||||
|
||||
// @Summary Store Ombi user template in an existing profile.
|
||||
// @Produce json
|
||||
// @Param ombiUser body ombiUser true "User to source settings from"
|
||||
// @Param profile path string true "Name of profile to store in"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /profiles/ombi/{profile} [post]
|
||||
// @Security Bearer
|
||||
// @tags Ombi
|
||||
func (app *appContext) SetOmbiProfile(gc *gin.Context) {
|
||||
var req ombiUser
|
||||
gc.BindJSON(&req)
|
||||
profileName := gc.Param("profile")
|
||||
profile, ok := app.storage.profiles[profileName]
|
||||
if !ok {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
template, code, err := app.ombi.TemplateByID(req.ID)
|
||||
if err != nil || code != 200 || len(template) == 0 {
|
||||
app.err.Printf("Couldn't get user from Ombi (%d): %v", code, err)
|
||||
respond(500, "Couldn't get user", gc)
|
||||
return
|
||||
}
|
||||
profile.Ombi = template
|
||||
app.storage.profiles[profileName] = profile
|
||||
if err := app.storage.storeProfiles(); err != nil {
|
||||
respond(500, "Failed to store profile", gc)
|
||||
app.err.Printf("Failed to store profiles: %v", err)
|
||||
return
|
||||
}
|
||||
respondBool(204, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Remove ombi user template from a profile.
|
||||
// @Produce json
|
||||
// @Param profile path string true "Name of profile to store in"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 400 {object} boolResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /profiles/ombi/{profile} [delete]
|
||||
// @Security Bearer
|
||||
// @tags Ombi
|
||||
func (app *appContext) DeleteOmbiProfile(gc *gin.Context) {
|
||||
profileName := gc.Param("profile")
|
||||
profile, ok := app.storage.profiles[profileName]
|
||||
if !ok {
|
||||
respondBool(400, false, gc)
|
||||
return
|
||||
}
|
||||
profile.Ombi = nil
|
||||
app.storage.profiles[profileName] = profile
|
||||
if err := app.storage.storeProfiles(); err != nil {
|
||||
respond(500, "Failed to store profile", gc)
|
||||
app.err.Printf("Failed to store profiles: %v", err)
|
||||
return
|
||||
}
|
||||
respondBool(204, true, gc)
|
||||
}
|
||||
121
api-profiles.go
Normal file
121
api-profiles.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// @Summary Get a list of profiles
|
||||
// @Produce json
|
||||
// @Success 200 {object} getProfilesDTO
|
||||
// @Router /profiles [get]
|
||||
// @Security Bearer
|
||||
// @tags Profiles & Settings
|
||||
func (app *appContext) GetProfiles(gc *gin.Context) {
|
||||
app.storage.loadProfiles()
|
||||
app.debug.Println("Profiles requested")
|
||||
out := getProfilesDTO{
|
||||
DefaultProfile: app.storage.defaultProfile,
|
||||
Profiles: map[string]profileDTO{},
|
||||
}
|
||||
for name, p := range app.storage.profiles {
|
||||
out.Profiles[name] = profileDTO{
|
||||
Admin: p.Admin,
|
||||
LibraryAccess: p.LibraryAccess,
|
||||
FromUser: p.FromUser,
|
||||
Ombi: p.Ombi != nil,
|
||||
}
|
||||
}
|
||||
gc.JSON(200, out)
|
||||
}
|
||||
|
||||
// @Summary Set the default profile to use.
|
||||
// @Produce json
|
||||
// @Param profileChangeDTO body profileChangeDTO true "Default profile object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /profiles/default [post]
|
||||
// @Security Bearer
|
||||
// @tags Profiles & Settings
|
||||
func (app *appContext) SetDefaultProfile(gc *gin.Context) {
|
||||
req := profileChangeDTO{}
|
||||
gc.BindJSON(&req)
|
||||
app.info.Printf("Setting default profile to \"%s\"", req.Name)
|
||||
if _, ok := app.storage.profiles[req.Name]; !ok {
|
||||
app.err.Printf("Profile not found: \"%s\"", req.Name)
|
||||
respond(500, "Profile not found", gc)
|
||||
return
|
||||
}
|
||||
for name, profile := range app.storage.profiles {
|
||||
if name == req.Name {
|
||||
profile.Admin = true
|
||||
app.storage.profiles[name] = profile
|
||||
} else {
|
||||
profile.Admin = false
|
||||
}
|
||||
}
|
||||
app.storage.defaultProfile = req.Name
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Create a profile based on a Jellyfin user's settings.
|
||||
// @Produce json
|
||||
// @Param newProfileDTO body newProfileDTO true "New profile object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Failure 500 {object} stringResponse
|
||||
// @Router /profiles [post]
|
||||
// @Security Bearer
|
||||
// @tags Profiles & Settings
|
||||
func (app *appContext) CreateProfile(gc *gin.Context) {
|
||||
app.info.Println("Profile creation requested")
|
||||
var req newProfileDTO
|
||||
gc.BindJSON(&req)
|
||||
app.jf.CacheExpiry = time.Now()
|
||||
user, status, err := app.jf.UserByID(req.ID, false)
|
||||
if !(status == 200 || status == 204) || err != nil {
|
||||
app.err.Printf("Failed to get user from Jellyfin (%d): %v", status, err)
|
||||
respond(500, "Couldn't get user", gc)
|
||||
return
|
||||
}
|
||||
profile := Profile{
|
||||
FromUser: user.Name,
|
||||
Policy: user.Policy,
|
||||
}
|
||||
app.debug.Printf("Creating profile from user \"%s\"", user.Name)
|
||||
if req.Homescreen {
|
||||
profile.Configuration = user.Configuration
|
||||
profile.Displayprefs, status, err = app.jf.GetDisplayPreferences(req.ID)
|
||||
if !(status == 200 || status == 204) || err != nil {
|
||||
app.err.Printf("Failed to get DisplayPrefs (%d): %v", status, err)
|
||||
respond(500, "Couldn't get displayprefs", gc)
|
||||
return
|
||||
}
|
||||
}
|
||||
app.storage.loadProfiles()
|
||||
app.storage.profiles[req.Name] = profile
|
||||
app.storage.storeProfiles()
|
||||
app.storage.loadProfiles()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
|
||||
// @Summary Delete an existing profile
|
||||
// @Produce json
|
||||
// @Param profileChangeDTO body profileChangeDTO true "Delete profile object"
|
||||
// @Success 200 {object} boolResponse
|
||||
// @Router /profiles [delete]
|
||||
// @Security Bearer
|
||||
// @tags Profiles & Settings
|
||||
func (app *appContext) DeleteProfile(gc *gin.Context) {
|
||||
req := profileChangeDTO{}
|
||||
gc.BindJSON(&req)
|
||||
name := req.Name
|
||||
if _, ok := app.storage.profiles[name]; ok {
|
||||
if app.storage.defaultProfile == name {
|
||||
app.storage.defaultProfile = ""
|
||||
}
|
||||
delete(app.storage.profiles, name)
|
||||
}
|
||||
app.storage.storeProfiles()
|
||||
respondBool(200, true, gc)
|
||||
}
|
||||
1195
api-users.go
Normal file
1195
api-users.go
Normal file
File diff suppressed because it is too large
Load Diff
13
args.go
13
args.go
@@ -75,18 +75,23 @@ func (app *appContext) loadArgs(firstCall bool) {
|
||||
os.Setenv("JFA_DATAPATH", app.dataPath)
|
||||
}
|
||||
|
||||
/* Adds start/stop/systemd to help message, and
|
||||
/*
|
||||
Adds start/stop/systemd to help message, and
|
||||
|
||||
also gets rid of usage for shorthand flags, and merge them with the full-length one.
|
||||
implementation is 🤢, will clean this up eventually.
|
||||
|
||||
-h SHORTHAND
|
||||
-help
|
||||
prints this message.
|
||||
|
||||
becomes:
|
||||
|
||||
-help, -h
|
||||
prints this message.
|
||||
*/
|
||||
func helpFunc() {
|
||||
fmt.Fprint(os.Stderr, `Usage of jfa-go:
|
||||
fmt.Fprint(stderr, `Usage of jfa-go:
|
||||
start
|
||||
start jfa-go as a daemon and run in the background.
|
||||
stop
|
||||
@@ -99,7 +104,7 @@ func helpFunc() {
|
||||
// Write defaults into buffer then remove any shorthands
|
||||
flag.CommandLine.SetOutput(&b)
|
||||
flag.PrintDefaults()
|
||||
flag.CommandLine.SetOutput(os.Stderr)
|
||||
flag.CommandLine.SetOutput(stderr)
|
||||
scanner := bufio.NewScanner(&b)
|
||||
out := ""
|
||||
line := scanner.Text()
|
||||
@@ -150,5 +155,5 @@ func helpFunc() {
|
||||
lastLine = true
|
||||
}
|
||||
}
|
||||
fmt.Fprint(os.Stderr, out)
|
||||
fmt.Fprint(stderr, out)
|
||||
}
|
||||
|
||||
@@ -265,6 +265,15 @@
|
||||
"value": "",
|
||||
"advanced": true,
|
||||
"description": "Set a different URL for the sign-up form to redirect the user to when they've signed up. Default to 'Public Server' or 'Server' in the Jellyfin tab."
|
||||
},
|
||||
"auto_redirect": {
|
||||
"name": "Auto redirect on success",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"advanced": true,
|
||||
"description": "Navigate directly to the above URL instead of needing the user to click \"Continue\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -502,6 +511,14 @@
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Require an email address on sign-up."
|
||||
},
|
||||
"require_unique": {
|
||||
"name": "Require unique address",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Disables using the same address on multiple accounts."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -641,6 +658,14 @@
|
||||
"value": false,
|
||||
"description": "Require Discord connection on sign-up. See the jfa-go wiki for info on setting this up."
|
||||
},
|
||||
"require_unique": {
|
||||
"name": "Require unique user",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||
},
|
||||
"token": {
|
||||
"name": "API Token",
|
||||
"required": false,
|
||||
@@ -745,6 +770,14 @@
|
||||
"value": false,
|
||||
"description": "Require telegram connection on sign-up."
|
||||
},
|
||||
"require_unique": {
|
||||
"name": "Require unique user",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||
},
|
||||
"token": {
|
||||
"name": "API Token",
|
||||
"required": false,
|
||||
@@ -801,6 +834,14 @@
|
||||
"value": false,
|
||||
"description": "Require Matrix connection on sign-up."
|
||||
},
|
||||
"require_unique": {
|
||||
"name": "Require unique user",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Disables using the same user on multiple Jellyfin accounts."
|
||||
},
|
||||
"homeserver": {
|
||||
"name": "Home Server URL",
|
||||
"required": false,
|
||||
|
||||
34
css/base.css
34
css/base.css
@@ -27,17 +27,26 @@
|
||||
background-color: #101010;
|
||||
}
|
||||
|
||||
html:not(.dark) body {
|
||||
background-color: #fff;
|
||||
}
|
||||
|
||||
.dark select, .dark option, .dark input {
|
||||
background: #202020;
|
||||
}
|
||||
|
||||
html:not(.dark) .card.\@low:not(.\~neutral):not(.\~positive):not(.\~urge):not(.\~warning):not(.\~info):not(.\~critical) {
|
||||
--color-fill: va(--color-fill);
|
||||
--color-content: var(--color-content);
|
||||
--color-accent: var(--color-accent);
|
||||
--color-muted: var(--color-muted);
|
||||
html:not(.dark) .card.\@low:not(.\~neutral):not(.\~positive):not(.\~urge):not(.\~warning):not(.\~info):not(.\~critical),
|
||||
html:not(.dark) .card.\@low:not(.\~neutral):not(.\~positive):not(.\~urge):not(.\~warning):not(.\~info):not(.\~critical) > * {
|
||||
/* Colors from ~neutral */
|
||||
--color-fill-high: #64748b;
|
||||
--color-fill-low: #e2e8f0;
|
||||
--color-content-high: #f8fafc;
|
||||
--color-content-low: #1e293b;
|
||||
--color-accent-high: #475569;
|
||||
--color-accent-low: #cbd5e1;
|
||||
--color-muted-high: #475569;
|
||||
--color-muted-low: #f1f5f9;
|
||||
background-color: #fff;
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.light-only {
|
||||
@@ -425,6 +434,10 @@ p.top {
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
|
||||
.dropdown.over-top {
|
||||
position: absolute;
|
||||
}
|
||||
|
||||
.dropdown-display.lg {
|
||||
white-space: nowrap;
|
||||
}
|
||||
@@ -477,10 +490,10 @@ a:hover:not(.lang-link):not(.\~urge), a:active:not(.lang-link):not(.\~urge) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.search {
|
||||
/* .search {
|
||||
max-width: 15rem;
|
||||
min-width: 10rem;
|
||||
}
|
||||
} */
|
||||
|
||||
td.img-circle {
|
||||
width: 32px;
|
||||
@@ -535,6 +548,11 @@ div.card:contains(section.banner.footer) {
|
||||
padding-bottom: 0px !important
|
||||
}
|
||||
|
||||
.mx-0i {
|
||||
margin-left: 0px !important;
|
||||
margin-right: 0px !important
|
||||
}
|
||||
|
||||
.text-center-i {
|
||||
text-align: center !important;
|
||||
}
|
||||
|
||||
160
daemon.go
Normal file
160
daemon.go
Normal file
@@ -0,0 +1,160 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
// clearEmails removes stored emails for users which no longer exist.
|
||||
// meant to be called with other such housekeeping functions, so assumes
|
||||
// the user cache is fresh.
|
||||
func (app *appContext) clearEmails() {
|
||||
app.debug.Println("Housekeeping: removing unused email addresses")
|
||||
users, status, err := app.jf.GetUsers(false)
|
||||
if status != 200 || err != nil || len(users) == 0 {
|
||||
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||
return
|
||||
}
|
||||
// Rebuild email storage to from existing users to reduce time complexity
|
||||
emails := map[string]EmailAddress{}
|
||||
for _, user := range users {
|
||||
if email, ok := app.storage.emails[user.ID]; ok {
|
||||
emails[user.ID] = email
|
||||
}
|
||||
}
|
||||
app.storage.emails = emails
|
||||
app.storage.storeEmails()
|
||||
}
|
||||
|
||||
// clearDiscord does the same as clearEmails, but for Discord Users.
|
||||
func (app *appContext) clearDiscord() {
|
||||
app.debug.Println("Housekeeping: removing unused Discord IDs")
|
||||
users, status, err := app.jf.GetUsers(false)
|
||||
if status != 200 || err != nil || len(users) == 0 {
|
||||
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||
return
|
||||
}
|
||||
// Rebuild discord storage to from existing users to reduce time complexity
|
||||
dcUsers := map[string]DiscordUser{}
|
||||
for _, user := range users {
|
||||
if dcUser, ok := app.storage.discord[user.ID]; ok {
|
||||
dcUsers[user.ID] = dcUser
|
||||
}
|
||||
}
|
||||
app.storage.discord = dcUsers
|
||||
app.storage.storeDiscordUsers()
|
||||
}
|
||||
|
||||
// clearMatrix does the same as clearEmails, but for Matrix Users.
|
||||
func (app *appContext) clearMatrix() {
|
||||
app.debug.Println("Housekeeping: removing unused Matrix IDs")
|
||||
users, status, err := app.jf.GetUsers(false)
|
||||
if status != 200 || err != nil || len(users) == 0 {
|
||||
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||
return
|
||||
}
|
||||
// Rebuild matrix storage to from existing users to reduce time complexity
|
||||
mxUsers := map[string]MatrixUser{}
|
||||
for _, user := range users {
|
||||
if mxUser, ok := app.storage.matrix[user.ID]; ok {
|
||||
mxUsers[user.ID] = mxUser
|
||||
}
|
||||
}
|
||||
app.storage.matrix = mxUsers
|
||||
app.storage.storeMatrixUsers()
|
||||
}
|
||||
|
||||
// clearTelegram does the same as clearEmails, but for Telegram Users.
|
||||
func (app *appContext) clearTelegram() {
|
||||
app.debug.Println("Housekeeping: removing unused Telegram IDs")
|
||||
users, status, err := app.jf.GetUsers(false)
|
||||
if status != 200 || err != nil || len(users) == 0 {
|
||||
app.err.Printf("Failed to get users from Jellyfin (%d): %v", status, err)
|
||||
return
|
||||
}
|
||||
// Rebuild telegram storage to from existing users to reduce time complexity
|
||||
tgUsers := map[string]TelegramUser{}
|
||||
for _, user := range users {
|
||||
if tgUser, ok := app.storage.telegram[user.ID]; ok {
|
||||
tgUsers[user.ID] = tgUser
|
||||
}
|
||||
}
|
||||
app.storage.telegram = tgUsers
|
||||
app.storage.storeTelegramUsers()
|
||||
}
|
||||
|
||||
// https://bbengfort.github.io/snippets/2016/06/26/background-work-goroutines-timer.html THANKS
|
||||
|
||||
type housekeepingDaemon struct {
|
||||
Stopped bool
|
||||
ShutdownChannel chan string
|
||||
Interval time.Duration
|
||||
period time.Duration
|
||||
jobs []func(app *appContext)
|
||||
app *appContext
|
||||
}
|
||||
|
||||
func newInviteDaemon(interval time.Duration, app *appContext) *housekeepingDaemon {
|
||||
daemon := housekeepingDaemon{
|
||||
Stopped: false,
|
||||
ShutdownChannel: make(chan string),
|
||||
Interval: interval,
|
||||
period: interval,
|
||||
app: app,
|
||||
}
|
||||
daemon.jobs = []func(app *appContext){func(app *appContext) {
|
||||
app.debug.Println("Housekeeping: Checking for expired invites")
|
||||
app.checkInvites()
|
||||
}}
|
||||
|
||||
clearEmail := app.config.Section("email").Key("require_unique").MustBool(false)
|
||||
clearDiscord := app.config.Section("discord").Key("require_unique").MustBool(false)
|
||||
clearTelegram := app.config.Section("telegram").Key("require_unique").MustBool(false)
|
||||
clearMatrix := app.config.Section("matrix").Key("require_unique").MustBool(false)
|
||||
|
||||
if clearEmail || clearDiscord || clearTelegram || clearMatrix {
|
||||
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.jf.CacheExpiry = time.Now() })
|
||||
}
|
||||
|
||||
if clearEmail {
|
||||
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearEmails() })
|
||||
}
|
||||
if clearDiscord {
|
||||
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearDiscord() })
|
||||
}
|
||||
if clearTelegram {
|
||||
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearTelegram() })
|
||||
}
|
||||
if clearMatrix {
|
||||
daemon.jobs = append(daemon.jobs, func(app *appContext) { app.clearMatrix() })
|
||||
}
|
||||
|
||||
return &daemon
|
||||
}
|
||||
|
||||
func (rt *housekeepingDaemon) run() {
|
||||
rt.app.info.Println("Invite daemon started")
|
||||
for {
|
||||
select {
|
||||
case <-rt.ShutdownChannel:
|
||||
rt.ShutdownChannel <- "Down"
|
||||
return
|
||||
case <-time.After(rt.period):
|
||||
break
|
||||
}
|
||||
started := time.Now()
|
||||
rt.app.storage.loadInvites()
|
||||
|
||||
for _, job := range rt.jobs {
|
||||
job(rt.app)
|
||||
}
|
||||
|
||||
finished := time.Now()
|
||||
duration := finished.Sub(started)
|
||||
rt.period = rt.Interval - duration
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *housekeepingDaemon) Shutdown() {
|
||||
rt.Stopped = true
|
||||
rt.ShutdownChannel <- "Down"
|
||||
<-rt.ShutdownChannel
|
||||
close(rt.ShutdownChannel)
|
||||
}
|
||||
32
discord.go
32
discord.go
@@ -120,7 +120,7 @@ func (d *DiscordDaemon) run() {
|
||||
defer d.deregisterCommands()
|
||||
defer d.bot.Close()
|
||||
|
||||
d.registerCommands()
|
||||
go d.registerCommands()
|
||||
|
||||
<-d.ShutdownChannel
|
||||
d.ShutdownChannel <- "Down"
|
||||
@@ -210,10 +210,29 @@ func (d *DiscordDaemon) NewTempInvite(ageSeconds, maxUses int) (inviteURL, iconU
|
||||
d.app.err.Printf("Discord: Failed to get guild: %v", err)
|
||||
return
|
||||
}
|
||||
iconURL = guild.IconURL()
|
||||
iconURL = guild.IconURL("256")
|
||||
return
|
||||
}
|
||||
|
||||
// RenderDiscordUsername returns String of discord username, with support for new discriminator-less versions.
|
||||
func RenderDiscordUsername[DcUser *dg.User | DiscordUser](user DcUser) string {
|
||||
u, ok := interface{}(user).(*dg.User)
|
||||
var discriminator, username string
|
||||
if ok {
|
||||
discriminator = u.Discriminator
|
||||
username = u.Username
|
||||
} else {
|
||||
u2 := interface{}(user).(DiscordUser)
|
||||
discriminator = u2.Discriminator
|
||||
username = u2.Username
|
||||
}
|
||||
|
||||
if discriminator == "0" {
|
||||
return "@" + username
|
||||
}
|
||||
return username + "#" + discriminator
|
||||
}
|
||||
|
||||
// Returns the user(s) roughly corresponding to the username (if they are in the guild).
|
||||
// if no discriminator (#xxxx) is given in the username and there are multiple corresponding users, a list of all matching users is returned.
|
||||
func (d *DiscordDaemon) GetUsers(username string) []*dg.Member {
|
||||
@@ -227,6 +246,10 @@ func (d *DiscordDaemon) GetUsers(username string) []*dg.Member {
|
||||
return nil
|
||||
}
|
||||
hasDiscriminator := strings.Contains(username, "#")
|
||||
hasAt := strings.HasPrefix(username, "@")
|
||||
if hasAt {
|
||||
username = username[1:]
|
||||
}
|
||||
var users []*dg.Member
|
||||
for _, member := range members {
|
||||
if hasDiscriminator {
|
||||
@@ -234,6 +257,11 @@ func (d *DiscordDaemon) GetUsers(username string) []*dg.Member {
|
||||
return []*dg.Member{member}
|
||||
}
|
||||
}
|
||||
if hasAt {
|
||||
if member.User.Username == username && member.User.Discriminator == "0" {
|
||||
return []*dg.Member{member}
|
||||
}
|
||||
}
|
||||
if strings.Contains(member.User.Username, username) {
|
||||
users = append(users, member)
|
||||
}
|
||||
|
||||
2
email.go
2
email.go
@@ -863,7 +863,7 @@ func (app *appContext) sendByID(email *Message, ID ...string) error {
|
||||
|
||||
func (app *appContext) getAddressOrName(jfID string) string {
|
||||
if dcChat, ok := app.storage.discord[jfID]; ok && dcChat.Contact && discordEnabled {
|
||||
return dcChat.Username + "#" + dcChat.Discriminator
|
||||
return RenderDiscordUsername(dcChat)
|
||||
}
|
||||
if tgChat, ok := app.storage.telegram[jfID]; ok && tgChat.Contact && telegramEnabled {
|
||||
return "@" + tgChat.Username
|
||||
|
||||
32
exit.go
32
exit.go
@@ -5,13 +5,14 @@ import (
|
||||
"html/template"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/browser"
|
||||
"github.com/robert-nix/ansihtml"
|
||||
)
|
||||
|
||||
// https://gist.github.com/swdunlop/9629168
|
||||
@@ -43,6 +44,21 @@ func identifyPanic() string {
|
||||
return fmt.Sprintf("pc:%x", pc)
|
||||
}
|
||||
|
||||
// OpenFile attempts to open a given file in the appropriate GUI application.
|
||||
func OpenFile(fpath string) (err error) {
|
||||
switch PLATFORM {
|
||||
case "linux":
|
||||
err = exec.Command("xdg-open", fpath).Start()
|
||||
case "windows":
|
||||
err = exec.Command("rundll32", "url.dll,FileProtocolHandler", fpath).Start()
|
||||
case "darwin":
|
||||
err = exec.Command("open", fpath).Start()
|
||||
default:
|
||||
err = fmt.Errorf("unknown os")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// Exit dumps the last 100 lines of output to a crash file in /tmp (or equivalent), and generates a prettier HTML file containing it that is opened in the browser if possible.
|
||||
func Exit(err interface{}) {
|
||||
tmpl, err2 := template.ParseFS(localFS, "html/crash.html", "html/header.html")
|
||||
@@ -63,12 +79,19 @@ func Exit(err interface{}) {
|
||||
if err != nil {
|
||||
data["Err"] = fmt.Sprintf("%s %v", identifyPanic(), err)
|
||||
}
|
||||
fpath := filepath.Join(temp, "jfa-go-crash-"+time.Now().Local().Format("2006-01-02T15:04:05"))
|
||||
// Use dashes for time rather than colons for Windows
|
||||
fpath := filepath.Join(temp, "jfa-go-crash-"+time.Now().Local().Format("2006-01-02T15-04-05"))
|
||||
err2 = os.WriteFile(fpath+".txt", []byte(logCache), 0666)
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to write crash dump file: %v", err2)
|
||||
}
|
||||
log.Printf("\n------\nA crash report has been saved to \"%s\".\n------", fpath+".txt")
|
||||
|
||||
// Render ANSI colors to HTML
|
||||
data["Log"] = template.HTML(string(ansihtml.ConvertToHTML([]byte(data["Log"].(string)))))
|
||||
data["SanitizedLog"] = template.HTML(string(ansihtml.ConvertToHTML([]byte(data["SanitizedLog"].(string)))))
|
||||
data["Err"] = template.HTML(string(ansihtml.ConvertToHTML([]byte(data["Err"].(string)))))
|
||||
|
||||
f, err2 := os.OpenFile(fpath+".html", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to open crash dump file: %v", err2)
|
||||
@@ -78,7 +101,10 @@ func Exit(err interface{}) {
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to execute template: %v", err2)
|
||||
}
|
||||
browser.OpenFile(fpath + ".html")
|
||||
if err := OpenFile(fpath + ".html"); err != nil {
|
||||
log.Printf("Failed to open browser, trying text file...")
|
||||
OpenFile(fpath + ".txt")
|
||||
}
|
||||
if TRAY {
|
||||
QuitTray()
|
||||
} else {
|
||||
|
||||
134
go.mod
134
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/hrfee/jfa-go
|
||||
|
||||
go 1.16
|
||||
go 1.20
|
||||
|
||||
replace github.com/hrfee/jfa-go/docs => ./docs
|
||||
|
||||
@@ -12,54 +12,104 @@ replace github.com/hrfee/jfa-go/logger => ./logger
|
||||
|
||||
replace github.com/hrfee/jfa-go/linecache => ./linecache
|
||||
|
||||
replace github.com/hrfee/jfa-go/api => ./api
|
||||
|
||||
require (
|
||||
github.com/bwmarrin/discordgo v0.23.3-0.20211228023845-29269347e820
|
||||
github.com/bwmarrin/discordgo v0.27.1
|
||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/fsnotify/fsnotify v1.5.1
|
||||
github.com/getlantern/golog v0.0.0-20210606115803-bce9f9fe5a5f // indirect
|
||||
github.com/getlantern/hidden v0.0.0-20201229170000-e66e7f878730 // indirect
|
||||
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 // indirect
|
||||
github.com/getlantern/systray v1.1.0
|
||||
github.com/gin-contrib/pprof v1.3.0
|
||||
github.com/fatih/color v1.15.0
|
||||
github.com/fsnotify/fsnotify v1.6.0
|
||||
github.com/getlantern/systray v1.2.2
|
||||
github.com/gin-contrib/pprof v1.4.0
|
||||
github.com/gin-contrib/static v0.0.1
|
||||
github.com/gin-gonic/gin v1.7.7
|
||||
github.com/go-playground/validator/v10 v10.9.0 // indirect
|
||||
github.com/go-stack/stack v1.8.1 // indirect
|
||||
github.com/gin-gonic/gin v1.9.1
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible
|
||||
github.com/golang/protobuf v1.5.2 // indirect
|
||||
github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hrfee/jfa-go/common v0.0.0-20211222231100-d47afe05f49c
|
||||
github.com/hrfee/jfa-go/docs v0.0.0-20211222231100-d47afe05f49c
|
||||
github.com/hrfee/jfa-go/linecache v0.0.0-20211222231100-d47afe05f49c
|
||||
github.com/hrfee/jfa-go/logger v0.0.0-20211222231100-d47afe05f49c
|
||||
github.com/hrfee/jfa-go/ombi v0.0.0-20211222231100-d47afe05f49c
|
||||
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a
|
||||
github.com/hrfee/jfa-go/common v0.0.0-20230421170108-d800b97f69b6
|
||||
github.com/hrfee/jfa-go/docs v0.0.0-20230421170108-d800b97f69b6
|
||||
github.com/hrfee/jfa-go/linecache v0.0.0-20230421170108-d800b97f69b6
|
||||
github.com/hrfee/jfa-go/logger v0.0.0-20230421170108-d800b97f69b6
|
||||
github.com/hrfee/jfa-go/ombi v0.0.0-20230421170108-d800b97f69b6
|
||||
github.com/hrfee/mediabrowser v0.3.8
|
||||
github.com/itchyny/timefmt-go v0.1.3
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/itchyny/timefmt-go v0.1.5
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||
github.com/mailgun/mailgun-go/v4 v4.6.0
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.12 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/mailgun/mailgun-go/v4 v4.9.0
|
||||
github.com/robert-nix/ansihtml v1.0.1
|
||||
github.com/steambap/captcha v1.4.1
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2
|
||||
github.com/swaggo/gin-swagger v1.3.3
|
||||
github.com/swaggo/swag v1.7.8 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.4 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
github.com/swaggo/files v1.0.1
|
||||
github.com/swaggo/gin-swagger v1.6.0
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce // indirect
|
||||
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba // indirect
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect
|
||||
golang.org/x/tools v0.1.8 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/ini.v1 v1.66.2
|
||||
maunium.net/go/mautrix v0.10.7
|
||||
github.com/xhit/go-simple-mail/v2 v2.13.0
|
||||
gopkg.in/ini.v1 v1.67.0
|
||||
maunium.net/go/mautrix v0.15.2
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/KyleBanks/depth v1.2.1 // indirect
|
||||
github.com/bytedance/sonic v1.9.1 // indirect
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 // indirect
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
|
||||
github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 // indirect
|
||||
github.com/getlantern/errors v1.0.3 // indirect
|
||||
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 // indirect
|
||||
github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc // indirect
|
||||
github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 // indirect
|
||||
github.com/getlantern/ops v0.0.0-20230519221840-1283e026181c // indirect
|
||||
github.com/gin-contrib/sse v0.1.0 // indirect
|
||||
github.com/go-logr/logr v1.2.4 // indirect
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/go-openapi/jsonpointer v0.19.6 // indirect
|
||||
github.com/go-openapi/jsonreference v0.20.2 // indirect
|
||||
github.com/go-openapi/spec v0.20.9 // indirect
|
||||
github.com/go-openapi/swag v0.22.4 // indirect
|
||||
github.com/go-playground/locales v0.14.1 // indirect
|
||||
github.com/go-playground/universal-translator v0.18.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.14.1 // indirect
|
||||
github.com/go-stack/stack v1.8.1 // indirect
|
||||
github.com/go-test/deep v1.1.0 // indirect
|
||||
github.com/goccy/go-json v0.10.2 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/gorilla/mux v1.8.0 // indirect
|
||||
github.com/gorilla/websocket v1.5.0 // indirect
|
||||
github.com/josharian/intern v1.0.0 // indirect
|
||||
github.com/json-iterator/go v1.1.12 // indirect
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 // indirect
|
||||
github.com/leodido/go-urn v1.2.4 // indirect
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
|
||||
github.com/modern-go/reflect2 v1.0.2 // indirect
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 // indirect
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/rs/zerolog v1.29.1 // indirect
|
||||
github.com/swaggo/swag v1.16.1 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/tidwall/gjson v1.14.4 // indirect
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
github.com/tidwall/sjson v1.2.5 // indirect
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 // indirect
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 // indirect
|
||||
github.com/ugorji/go/codec v1.2.11 // indirect
|
||||
go.opentelemetry.io/otel v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/metric v1.16.0 // indirect
|
||||
go.opentelemetry.io/otel/trace v1.16.0 // indirect
|
||||
go.uber.org/atomic v1.11.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
go.uber.org/zap v1.24.0 // indirect
|
||||
golang.org/x/arch v0.3.0 // indirect
|
||||
golang.org/x/crypto v0.9.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
|
||||
golang.org/x/image v0.7.0 // indirect
|
||||
golang.org/x/net v0.10.0 // indirect
|
||||
golang.org/x/sys v0.8.0 // indirect
|
||||
golang.org/x/text v0.9.0 // indirect
|
||||
golang.org/x/tools v0.9.3 // indirect
|
||||
google.golang.org/protobuf v1.30.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
maunium.net/go/maulogger/v2 v2.4.1 // indirect
|
||||
)
|
||||
|
||||
388
go.sum
388
go.sum
@@ -1,31 +1,24 @@
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tNFfI=
|
||||
github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 h1:d+Bc7a5rLufV/sSk/8dngufqelfh6jnri85riMAaF/M=
|
||||
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE=
|
||||
github.com/aead/siphash v1.0.1/go.mod h1:Nywa3cDsYNNK3gaciGTWPwHt0wlpNV15vwmswBAUSII=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
|
||||
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/btcsuite/btcd v0.20.1-beta/go.mod h1:wVuoA8VJLEcwgqHBwHmzLRazpKxTv13Px/pDuV7OomQ=
|
||||
github.com/btcsuite/btclog v0.0.0-20170628155309-84c8d2346e9f/go.mod h1:TdznJufoqS23FtqVCzL0ZqgP5MqXbb4fg/WgDys70nA=
|
||||
github.com/btcsuite/btcutil v0.0.0-20190425235716-9e5f4b9a998d/go.mod h1:+5NJ2+qvTyV9exUAL/rxXi3DcLg2Ts+ymUAY5y4NvMg=
|
||||
github.com/btcsuite/btcutil v1.0.2 h1:9iZ1Terx9fMIOtq1VrwdqfsATL9MC2l8ZrUY6YZ2uts=
|
||||
github.com/btcsuite/btcutil v1.0.2/go.mod h1:j9HUFwoQRsZL3V4n+qG+CUnEGHOarIxfC3Le2Yhbcts=
|
||||
github.com/btcsuite/go-socks v0.0.0-20170105172521-4720035b7bfd/go.mod h1:HHNXQzUsZCxOoE+CPiyCTO6x34Zs86zZUiwtpXoGdtg=
|
||||
github.com/btcsuite/goleveldb v0.0.0-20160330041536-7834afc9e8cd/go.mod h1:F+uVaaLLH7j4eDXPRvw78tMflu7Ie2bzYOH4Y8rRKBY=
|
||||
github.com/btcsuite/snappy-go v0.0.0-20151229074030-0bdef8d06723/go.mod h1:8woku9dyThutzjeg+3xrA5iCpBRH8XEEg3lh6TiUghc=
|
||||
github.com/btcsuite/websocket v0.0.0-20150119174127-31079b680792/go.mod h1:ghJtEyQwv5/p4Mg4C0fgbePVuGr935/5ddU9Z3TmDRY=
|
||||
github.com/btcsuite/winsvc v1.0.0/go.mod h1:jsenWakMcC0zFBFurPLEAyrnc/teJEM1O46fmI40EZs=
|
||||
github.com/bwmarrin/discordgo v0.23.3-0.20211228023845-29269347e820 h1:MIW5DnBVJAgAy4LYBqWwIMBB0ezklvh8b7DsYvHZHb0=
|
||||
github.com/bwmarrin/discordgo v0.23.3-0.20211228023845-29269347e820/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8=
|
||||
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
|
||||
github.com/bwmarrin/discordgo v0.27.1 h1:ib9AIc/dom1E/fSIulrBwnez0CToJE113ZGt4HoliGY=
|
||||
github.com/bwmarrin/discordgo v0.27.1/go.mod h1:NJZpH+1AfhIcyQsPeuBKsUtYrRnjkyu0kIVMCHkZtRY=
|
||||
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
|
||||
github.com/bytedance/sonic v1.9.1 h1:6iJ6NqdoxCDr6mbY8h18oSO+cShGSMRGCEo7F2h0x8s=
|
||||
github.com/bytedance/sonic v1.9.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311 h1:qSGYFH7+jGhDF8vLC+iwCD4WpbV1EBDSzWkJODFLams=
|
||||
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
|
||||
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
|
||||
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
|
||||
github.com/davecgh/go-spew v0.0.0-20171005155431-ecdeabc65495/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
@@ -38,36 +31,39 @@ github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqL
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y=
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
|
||||
github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI=
|
||||
github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
||||
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
|
||||
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
|
||||
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
|
||||
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2 h1:w5qFW6JKBz9Y393Y4q372O9A7cUSequkh1Q7OhCmWKU=
|
||||
github.com/gabriel-vasile/mimetype v1.4.2/go.mod h1:zApsH/mKG4w07erKIaJPFiX0Tsq9BFQgN3qGY5GnNgA=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
||||
github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201 h1:oEZYEpZo28Wdx+5FZo4aU7JFXu0WG/4wJWese5reQSA=
|
||||
github.com/getlantern/context v0.0.0-20220418194847-3d5e7a086201/go.mod h1:Y9WZUHEb+mpra02CbQ/QczLUe6f0Dezxaw5DCJlJQGo=
|
||||
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
|
||||
github.com/getlantern/errors v1.0.1 h1:XukU2whlh7OdpxnkXhNH9VTLVz0EVPGKDV5K0oWhvzw=
|
||||
github.com/getlantern/errors v1.0.1/go.mod h1:l+xpFBrCtDLpK9qNjxs+cHU6+BAdlBaxHqikB6Lku3A=
|
||||
github.com/getlantern/errors v1.0.3 h1:Ne4Ycj7NI1BtSyAfVeAT/DNoxz7/S2BUc3L2Ht1YSHE=
|
||||
github.com/getlantern/errors v1.0.3/go.mod h1:m8C7H1qmouvsGpwQqk/6NUpIVMpfzUPn608aBZDYV04=
|
||||
github.com/getlantern/golog v0.0.0-20190830074920-4ef2e798c2d7/go.mod h1:zx/1xUUeYPy3Pcmet8OSXLbF47l+3y6hIPpyLWoR9oc=
|
||||
github.com/getlantern/golog v0.0.0-20210606115803-bce9f9fe5a5f h1:wsVt3P/boVKkPFEZkWxgNgRq/+mD7sWHc17+Vw2PgH8=
|
||||
github.com/getlantern/golog v0.0.0-20210606115803-bce9f9fe5a5f/go.mod h1:ZyIjgH/1wTCl+B+7yH1DqrWp6MPJqESmwmEQ89ZfhvA=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7 h1:micT5vkcr9tOVk1FiH8SWKID8ultN44Z+yzd2y/Vyb0=
|
||||
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65 h1:NlQedYmPI3pRAXJb+hLVVDGqfvvXGRPV8vp7XOjKAZ0=
|
||||
github.com/getlantern/golog v0.0.0-20230503153817-8e72de7e0a65/go.mod h1:+ZU1h+iOVqWReBpky6d5Y2WL0sF2Llxu+QcxJFs2+OU=
|
||||
github.com/getlantern/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
|
||||
github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc h1:sue+aeVx7JF5v36H1HfvcGFImLpSD5goj8d+MitovDU=
|
||||
github.com/getlantern/hex v0.0.0-20220104173244-ad7e4b9194dc/go.mod h1:D9RWpXy/EFPYxiKUURo2TB8UBosbqkiLhttRrZYtvqM=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
|
||||
github.com/getlantern/hidden v0.0.0-20201229170000-e66e7f878730 h1:oKJVQbWZ2CAJ71jYnm6A3+e6h5bkPJ0okIMwkaYB5HI=
|
||||
github.com/getlantern/hidden v0.0.0-20201229170000-e66e7f878730/go.mod h1:6mmzY2kW1TOOrVy+r41Za2MxXM+hhqTtY3oBKd2AgFA=
|
||||
github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770 h1:cSrD9ryDfTV2yaur9Qk3rHYD414j3Q1rl7+L0AylxrE=
|
||||
github.com/getlantern/hidden v0.0.0-20220104173330-f221c5a24770/go.mod h1:GOQsoDnEHl6ZmNIL+5uVo+JWRFWozMEp18Izcb++H+A=
|
||||
github.com/getlantern/ops v0.0.0-20190325191751-d70cb0d6f85f/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
|
||||
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6 h1:QthAQCekS1YOeYWSvoHI6ZatlG4B+GBDLxV/2ZkBsTA=
|
||||
github.com/getlantern/ops v0.0.0-20200403153110-8476b16edcd6/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
|
||||
github.com/getlantern/systray v1.1.0 h1:U0wCEqseLi2ok1fE6b88gJklzriavPJixZysZPkZd/Y=
|
||||
github.com/getlantern/systray v1.1.0/go.mod h1:AecygODWIsBquJCJFop8MEQcJbWFfw/1yWbVabNgpCM=
|
||||
github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
|
||||
github.com/getlantern/ops v0.0.0-20220713155959-1315d978fff7/go.mod h1:D5ao98qkA6pxftxoqzibIBBrLSUli+kYnJqrgBf9cIA=
|
||||
github.com/getlantern/ops v0.0.0-20230519221840-1283e026181c h1:qcPAzA1ZDnwx618jAgQmxo6UvJkw2SkM1L4ofncmEhI=
|
||||
github.com/getlantern/ops v0.0.0-20230519221840-1283e026181c/go.mod h1:g2ueCncOwWenlAr56Fh90FwsACkelqqtFUDLAHg1mng=
|
||||
github.com/getlantern/systray v1.2.2 h1:dCEHtfmvkJG7HZ8lS/sLklTH4RKUcIsKrAD9sThoEBE=
|
||||
github.com/getlantern/systray v1.2.2/go.mod h1:pXFOI1wwqwYXEhLPm9ZGjS2u/vVELeIgNMY5HvhHhcE=
|
||||
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.1/go.mod h1:fGBJBCdt6qCZuCAOwWuFhBB4OOq9EFqlo5dEaFhhu5w=
|
||||
github.com/gin-contrib/gzip v0.0.3 h1:etUaeesHhEORpZMp18zoOhepboiWnFtXrBZxszWUn4k=
|
||||
github.com/gin-contrib/gzip v0.0.3/go.mod h1:YxxswVZIqOvcHEQpsSn+QF5guQtO1dCfy0shBPy4jFc=
|
||||
github.com/gin-contrib/pprof v1.3.0 h1:G9eK6HnbkSqDZBYbzG4wrjCsA4e+cvYAHUZw6W+W9K0=
|
||||
github.com/gin-contrib/pprof v1.3.0/go.mod h1:waMjT1H9b179t3CxuG1cV3DHpga6ybizwfBaM5OXaB0=
|
||||
github.com/gin-contrib/gzip v0.0.6 h1:NjcunTcGAj5CO1gn4N8jHOSIeRFHIbn51z6K+xaN4d4=
|
||||
github.com/gin-contrib/pprof v1.4.0 h1:XxiBSf5jWZ5i16lNOPbMTVdgHBdhfGRD5PZ1LWazzvg=
|
||||
github.com/gin-contrib/pprof v1.4.0/go.mod h1:RrehPJasUVBPK6yTUwOl8/NP6i0vbUgmxtis+Z5KE90=
|
||||
github.com/gin-contrib/sse v0.0.0-20170109093832-22d885f9ecc7/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s=
|
||||
github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE=
|
||||
@@ -76,52 +72,65 @@ github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Sw
|
||||
github.com/gin-contrib/static v0.0.1/go.mod h1:CSxeF+wep05e0kCOsqWdAWbSszmc31zTIbD8TvWl7Hs=
|
||||
github.com/gin-gonic/gin v1.3.0/go.mod h1:7cKuhb5qV2ggCFctp2fJQ+ErvciLZrIeoOSOm6mUr7Y=
|
||||
github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM=
|
||||
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.7 h1:3DoBmSbJbZAWqXJC3SLjAPfutPJJRN1U5pALB7EeTTs=
|
||||
github.com/gin-gonic/gin v1.7.7/go.mod h1:axIBovoeJpVj8S3BwE0uPMTeReE4+AfFtqpqaZ1qq1U=
|
||||
github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk=
|
||||
github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg=
|
||||
github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU=
|
||||
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
|
||||
github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
|
||||
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
|
||||
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
|
||||
github.com/go-openapi/jsonpointer v0.17.0/go.mod h1:cOnomiV+CVVwFLk0A/MExoFMjwdsUdVpsRhURCKh+3M=
|
||||
github.com/go-openapi/jsonpointer v0.19.2/go.mod h1:3akKfEdA7DF1sugOqz1dVQHBcuDBPKZGEoHC/NkiQRg=
|
||||
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.5 h1:gZr+CIYByUqjcgeLXnQu2gHYQC9o73G2XUeOFYEICuY=
|
||||
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
|
||||
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
|
||||
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
|
||||
github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3HfopLOL6uZrK/VgnsK9I=
|
||||
github.com/go-openapi/jsonreference v0.19.2/go.mod h1:jMjeRr2HHw6nAVajTXJ4eiUwohSTlpa0o73RUL1owJc=
|
||||
github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8=
|
||||
github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/jsonreference v0.19.6 h1:UBIxjkht+AWIgYzCDSv2GN+E/togfwXUJFRTWhl2Jjs=
|
||||
github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns=
|
||||
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
|
||||
github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
|
||||
github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
|
||||
github.com/go-openapi/spec v0.19.0/go.mod h1:XkF/MOi14NmjsfZ8VtAKf8pIlbZzyoTvZsdfssdxcBI=
|
||||
github.com/go-openapi/spec v0.19.4/go.mod h1:FpwSN1ksY1eteniUU7X0N/BgJ7a4WvBFVA8Lj9mJglo=
|
||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
||||
github.com/go-openapi/spec v0.20.4 h1:O8hJrt0UMnhHcluhIdUgCLRWyM2x7QkBXRvOs7m+O1M=
|
||||
github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I=
|
||||
github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8=
|
||||
github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
|
||||
github.com/go-openapi/swag v0.17.0/go.mod h1:AByQ+nYG6gQg71GINrmuDXCPWdL640yX49/kXLo40Tg=
|
||||
github.com/go-openapi/swag v0.19.2/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk=
|
||||
github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-openapi/swag v0.19.15 h1:D2NRCBzS9/pEY3gP9Nl8aDqGUcPFrwG2p+CNFrLyrCM=
|
||||
github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
|
||||
github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A=
|
||||
github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU=
|
||||
github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14=
|
||||
github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4=
|
||||
github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s=
|
||||
github.com/go-playground/locales v0.13.0/go.mod h1:taPMhCMXrRLJO55olJkUXHZBHCxTMfnGwq/HNwmWNS8=
|
||||
github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU=
|
||||
github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs=
|
||||
github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA=
|
||||
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
|
||||
github.com/go-playground/universal-translator v0.17.0/go.mod h1:UkSxE5sNxxRwHyU+Scu5vgOQjsIJAF8j9muTVoKLVtA=
|
||||
github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho=
|
||||
github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA=
|
||||
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
|
||||
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
|
||||
github.com/go-playground/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-playground/validator/v10 v10.9.0 h1:NgTtmN58D0m8+UuxtYmGztBJB7VnPgjj221I1QHci2A=
|
||||
github.com/go-playground/validator/v10 v10.9.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.10.0/go.mod h1:74x4gJWsvQexRdW8Pn3dXSGrTK4nAUsbPlLADvpJkos=
|
||||
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
|
||||
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw=
|
||||
github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible h1:2cauKuaELYAEARXRkq2LrJ0yDDv1rW7+wrTEdVL3uaU=
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible/go.mod h1:qf9acutJ8cwBUhm1bqgz6Bei9/C/c93FPDljKWwsOgM=
|
||||
github.com/gofrs/uuid v4.0.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
|
||||
github.com/go-test/deep v1.1.0 h1:WOcxcdHcvdgThNXjw0t76K42FXTU7HpNQWHpA2HHNlg=
|
||||
github.com/go-test/deep v1.1.0/go.mod h1:5C2ZWiW0ErCdrYzpqxLbTX7MG14M9iiw8DgHncVwcsE=
|
||||
github.com/goccy/go-json v0.9.7/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU=
|
||||
github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I=
|
||||
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY=
|
||||
github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
@@ -130,38 +139,35 @@ github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5y
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw=
|
||||
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
|
||||
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
|
||||
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
|
||||
github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df h1:M7mdNDTRraBcrHZg2aOYiFP9yTDajb6fquRZRpXnbVA=
|
||||
github.com/gomarkdown/markdown v0.0.0-20211212230626-5af6ad2f47df/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a h1:AWZzzFrqyjYlRloN6edwTLTUbKxf5flLXNuTBDm3Ews=
|
||||
github.com/gomarkdown/markdown v0.0.0-20230322041520-c84983bdbf2a/go.mod h1:JDGcbDT52eL4fju3sZ4TeHGsQwhG9nbDV21aMyhwPoA=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
|
||||
github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI=
|
||||
github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So=
|
||||
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/hrfee/mediabrowser v0.3.8 h1:y0iBCb6jE3QKcsiCJSYva2fFPHRn4UA+sGRzoPuJ/Dk=
|
||||
github.com/hrfee/mediabrowser v0.3.8/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||
github.com/itchyny/timefmt-go v0.1.3 h1:7M3LGVDsqcd0VZH2U+x393obrzZisp7C0uEe921iRkU=
|
||||
github.com/itchyny/timefmt-go v0.1.3/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
|
||||
github.com/jessevdk/go-flags v0.0.0-20141203071132-1679536dcc89/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/itchyny/timefmt-go v0.1.5 h1:G0INE2la8S6ru/ZI5JecgyzbbJNs5lG1RcBqa7Jm6GE=
|
||||
github.com/itchyny/timefmt-go v0.1.5/go.mod h1:nEP7L+2YmAbT2kZ2HfSs1d8Xtw9LY8D2stDBckWakZ8=
|
||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||
github.com/jrick/logrotate v1.0.0/go.mod h1:LNinyqDIJnpAur+b8yyulnQw/wDuN1+BYKlTRt3OuAQ=
|
||||
github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
|
||||
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/qbZg=
|
||||
github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0=
|
||||
@@ -172,12 +178,15 @@ github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/leodido/go-urn v1.2.0/go.mod h1:+8+nEpDfqqsY+g338gtMEUOtuK+4dEMhiQEgxpxOKII=
|
||||
github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w=
|
||||
github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY=
|
||||
github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q=
|
||||
github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7 h1:trX0KTHy4Pbwo/6ia8fscyHoGA+mf1jWbPJVuvyJQQ8=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7/go.mod h1:vMk8ke37EmiewwolSO1NLW8vP4ZaKlRuDIi8tWWmAts=
|
||||
github.com/mailgun/mailgun-go/v4 v4.6.0 h1:qSrgT3wP5fU7wF/tNUp4xeYe8wSUy+8V5NJPYnB6Hxo=
|
||||
github.com/mailgun/mailgun-go/v4 v4.6.0/go.mod h1:FJlF9rI5cQT+mrwujtJjPMbIVy3Ebor9bKTVsJ0QU40=
|
||||
github.com/lxn/walk v0.0.0-20210112085537-c389da54e794/go.mod h1:E23UucZGqpuUANJooIbHWCufXvOcT6E7Stq81gU+CSQ=
|
||||
github.com/lxn/win v0.0.0-20210218163916-a377121e959e/go.mod h1:KxxjdtRkfNoYDCUP5ryK7XJJNTnpC8atvtmTheChOtk=
|
||||
github.com/mailgun/mailgun-go/v4 v4.9.0 h1:wRbxvVQ5QObFewLxc1uVvipA16D8gxeiO+cBOca51Iw=
|
||||
github.com/mailgun/mailgun-go/v4 v4.9.0/go.mod h1:FJlF9rI5cQT+mrwujtJjPMbIVy3Ebor9bKTVsJ0QU40=
|
||||
github.com/mailru/easyjson v0.0.0-20180823135443-60711f1a8329/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
|
||||
@@ -185,17 +194,18 @@ github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJ
|
||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||
github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
|
||||
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-sqlite3 v1.14.9 h1:10HX2Td0ocZpYEjhilsuo6WWtUqttj2Kb0KtD86/KYA=
|
||||
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
|
||||
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
|
||||
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
|
||||
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
|
||||
@@ -204,111 +214,130 @@ github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3Rllmb
|
||||
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
|
||||
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE=
|
||||
github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
|
||||
github.com/otiai10/copy v1.7.0 h1:hVoPiN+t+7d2nzzwMiDHPSOogsWAStewq3TwU05+clE=
|
||||
github.com/otiai10/copy v1.7.0/go.mod h1:rmRl6QPdJj6EiUqXQ/4Nn2lLXoNQjFCQbbNrxgc/t3U=
|
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE=
|
||||
github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs=
|
||||
github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo=
|
||||
github.com/otiai10/mint v1.3.3/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c h1:rp5dCmg/yLR3mgFuSOe4oEnDDmGLROTvMragMUXpTQw=
|
||||
github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c/go.mod h1:X07ZCGwUbLaax7L0S3Tw4hpejzu63ZrrQiUe6W0hcy0=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
|
||||
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pelletier/go-toml/v2 v2.0.1/go.mod h1:r9LEWfGN8R5k0VXJ+0BkIe7MYkRdwZOjgMj2KwnJFUo=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
|
||||
github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/robert-nix/ansihtml v1.0.1 h1:VTiyQ6/+AxSJoSSLsMecnkh8i0ZqOEdiRl/odOc64fc=
|
||||
github.com/robert-nix/ansihtml v1.0.1/go.mod h1:CJwclxYaTPc2RfcxtanEACsYuTksh4yDXcNeHHKZINE=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
|
||||
github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc=
|
||||
github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
|
||||
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0/go.mod h1:dA0hQrYB0VpLJoorglMZABFdXlWrHn1NEOzdhQKdks0=
|
||||
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA=
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/steambap/captcha v1.4.1 h1:OmMdxLCWCqJvsFaFYwRpvMckIuvI6s8s1LsBrBw97P0=
|
||||
github.com/steambap/captcha v1.4.1/go.mod h1:oC9T7IfEgnrhzjDz5Djf1H7GPffCzRMbsQfFkJmhlnk=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
|
||||
github.com/stretchr/testify v1.8.3 h1:RP3t2pwF7cMEbC1dqtB6poj3niw/9gnV4Cjg5oW5gtY=
|
||||
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14/go.mod h1:gxQT6pBGRuIGunNf/+tSOB5OHvguWi8Tbt82WOkf35E=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2 h1:+iNTcqQJy0OZ5jk6a5NLib47eqXK8uYcPX+O4+cBpEM=
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2/go.mod h1:lKJPbtWzJ9JhsTN1k1gZgleJWY/cqq0psdoMmaThG3w=
|
||||
github.com/swaggo/files v1.0.1 h1:J1bVJ4XHZNq0I46UU90611i9/YzdrF7x92oX1ig5IdE=
|
||||
github.com/swaggo/files v1.0.1/go.mod h1:0qXmMNH6sXNf+73t65aKeB+ApmgxdnkQzVTAj2uaMUg=
|
||||
github.com/swaggo/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||
github.com/swaggo/gin-swagger v1.3.3 h1:XHyYmeNVFG5PbyWHG4jXtxOm2P4kiZapDCWsyDDiQ/I=
|
||||
github.com/swaggo/gin-swagger v1.3.3/go.mod h1:ymsZuGpbbu+S7ZoQ49QPpZoDBj6uqhb8WizgQPVgWl0=
|
||||
github.com/swaggo/gin-swagger v1.6.0 h1:y8sxvQ3E20/RCyrXeFfg60r6H0Z+SwpTjMYsMm+zy8M=
|
||||
github.com/swaggo/gin-swagger v1.6.0/go.mod h1:BG00cCEy294xtVpyIAHG6+e2Qzj/xKlRdOqDkvq0uzo=
|
||||
github.com/swaggo/swag v1.5.1/go.mod h1:1Bl9F/ZBpVWh22nY0zmYyASPO1lI/zIwRDrpZU+tv8Y=
|
||||
github.com/swaggo/swag v1.6.7/go.mod h1:xDhTyuFIujYiN3DKWC/H/83xcfHp+UE/IzWWampG7Zc=
|
||||
github.com/swaggo/swag v1.7.4/go.mod h1:zD8h6h4SPv7t3l+4BKdRquqW1ASWjKZgT6Qv9z3kNqI=
|
||||
github.com/swaggo/swag v1.7.8 h1:w249t0l/kc/DKMGlS0fppNJQxKyJ8heNaUWB6nsH3zc=
|
||||
github.com/swaggo/swag v1.7.8/go.mod h1:gZ+TJ2w/Ve1RwQsA2IRoSOTidHz6DX+PIG8GWvbnoLU=
|
||||
github.com/swaggo/swag v1.16.1 h1:fTNRhKstPKxcnoKsytm4sahr8FaYzUcT7i1/3nd/fBg=
|
||||
github.com/swaggo/swag v1.16.1/go.mod h1:9/LMvHycG3NFHfR6LwvikHv5iFvmPADQ359cKikGxto=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 h1:XRztA5MXiR1TIRHxH2uNxXxaIkKQDeX7m2XsSOlQEnM=
|
||||
github.com/technoweenie/multipartstreamer v1.0.1/go.mod h1:jNVxdtShOxzAsukZwTSw6MDx5eUJoiEBsSvzDU9uzog=
|
||||
github.com/tidwall/gjson v1.10.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.12.1 h1:ikuZsLdhr8Ws0IdROXUS1Gi4v9Z4pGqpX/CvJkxvfpo=
|
||||
github.com/tidwall/gjson v1.12.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
|
||||
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.2.0 h1:RWIZEg2iJ8/g6fDDYzMpobmaoGh5OLl4AXtGUGPcqCs=
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.3/go.mod h1:5WdjKx3AQMvCJ4RG6/2UYT7dLrGvJUV1x4jdTAyGvZs=
|
||||
github.com/tidwall/sjson v1.2.4 h1:cuiLzLnaMeBhRmEv00Lpk3tkYrcxpmbU81tAY4Dw0tc=
|
||||
github.com/tidwall/sjson v1.2.4/go.mod h1:098SZ494YoMWPmMO6ct4dcFnqxwj9r/gF0Etp19pSNM=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY=
|
||||
github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28=
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208 h1:PM5hJF7HVfNWmCjMdEfbuOBNXSVF2cMFGgQTPdKCbwM=
|
||||
github.com/toorop/go-dkim v0.0.0-20201103131630-e1cd1a0a5208/go.mod h1:BzWtXXrXzZUvMacR0oF/fbDDgUPO8L36tDMmRAf14ns=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI=
|
||||
github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08=
|
||||
github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc=
|
||||
github.com/ugorji/go v1.1.5-pre/go.mod h1:FwP/aQVg39TXzItUBMwnWp9T9gPQnXw4Poh4/oBQZ/0=
|
||||
github.com/ugorji/go v1.1.7/go.mod h1:kZn38zHttfInRq0xu/PH0az30d+z6vm202qpg1oXVMw=
|
||||
github.com/ugorji/go v1.2.6 h1:tGiWC9HENWE2tqYycIqFTNorMmFRVhNwCpDOpWqnk8E=
|
||||
github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0=
|
||||
github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M=
|
||||
github.com/ugorji/go/codec v0.0.0-20181022190402-e5e69e061d4f/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0=
|
||||
github.com/ugorji/go/codec v1.1.5-pre/go.mod h1:tULtS6Gy1AE1yCENaw4Vb//HLH5njI2tfCQDUqRd8fI=
|
||||
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
|
||||
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
|
||||
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
|
||||
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
|
||||
github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY=
|
||||
github.com/ugorji/go/codec v1.2.11 h1:BMaWp1Bb6fHwEtbplGBGJ498wD+LKlNSl25MjdZY4dU=
|
||||
github.com/ugorji/go/codec v1.2.11/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg=
|
||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
github.com/urfave/cli/v2 v2.3.0 h1:qph92Y649prgesehzOrQjdWyxFOp/QVM+6imKHad91M=
|
||||
github.com/urfave/cli/v2 v2.3.0/go.mod h1:LJmUH05zAU44vOAcrfzZQKsZbVcdbOG8rtL3/XcUArI=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible h1:IIqxTM5Jr7RzhigcL6FkrCNfXkvbR+Nbu1ls48pXYcw=
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible/go.mod h1:Rsyu10ZhbEK9pXdk8V6MVnZmTzRG0alMNLMwa0J01fE=
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0 h1:nib6RaJ4qVh5HD9UE9QJqnUZyWp3upv+Z6CFxaMj0V8=
|
||||
github.com/xhit/go-simple-mail/v2 v2.10.0/go.mod h1:kA1XbQfCI4JxQ9ccSN6VFyIEkkugOm7YiPkA5hKiQn4=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
github.com/xhit/go-simple-mail/v2 v2.13.0 h1:OANWU9jHZrVfBkNkvLf8Ww0fexwpQVF/v/5f96fFTLI=
|
||||
github.com/xhit/go-simple-mail/v2 v2.13.0/go.mod h1:b7P5ygho6SYE+VIqpxA6QkYfv4teeyG4MKqB3utRu98=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
|
||||
go.opentelemetry.io/otel v1.9.0/go.mod h1:np4EoPGzoPs3O67xUVNoPPcmSvsfOxNlNA4F4AC+0Eo=
|
||||
go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
|
||||
go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
|
||||
go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
|
||||
go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
|
||||
go.opentelemetry.io/otel/trace v1.9.0/go.mod h1:2737Q0MuG8q1uILYm2YYVkAyLtOofiTNGg6VODnOiPo=
|
||||
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
|
||||
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
|
||||
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
|
||||
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
|
||||
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
|
||||
go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
|
||||
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
|
||||
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI=
|
||||
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
|
||||
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
|
||||
golang.org/x/arch v0.0.0-20210923205945-b76863e36670/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/arch v0.3.0 h1:02VY4/ZcO/gBOH6PUaoiptASxtXU10jazRCP865E97k=
|
||||
golang.org/x/arch v0.3.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20190611184440-5c40567a22f8/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200115085410-6d4e4cb37c7d/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce h1:Roh6XWxHFKrPgC/EQhVubSAGQ6Ozk6IdxHSzt1mR0EI=
|
||||
golang.org/x/crypto v0.0.0-20220112180741-5e0467b6c7ce/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g=
|
||||
golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 h1:k/i9J1pBpvlfR+9QsetwPyERsqu1GIbi967PQMq3Ivc=
|
||||
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1/go.mod h1:V1LtkGg67GoY2N1AnLN78QLrzxkLyJw7RJb1gzOOz9w=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
|
||||
golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
|
||||
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.5.1 h1:OJxoQ/rynoF0dcCdI7cLPktw/hR2cueqYfjm43oqK38=
|
||||
golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk=
|
||||
golang.org/x/net v0.0.0-20181005035420-146acd28ed58/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -318,22 +347,18 @@ golang.org/x/net v0.0.0-20190611141213-3f473d35a33a/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211020060615-d418f374d309/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba h1:6u6sik+bn/y7vILcYkK3iwTBWN7WtBvB0+SZswQnbf8=
|
||||
golang.org/x/net v0.0.0-20220121210141-e204ce36a2ba/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
|
||||
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
|
||||
golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
|
||||
golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
|
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20181228144115-9a3f9b0469bb/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -342,73 +367,76 @@ golang.org/x/sys v0.0.0-20190610200419-93c9922d18ae/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190616124812-15dcb6c0061f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 h1:XfKQ4OlFl8okEOr5UvAqFRVj8pY/4yfcXrddB8qAbU0=
|
||||
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
|
||||
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
|
||||
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
|
||||
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
|
||||
golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
|
||||
golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190606050223-4d9ae51c2468/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190611222205-d73e1c7e250b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20190614205625-5aca471b1d59/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc=
|
||||
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo=
|
||||
golang.org/x/tools v0.1.8 h1:P1HhGGuLW4aAclzjtmJdf0mJOjVUZUzOTqkAkWL+l6w=
|
||||
golang.org/x/tools v0.1.8/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
|
||||
golang.org/x/tools v0.9.3 h1:Gn1I8+64MsuTb/HpH+LmQtNas23LhUVr3rYZ0eKuaMM=
|
||||
golang.org/x/tools v0.9.3/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
|
||||
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
|
||||
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ=
|
||||
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
|
||||
google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng=
|
||||
google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I=
|
||||
gopkg.in/Knetic/govaluate.v3 v3.0.0/go.mod h1:csKLBORsPbafmSCGTEh3U7Ozmsuq8ZSIlKk1bcqph0E=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/ini.v1 v1.66.2 h1:XfR1dOYubytKy4Shzc2LHrrGhU0lDCfDGG1yLPmpgsI=
|
||||
gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
|
||||
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/maulogger/v2 v2.3.1 h1:fwBYJne0pHvJrrIPHK+TAPfyxxbBEz46oVGez2x0ODE=
|
||||
maunium.net/go/maulogger/v2 v2.3.1/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/mautrix v0.10.7 h1:QV5vbCY4g50N7r1ihdG6zEPfaPn/EVYjM5H+qfLy4RM=
|
||||
maunium.net/go/mautrix v0.10.7/go.mod h1:k4Ng5oci83MEbqPL6KOjPdbU7f8v01KlMjR/zTQ+7mA=
|
||||
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
|
||||
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/maulogger/v2 v2.4.1 h1:N7zSdd0mZkB2m2JtFUsiGTQQAdP0YeFWT7YMc80yAL8=
|
||||
maunium.net/go/maulogger/v2 v2.4.1/go.mod h1:omPuYwYBILeVQobz8uO3XC8DIRuEb5rXYlQSuqrbCho=
|
||||
maunium.net/go/mautrix v0.15.2 h1:fUiVajeoOR92uJoSShHbCvh7uG6lDY4ZO4Mvt90LbjU=
|
||||
maunium.net/go/mautrix v0.15.2/go.mod h1:h4NwfKqE4YxGTLSgn/gawKzXAb2sF4qx8agL6QEFtGg=
|
||||
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
|
||||
|
||||
@@ -63,8 +63,8 @@
|
||||
</a>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button input ~neutral field mb-2 lang-link">Ko-fi</a>
|
||||
<a href="https://github.com/sponsors/hrfee" target="_blank" class="button ~neutral mb-2 w-100 lang-link">GitHub</a>
|
||||
<a href="https://ko-fi.com/hrfee" target="_blank" class="button ~neutral mb-2 w-100 lang-link">Ko-fi</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -579,58 +579,71 @@
|
||||
</div>
|
||||
</div>
|
||||
<div id="tab-accounts" class="unfocused">
|
||||
<div class="card @low dark:~d_neutral accounts mb-4">
|
||||
<div class="flex-expand row">
|
||||
<div class="row">
|
||||
<span class="text-3xl font-bold mr-2 col">{{ .strings.accounts }}</span>
|
||||
<input type="search" class="col sm field ~neutral @low input search ml-2 mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col sm button ~neutral @low center mb-2" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col sm dropdown pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~info @low center mb-2" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
</div>
|
||||
<div class="card @low dark:~d_neutral accounts mb-4 overflow-visible">
|
||||
<div class="flex-expand align-middle">
|
||||
<span class="text-3xl font-bold mr-4">{{ .strings.accounts }}</span>
|
||||
<div id="accounts-filter-dropdown" class="dropdown z-10" tabindex="0">
|
||||
<span class="h-100 button ~neutral @low center" id="accounts-filter-button">{{ .strings.filters }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low mt-2" id="accounts-filter-list">
|
||||
<p class="supra pb-2">{{ .strings.filters }}</p>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~urge @low center mb-2" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col sm button ~warning @low center mb-2" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col sm dropdown manual pb-0i" tabindex="0">
|
||||
<span class="h-100 sm button ~positive @low center mb-2" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="button ~urge sm full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col sm button ~info @low center mb-2 unfocused" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col sm button ~critical @low center mb-2" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
</div>
|
||||
<input type="search" class="field ~neutral @low input search ml-2 mr-2" id="accounts-search" placeholder="{{ .strings.search }}">
|
||||
<span class="button ~neutral @low center -ml-8" id="accounts-search-clear" aria-label="{{ .strings.clearSearch }}" text="{{ .strings.clearSearch }}"><i class="ri-close-line"></i></span>
|
||||
</div>
|
||||
<div class="card @low accounts-header table-responsive mt-8">
|
||||
<div class="supra py-1 sm hidden" id="accounts-search-options-header">{{ .strings.searchOptions }}</div>
|
||||
<div class="row -mx-2">
|
||||
<button type="button" class="button ~neutral @low center m-2 hidden"><span id="accounts-sort-by-field"></span> <i class="ri-close-line ml-2 text-2xl"></i></button>
|
||||
<span id="accounts-filter-area"></span>
|
||||
</div>
|
||||
<div class="supra py-1 sm">{{ .strings.actions }}</div>
|
||||
<div class="row -mx-2">
|
||||
<span class="col button ~neutral @low center max-w-[20%]" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col dropdown pb-0i max-w-[20%]" tabindex="0">
|
||||
<span class="w-100 button ~info @low center" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="supra sm">{{ .strings.templates }}</span>
|
||||
<div id="accounts-announce-templates"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col button ~urge @low center max-w-[20%]" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col button ~warning @low center max-w-[20%]" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<div id="accounts-disable-enable-dropdown" class="col dropdown manual pb-0i max-w-[20%]" tabindex="0">
|
||||
<span class="w-100 button ~positive @low center" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
<div class="dropdown-display">
|
||||
<div class="card ~neutral @low">
|
||||
<span class="button ~urge full-width accounts-announce-template-button" id="accounts-enable-expiry">{{ .strings.setExpiry }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<span class="col button ~info @low center unfocused max-w-[20%]" id="accounts-send-pwr">{{ .strings.sendPWR }}</span>
|
||||
<span class="col button ~critical @low center max-w-[20%]" id="accounts-delete-user">{{ .quantityStrings.deleteUser.Singular }}</span>
|
||||
</div>
|
||||
<div class="card @low accounts-header table-responsive mt-2">
|
||||
<table class="table text-base leading-4">
|
||||
<thead>
|
||||
<tr>
|
||||
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
||||
<th class="table-inline my-2">{{ .strings.username }}</th>
|
||||
<th class="table-inline my-2 grid gap-4 place-items-stretch accounts-header-username">{{ .strings.username }}</th>
|
||||
{{ if .jellyfinLogin }}
|
||||
<th class="text-center-i">{{ .strings.accessJFA }}</th>
|
||||
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-access-jfa">{{ .strings.accessJFA }}</th>
|
||||
{{ end }}
|
||||
<th>{{ .strings.emailAddress }}</th>
|
||||
<th class="grid gap-4 place-items-stretch accounts-header-email">{{ .strings.emailAddress }}</th>
|
||||
{{ if .telegramEnabled }}
|
||||
<th class="text-center-i">Telegram</th>
|
||||
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-telegram">Telegram</th>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<th class="text-center-i">Matrix</th>
|
||||
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-matrix">Matrix</th>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<th class="text-center-i">Discord</th>
|
||||
<th class="text-center-i grid gap-4 place-items-stretch accounts-header-discord">Discord</th>
|
||||
{{ end }}
|
||||
<th>{{ .strings.expiry }}</th>
|
||||
<th>{{ .strings.lastActiveTime }}</th>
|
||||
<th class="grid gap-4 place-items-stretch accounts-header-expiry">{{ .strings.expiry }}</th>
|
||||
<th class="grid gap-4 place-items-stretch accounts-header-last-active">{{ .strings.lastActiveTime }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody id="accounts-list"></tbody>
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
{{ else }}
|
||||
<title>{{ .strings.pageTitle }}</title>
|
||||
{{ end }}
|
||||
<script>
|
||||
window.redirectToJellyfin = {{ .redirectToJellyfin }};
|
||||
</script>
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="modal-success" class="modal">
|
||||
|
||||
@@ -137,7 +137,7 @@
|
||||
<input type="radio" class="mr-2" name="ui-jellyfin_login" value="true" checked><span>{{ .lang.Login.authorizeWithJellyfin }}</span>
|
||||
</label>
|
||||
<label class="row switch pl-4 pb-4">
|
||||
<input type="checkbox" class="mr-2" id="ui-admin_only"><span>{{ .lang.Login.adminOnly }}</span>
|
||||
<input type="checkbox" class="mr-2" id="ui-admin_only" checked><span>{{ .lang.Login.adminOnly }}</span>
|
||||
</label>
|
||||
<label class="row switch pl-4 pb-2">
|
||||
<input type="checkbox" class="mr-2" id="ui-allow_all"><span>{{ .lang.Login.allowAll }}</span>
|
||||
|
||||
50
invdaemon.go
50
invdaemon.go
@@ -1,50 +0,0 @@
|
||||
package main
|
||||
|
||||
import "time"
|
||||
|
||||
// https://bbengfort.github.io/snippets/2016/06/26/background-work-goroutines-timer.html THANKS
|
||||
|
||||
type inviteDaemon struct {
|
||||
Stopped bool
|
||||
ShutdownChannel chan string
|
||||
Interval time.Duration
|
||||
period time.Duration
|
||||
app *appContext
|
||||
}
|
||||
|
||||
func newInviteDaemon(interval time.Duration, app *appContext) *inviteDaemon {
|
||||
return &inviteDaemon{
|
||||
Stopped: false,
|
||||
ShutdownChannel: make(chan string),
|
||||
Interval: interval,
|
||||
period: interval,
|
||||
app: app,
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *inviteDaemon) run() {
|
||||
rt.app.info.Println("Invite daemon started")
|
||||
for {
|
||||
select {
|
||||
case <-rt.ShutdownChannel:
|
||||
rt.ShutdownChannel <- "Down"
|
||||
return
|
||||
case <-time.After(rt.period):
|
||||
break
|
||||
}
|
||||
started := time.Now()
|
||||
rt.app.storage.loadInvites()
|
||||
rt.app.debug.Println("Daemon: Checking invites")
|
||||
rt.app.checkInvites()
|
||||
finished := time.Now()
|
||||
duration := finished.Sub(started)
|
||||
rt.period = rt.Interval - duration
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *inviteDaemon) Shutdown() {
|
||||
rt.Stopped = true
|
||||
rt.ShutdownChannel <- "Down"
|
||||
<-rt.ShutdownChannel
|
||||
close(rt.ShutdownChannel)
|
||||
}
|
||||
@@ -112,7 +112,9 @@
|
||||
"sendPWRManual": "Brugeren {n} har ingen kontaktinformation, tryk kopier for at få et link du kan sende til dem.",
|
||||
"sendPWRSuccess": "Link til nulstilling af adgangskode sendt.",
|
||||
"sendPWRSuccessManual": "Hvis brugeren ikke er modtaget den, så tryk på kopier for manuelt at sende et link til dem.",
|
||||
"sendPWRValidFor": "Dette link er gyldigt i 30m."
|
||||
"sendPWRValidFor": "Dette link er gyldigt i 30m.",
|
||||
"accessJFA": "Få adgang til jfa-go",
|
||||
"accessJFASettings": "Kan ikke ændres, da enten \"Kun administrator\" eller \"Tillad alle\" er blevet indstillet i Indstillinger > Generelt."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Ændret e-mail adresse på {n}.",
|
||||
@@ -209,6 +211,10 @@
|
||||
"extendedExpiry": {
|
||||
"singular": "Forlængede udløb for {n} bruger.",
|
||||
"plural": "Forlængede udløb for {n} brugere."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Indstil udløb for {n} bruger",
|
||||
"plural": "Indstil udløb for {n} brugere"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
"settingsRequiredOrRestartMessage": "Hinweis: {n} zeigt ein erforderliches Feld an, {n} zeigt an, dass Änderungen einen Neustart erfordern.",
|
||||
"settingsSave": "Speichern",
|
||||
"ombiUserDefaults": "Ombi-Benutzerstandardeinstellungen",
|
||||
"ombiUserDefaultsDescription": "Erstelle einen Ombi-Benutzer und konfiguriere ihn, dann wähle ihn unten aus. Seine Einstellungen/Berechtigungen werden gespeichert und auf neue Ombi-Benutzer, erstellt von jfa-go, angewendet",
|
||||
"ombiUserDefaultsDescription": "Erstelle einen Ombi-Benutzer, konfiguriere ihn und wähle ihn dann unten aus. Seine Einstellungen/Berechtigungen werden gespeichert und auf neue Ombi-Benutzer, welche von jfa-go erstellt werden, angewendet, sofern dieses Profil ausgewählt ist.",
|
||||
"userProfiles": "Benutzerprofile",
|
||||
"userProfilesDescription": "Profile werden auf Benutzer angewendet, wenn sie ein Konto erstellen. Ein Profil beinhaltet Bibliothekszugriffsrechte und das Startbildschirmlayout.",
|
||||
"userProfilesIsDefault": "Standard",
|
||||
@@ -69,7 +69,7 @@
|
||||
"preview": "Vorschau",
|
||||
"reset": "Zurücksetzen",
|
||||
"edit": "Bearbeiten",
|
||||
"customizeMessages": "E-Mails anpassen",
|
||||
"customizeMessages": "Benachrichtigungen anpassen",
|
||||
"customizeMessagesDescription": "Wenn du jfa-go's E-Mail-Vorlagen nicht benutzen willst, kannst du deinen eigenen unter Verwendung von Markdown erstellen.",
|
||||
"announce": "Ankündigen",
|
||||
"subject": "Betreff",
|
||||
@@ -101,7 +101,20 @@
|
||||
"findDiscordUser": "Suche Discord-Benutzer",
|
||||
"linkMatrixDescription": "Gib den Benutzernamen und das Passwort des Benutzers ein, der als Bot verwendet werden soll. Nach dem Absenden wird die App neu gestartet.",
|
||||
"matrixHomeServer": "Adresse des Homeservers",
|
||||
"templates": "Vorlagen"
|
||||
"templates": "Vorlagen",
|
||||
"ombiProfile": "Ombi-Benutzerprofil",
|
||||
"accessJFA": "jfa-go Zugriff",
|
||||
"sendPWRValidFor": "Der Link ist 30m gültig.",
|
||||
"logs": "Logdaten",
|
||||
"setExpiry": "Ablauf setzen",
|
||||
"sendPWRSuccess": "Link zur Passwortrücksetzung versandt.",
|
||||
"sendPWRSuccessManual": "Falls der Benutzer ihn nicht erhalten hat, klicke \"Kopieren\" und sende ihm den Link manuell.",
|
||||
"sendPWR": "Sende Passwortrücksetzung",
|
||||
"sendPWRManual": "Benutzer {n} hat keine Kontaktmöglichkeit hinterlegt. Klicke \"Kopieren\" um einen Link zu erhalten, den du dem Benutzer manuell senden kannst.",
|
||||
"accessJFASettings": "Kann nicht geändert werden, da entweder \"Nur Admin-Benutzer\" oder \"Erlaube allen Jellyfin-Nutzern sich anzumelden\" in Einstellungen > Allgemein aktiviert ist.",
|
||||
"saveAsTemplate": "Als Vorlage speichern",
|
||||
"deleteTemplate": "Vorlage löschen",
|
||||
"templateEnterName": "Gebe einen Namen ein, um diese Vorlage zu speichern."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "E-Mail-Adresse von {n} geändert.",
|
||||
@@ -142,7 +155,9 @@
|
||||
"updateAppliedRefresh": "Update angewendet, bitte aktualisieren.",
|
||||
"telegramVerified": "Telegram-Konto verifiziert.",
|
||||
"accountConnected": "Konto verbunden.",
|
||||
"savedAnnouncement": "Ankündigung gespeichert."
|
||||
"savedAnnouncement": "Ankündigung gespeichert.",
|
||||
"errorSetOmbiProfile": "Ombi-Profil konnte nicht gespeichert werden.",
|
||||
"setOmbiProfile": "Ombi-Profil gespeichert."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@@ -196,6 +211,10 @@
|
||||
"reEnableUsers": {
|
||||
"singular": "Benutzer {n} wieder aktivieren",
|
||||
"plural": "Benutzer {n} wieder aktivieren"
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Ablauf für {n} Benutzer setzen",
|
||||
"plural": "Ablauf für {n} Benutzer setzen"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,217 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"quantityStrings": {
|
||||
"deleteUser": {
|
||||
"singular": "Delete User",
|
||||
"plural": "Delete Users"
|
||||
},
|
||||
"deletedUser": {
|
||||
"singular": "Deleted {n} user.",
|
||||
"plural": "Deleted {n} users."
|
||||
},
|
||||
"disabledUser": {
|
||||
"plural": "Disabled {n} users.",
|
||||
"singular": "Disabled {n} user."
|
||||
},
|
||||
"extendExpiry": {
|
||||
"singular": "Extend expiry for {n} user",
|
||||
"plural": "Extend expiry for {n} users"
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"plural": "Extended expiry for {n} users.",
|
||||
"singular": "Extended expiry for {n} user."
|
||||
},
|
||||
"addUser": {
|
||||
"singular": "Add user",
|
||||
"plural": "Add users"
|
||||
},
|
||||
"modifySettingsFor": {
|
||||
"singular": "Modify Settings for {n} user",
|
||||
"plural": "Modify Settings for {n} users"
|
||||
},
|
||||
"deleteNUsers": {
|
||||
"plural": "Delete {n} users",
|
||||
"singular": "Delete {n} user"
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "Disable {n} user",
|
||||
"plural": "Disable {n} users"
|
||||
},
|
||||
"enabledUser": {
|
||||
"singular": "Enabled {n} user.",
|
||||
"plural": "Enabled {n} users."
|
||||
},
|
||||
"announceTo": {
|
||||
"singular": "Announce to {n} user",
|
||||
"plural": "Announce to {n} users"
|
||||
},
|
||||
"appliedSettings": {
|
||||
"singular": "Applied settings to {n} user.",
|
||||
"plural": "Applied settings to {n} users."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Set expiry for {n} user",
|
||||
"plural": "Set expiry for {n} users"
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "Re-enable {n} user",
|
||||
"plural": "Re-enable {n} users"
|
||||
}
|
||||
},
|
||||
"strings": {
|
||||
"invites": "Invites",
|
||||
"accounts": "Accounts",
|
||||
"settings": "Settings",
|
||||
"inviteDays": "Days",
|
||||
"inviteHours": "Hours",
|
||||
"inviteInfiniteUsesWarning": "invites with infinite uses can be used abusively",
|
||||
"inviteSendToEmail": "Send to",
|
||||
"login": "Login",
|
||||
"logout": "Logout",
|
||||
"apply": "Apply",
|
||||
"delete": "Delete",
|
||||
"updates": "Updates",
|
||||
"expiry": "Expiry",
|
||||
"variables": "Variables",
|
||||
"preview": "Preview",
|
||||
"markdownSupported": "Markdown is supported.",
|
||||
"applyHomescreenLayout": "Apply homescreen layout",
|
||||
"ombiProfile": "Ombi user profile",
|
||||
"settingsApplyRestartNow": "Apply & restart",
|
||||
"settingsApplied": "Settings applied.",
|
||||
"userProfiles": "User Profiles",
|
||||
"addProfile": "Add Profile",
|
||||
"userProfilesLibraries": "Libraries",
|
||||
"addProfileNameOf": "Profile Name",
|
||||
"inviteDateCreated": "Created",
|
||||
"settingsRestart": "Restart",
|
||||
"inviteMinutes": "Minutes",
|
||||
"inviteNumberOfUses": "Number of uses",
|
||||
"warning": "Warning",
|
||||
"create": "Create",
|
||||
"name": "Name",
|
||||
"conditionals": "Conditionals",
|
||||
"contactThrough": "Contact through:",
|
||||
"select": "Select",
|
||||
"date": "Date",
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"disable": "Disable",
|
||||
"edit": "Edit",
|
||||
"extendExpiry": "Extend expiry",
|
||||
"sendPWR": "Send Password Reset",
|
||||
"inviteMonths": "Months",
|
||||
"inviteDuration": "Invite Duration",
|
||||
"add": "Add",
|
||||
"reEnable": "Re-enable",
|
||||
"update": "Update",
|
||||
"user": "User",
|
||||
"userExpiryDescription": "A specified amount of time after each signup, jfa-go will delete/disable the account. You can change this behaviour in settings.",
|
||||
"templates": "Templates",
|
||||
"accessJFA": "Access jfa-go",
|
||||
"message": "Message",
|
||||
"reset": "Reset",
|
||||
"donate": "Donate",
|
||||
"sendPWRSuccessManual": "If the user hasn't received it, press copy to get a link to manually send to them.",
|
||||
"modifySettingsDescription": "Apply settings from an existing profile, or source them directly from a user.",
|
||||
"logs": "Logs",
|
||||
"sendPWRManual": "User {n} has no method of contact, press copy to get a link to send to them.",
|
||||
"sendPWRSuccess": "Password reset link sent.",
|
||||
"customizeMessages": "Customise Messages",
|
||||
"customizeMessagesDescription": "If you don't want to use jfa-go's message templates, you can create your own using Markdown.",
|
||||
"modifySettings": "Modify Settings",
|
||||
"sendDeleteNotificationEmail": "Send notification message",
|
||||
"sendDeleteNotifiationExample": "Your account has been deleted.",
|
||||
"settingsRestarting": "Restarting…",
|
||||
"settingsRestartRequired": "Restart needed",
|
||||
"settingsRefreshPage": "Refresh the page in a few seconds.",
|
||||
"settingsRequiredOrRestartMessage": "Note: {n} indicates a required field, {n} indicates changes require a restart.",
|
||||
"settingsSave": "Save",
|
||||
"userProfilesDescription": "Profiles are applied to users when they create an account. A profile include library access rights and homescreen layout.",
|
||||
"addProfileDescription": "Create a Jellyfin user and configure it, then select it below. When this profile is applied to an invite, new users will be created with the settings.",
|
||||
"addProfileStoreHomescreenLayout": "Store homescreen layout",
|
||||
"inviteNoUsersCreated": "None yet!",
|
||||
"inviteUsersCreated": "Created users",
|
||||
"inviteRemainingUses": "Remaining uses",
|
||||
"inviteNoInvites": "None",
|
||||
"inviteExpiresInTime": "Expires in {n}",
|
||||
"notifyEvent": "Notify on:",
|
||||
"notifyInviteExpiry": "On expiry",
|
||||
"notifyUserCreation": "On user creation",
|
||||
"sendPIN": "Ask the user to send the PIN below to the bot.",
|
||||
"findDiscordUser": "Find Discord user",
|
||||
"linkMatrixDescription": "Enter the username and password of the user to use as a bot. Once submitted, the app will restart.",
|
||||
"matrixHomeServer": "Home server address",
|
||||
"saveAsTemplate": "Save as template",
|
||||
"deleteTemplate": "Delete template",
|
||||
"settingsRestartRequiredDescription": "A restart is necessary to apply some settings you changed. Restart now or later?",
|
||||
"settingsApplyRestartLater": "Apply, restart later",
|
||||
"subject": "Subject",
|
||||
"setExpiry": "Set expiry",
|
||||
"admin": "Admin",
|
||||
"download": "Download",
|
||||
"search": "Search",
|
||||
"advancedSettings": "Advanced Settings",
|
||||
"lastActiveTime": "Last Active",
|
||||
"from": "From",
|
||||
"userExpiry": "User Expiry",
|
||||
"aboutProgram": "About",
|
||||
"version": "Version",
|
||||
"commitNoun": "Commit",
|
||||
"newUser": "New User",
|
||||
"profile": "Profile",
|
||||
"unknown": "Unknown",
|
||||
"label": "Label",
|
||||
"announce": "Announce",
|
||||
"sendPWRValidFor": "The link is valid for 30m.",
|
||||
"ombiUserDefaultsDescription": "Create an Ombi user and configure it, then select it below. It's settings/permissions will be stored and applied to new Ombi users created by jfa-go when this profile is selected.",
|
||||
"userProfilesIsDefault": "Default",
|
||||
"inviteNoProfile": "No Profile",
|
||||
"searchDiscordUser": "Start typing the Discord username to find the user.",
|
||||
"templateEnterName": "Enter a name to save this template.",
|
||||
"accessJFASettings": "Cannot be changed as either \"Admin Only\" or \"Allow All\" has been set in Settings > General."
|
||||
},
|
||||
"notifications": {
|
||||
"errorSettingsFailed": "Application failed.",
|
||||
"errorLoginBlank": "The username and/or password was left blank.",
|
||||
"errorLoadSettings": "Failed to load settings.",
|
||||
"errorUnknown": "Unknown error.",
|
||||
"errorDeleteProfile": "Failed to delete profile {n}",
|
||||
"sentAnnouncement": "Announcement sent.",
|
||||
"savedAnnouncement": "Announcement saved.",
|
||||
"setOmbiProfile": "Stored ombi profile.",
|
||||
"updateApplied": "Update applied, please restart.",
|
||||
"updateAppliedRefresh": "Update applied, please refresh.",
|
||||
"telegramVerified": "Telegram account verified.",
|
||||
"accountConnected": "Account connected.",
|
||||
"error401Unauthorized": "Unauthorised. Try refreshing the page.",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
||||
"errorSaveEmail": "Failed to save email.",
|
||||
"errorLoadProfiles": "Failed to load profiles.",
|
||||
"errorCreateProfile": "Failed to create profile {n}",
|
||||
"errorLoadUsers": "Failed to load users.",
|
||||
"errorSaveSettings": "Couldn't save settings.",
|
||||
"errorSetOmbiProfile": "Failed to store ombi profile.",
|
||||
"errorLoadOmbiUsers": "Failed to load ombi users.",
|
||||
"errorFailureCheckLogs": "Failed (check console/logs)",
|
||||
"errorPartialFailureCheckLogs": "Partial failure (check console/logs)",
|
||||
"errorUserCreated": "Failed to create user {n}.",
|
||||
"errorSendWelcomeEmail": "Failed to send welcome message (check console/logs)",
|
||||
"errorApplyUpdate": "Failed to apply update, try manually.",
|
||||
"errorCheckUpdate": "Failed to check for update.",
|
||||
"noUpdatesAvailable": "No new updates available.",
|
||||
"changedEmailAddress": "Changed email address of {n}.",
|
||||
"userCreated": "User {n} created.",
|
||||
"saveEmail": "Email saved.",
|
||||
"createProfile": "Created profile {n}.",
|
||||
"saveSettings": "Settings were saved",
|
||||
"errorConnection": "Couldn't connect to jfa-go.",
|
||||
"errorHomescreenAppliedNoSettings": "Homescreen layout was applied, but applying settings may have failed.",
|
||||
"errorBlankFields": "Fields were left blank",
|
||||
"errorSetDefaultProfile": "Failed to set default profile.",
|
||||
"errorChangedEmailAddress": "Couldn't change email address of {n}.",
|
||||
"updateAvailable": "A new update is available, check settings."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@
|
||||
"advancedSettings": "Advanced Settings",
|
||||
"lastActiveTime": "Last Active",
|
||||
"from": "From",
|
||||
"after": "After",
|
||||
"before": "Before",
|
||||
"user": "User",
|
||||
"expiry": "Expiry",
|
||||
"userExpiry": "User Expiry",
|
||||
@@ -59,6 +61,7 @@
|
||||
"reset": "Reset",
|
||||
"edit": "Edit",
|
||||
"donate": "Donate",
|
||||
"unlink": "Unlink Account",
|
||||
"sendPWR": "Send Password Reset",
|
||||
"contactThrough": "Contact through:",
|
||||
"extendExpiry": "Extend expiry",
|
||||
@@ -113,7 +116,15 @@
|
||||
"deleteTemplate": "Delete template",
|
||||
"templateEnterName": "Enter a name to save this template.",
|
||||
"accessJFA": "Access jfa-go",
|
||||
"accessJFASettings": "Cannot be changed as this either \"Admin Only\" or \"Allow All\" has been set in Settings > General."
|
||||
"accessJFASettings": "Cannot be changed as either \"Admin Only\" or \"Allow All\" has been set in Settings > General.",
|
||||
"sortingBy": "Sorting By",
|
||||
"filters": "Filters",
|
||||
"clickToRemoveFilter": "Click to remove this filter.",
|
||||
"clearSearch": "Clear search",
|
||||
"actions": "Actions",
|
||||
"searchOptions": "Search Options",
|
||||
"matchText": "Match Text",
|
||||
"jellyfinID": "Jellyfin ID"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Changed email address of {n}.",
|
||||
|
||||
@@ -111,7 +111,10 @@
|
||||
"sendPWRSuccessManual": "Si el usuario no lo ha recibido, presione copiar para generar el enlace y enviárselo manualmente.",
|
||||
"sendPWRValidFor": "El enlace es válido por 30m.",
|
||||
"sendPWRManual": "El usuario {n} no tiene ningún método de contacto, presione copiar para generar el enlace para enviarle.",
|
||||
"ombiProfile": "Perfil de usuario de Ombi"
|
||||
"ombiProfile": "Perfil de usuario de Ombi",
|
||||
"logs": "Registros",
|
||||
"accessJFA": "Acceso",
|
||||
"accessJFASettings": "No se puede cambia, ya que se ha establecido \"Solo administradores\" o \"Permitir a todos\" en Configuración > General."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Se cambió la dirección de correo electrónico de {n}.",
|
||||
@@ -208,6 +211,10 @@
|
||||
"extendedExpiry": {
|
||||
"singular": "Caducidad extendida para {n} usuario.",
|
||||
"plural": "Caducidad extendida para {n} usuarios."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Fijar la caducidad del usuario {n}",
|
||||
"plural": "Establecer la caducidad para {n} usuarios"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
"addProfileNameOf": "Nom de profil",
|
||||
"addProfileStoreHomescreenLayout": "Enregistrer la disposition de l'écran d'accueil",
|
||||
"inviteNoUsersCreated": "Aucun pour l'instant !",
|
||||
"inviteUsersCreated": "Utilisateurs créer",
|
||||
"inviteUsersCreated": "Utilisateurs créés",
|
||||
"inviteNoProfile": "Aucun profil",
|
||||
"inviteDateCreated": "Créer",
|
||||
"inviteRemainingUses": "Utilisations restantes",
|
||||
@@ -64,7 +64,7 @@
|
||||
"notifyEvent": "Notifier sur :",
|
||||
"notifyInviteExpiry": "À l'expiration",
|
||||
"notifyUserCreation": "à la création de l'utilisateur",
|
||||
"label": "Etiquette",
|
||||
"label": "Nom",
|
||||
"settingsRestarting": "Redémarrage…",
|
||||
"settingsRestart": "Redémarrer",
|
||||
"announce": "Annoncer",
|
||||
@@ -112,7 +112,10 @@
|
||||
"sendPWRValidFor": "Ce lien est valable 30min.",
|
||||
"sendPWRManual": "L'utilisateur {n} n'a pas indiqué de méthode de contact, appuyez sur copier pour recevoir un lien à lui envoyer.",
|
||||
"sendPWRSuccessManual": "Si l'utilisateur ne l'a pas reçu, appuyez sur copier pour recevoir un lien à lui envoyer manuellement.",
|
||||
"ombiProfile": "Profil d'utilisateur Ombi"
|
||||
"ombiProfile": "Profil d'utilisateur Ombi",
|
||||
"logs": "Logs",
|
||||
"accessJFA": "Accès à jfa-go",
|
||||
"accessJFASettings": "Ne peut pas être changé car \"Admin Only\" ou \"Allow All\" a été défini dans Paramètres > Général."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Adresse e-mail modifiée de {n}.",
|
||||
@@ -209,6 +212,10 @@
|
||||
"disabledUser": {
|
||||
"singular": "{n} utilisateur désactivé.",
|
||||
"plural": "{n} utilisateurs désactivés."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Définir l'expiration pour {n} utilisateur",
|
||||
"plural": "Définir l'expiration pour {n} utilisateurs"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,63 +3,63 @@
|
||||
"name": "Magyar (HU)"
|
||||
},
|
||||
"strings": {
|
||||
"invites": "",
|
||||
"accounts": "",
|
||||
"settings": "",
|
||||
"inviteMonths": "",
|
||||
"inviteDays": "",
|
||||
"inviteHours": "",
|
||||
"inviteMinutes": "",
|
||||
"inviteNumberOfUses": "",
|
||||
"inviteDuration": "",
|
||||
"warning": "",
|
||||
"inviteInfiniteUsesWarning": "",
|
||||
"inviteSendToEmail": "",
|
||||
"login": "",
|
||||
"logout": "",
|
||||
"create": "",
|
||||
"apply": "",
|
||||
"delete": "",
|
||||
"add": "",
|
||||
"select": "",
|
||||
"name": "",
|
||||
"date": "",
|
||||
"enabled": "",
|
||||
"disabled": "",
|
||||
"reEnable": "",
|
||||
"setExpiry": "",
|
||||
"disable": "",
|
||||
"admin": "",
|
||||
"updates": "",
|
||||
"update": "",
|
||||
"download": "",
|
||||
"search": "",
|
||||
"advancedSettings": "",
|
||||
"lastActiveTime": "",
|
||||
"from": "",
|
||||
"user": "",
|
||||
"expiry": "",
|
||||
"userExpiry": "",
|
||||
"userExpiryDescription": "",
|
||||
"aboutProgram": "",
|
||||
"version": "",
|
||||
"commitNoun": "",
|
||||
"newUser": "",
|
||||
"profile": "",
|
||||
"unknown": "",
|
||||
"label": "",
|
||||
"logs": "",
|
||||
"announce": "",
|
||||
"templates": "",
|
||||
"subject": "",
|
||||
"message": "",
|
||||
"variables": "",
|
||||
"conditionals": "",
|
||||
"preview": "",
|
||||
"reset": "",
|
||||
"edit": "",
|
||||
"donate": "",
|
||||
"sendPWR": "",
|
||||
"invites": "Meghívások",
|
||||
"accounts": "Fiókok",
|
||||
"settings": "Beállítások",
|
||||
"inviteMonths": "Hónapok",
|
||||
"inviteDays": "Napok",
|
||||
"inviteHours": "Órák",
|
||||
"inviteMinutes": "Percek",
|
||||
"inviteNumberOfUses": "Felhasználások száma",
|
||||
"inviteDuration": "Meghívás időtartama",
|
||||
"warning": "Figyelmeztetés",
|
||||
"inviteInfiniteUsesWarning": "a végtelen felhasználású meghívókkal visszaélhetnek",
|
||||
"inviteSendToEmail": "Címzett",
|
||||
"login": "Belépés",
|
||||
"logout": "Kijelentkezés",
|
||||
"create": "Létrehozás",
|
||||
"apply": "Alkalmaz",
|
||||
"delete": "Törlés",
|
||||
"add": "Hozzáadás",
|
||||
"select": "Kiválasztás",
|
||||
"name": "Név",
|
||||
"date": "Dátum",
|
||||
"enabled": "Engedélyezve",
|
||||
"disabled": "Tiltva",
|
||||
"reEnable": "Újra engedélyezés",
|
||||
"setExpiry": "Lejárat beállítása",
|
||||
"disable": "Letiltás",
|
||||
"admin": "Adminisztrátor",
|
||||
"updates": "Frissítések",
|
||||
"update": "Frissítés",
|
||||
"download": "Letöltés",
|
||||
"search": "Keresés",
|
||||
"advancedSettings": "További beállítások",
|
||||
"lastActiveTime": "Utoljára aktív",
|
||||
"from": "Feladó",
|
||||
"user": "Felhasználó",
|
||||
"expiry": "Lejárat",
|
||||
"userExpiry": "Felhasználói lejárat",
|
||||
"userExpiryDescription": "Egy meghatározott idő után minden regisztrációt töröl, vagy felfüggeszt a jfa-go. Ezt a működést megváltoztathatod a beállításokban.",
|
||||
"aboutProgram": "Névjegy",
|
||||
"version": "Verzió",
|
||||
"commitNoun": "Elkövet",
|
||||
"newUser": "Új felhasználó",
|
||||
"profile": "Profil",
|
||||
"unknown": "Ismeretlen",
|
||||
"label": "Címke",
|
||||
"logs": "Naplók",
|
||||
"announce": "Bejelentés",
|
||||
"templates": "Sablonok",
|
||||
"subject": "Téma",
|
||||
"message": "Üzenet",
|
||||
"variables": "Változók",
|
||||
"conditionals": "Feltételek",
|
||||
"preview": "Előnézet",
|
||||
"reset": "Visszaállítás",
|
||||
"edit": "Szerkesztés",
|
||||
"donate": "Támogatás",
|
||||
"sendPWR": "Jelszó visszaállítás küldése",
|
||||
"contactThrough": "",
|
||||
"extendExpiry": "",
|
||||
"sendPWRManual": "",
|
||||
|
||||
@@ -112,7 +112,9 @@
|
||||
"sendPWRSuccess": "Wachtwoordreset-link verstuurd.",
|
||||
"sendPWRValidFor": "De link is 30m geldig.",
|
||||
"ombiProfile": "Ombi gebruikersprofiel",
|
||||
"logs": "Logs"
|
||||
"logs": "Logs",
|
||||
"accessJFA": "Toegang tot jfa-go",
|
||||
"accessJFASettings": "Kan niet worden aangepast, omdat \"Alleen beheerders\" of \"Laat alle Jellyfin-gebruikers inloggen\" is aangevinkt in Instellingen > Algemeen."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",
|
||||
@@ -209,6 +211,10 @@
|
||||
"enabledUser": {
|
||||
"singular": "{n} gebruiker ingeschakeld.",
|
||||
"plural": "{n} gebruikers ingeschakeld."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Stel verloop in voor {n} gebruiker",
|
||||
"plural": "Stel verloop in voor {n} gebruikers"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
217
lang/admin/pl-PL.json
Normal file
217
lang/admin/pl-PL.json
Normal file
@@ -0,0 +1,217 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"invites": "Zaproszenia",
|
||||
"accounts": "Konta",
|
||||
"settings": "Ustawienia",
|
||||
"inviteMonths": "Miesiące",
|
||||
"inviteDays": "Dni",
|
||||
"inviteHours": "Godziny",
|
||||
"inviteMinutes": "Minuty",
|
||||
"inviteNumberOfUses": "Liczba użyć",
|
||||
"inviteDuration": "Czas trwania zaproszenia",
|
||||
"warning": "Ostrzeżenie",
|
||||
"inviteInfiniteUsesWarning": "",
|
||||
"inviteSendToEmail": "",
|
||||
"login": "",
|
||||
"logout": "",
|
||||
"create": "",
|
||||
"apply": "",
|
||||
"delete": "",
|
||||
"add": "",
|
||||
"select": "",
|
||||
"name": "Imię",
|
||||
"date": "Data",
|
||||
"enabled": "Włączone",
|
||||
"disabled": "Wyłączone",
|
||||
"reEnable": "",
|
||||
"setExpiry": "",
|
||||
"disable": "Wyłączone",
|
||||
"admin": "Admin",
|
||||
"updates": "Aktualizacje",
|
||||
"update": "Aktualizacja",
|
||||
"download": "Pobierz",
|
||||
"search": "Szukaj",
|
||||
"advancedSettings": "Zaawansowane",
|
||||
"lastActiveTime": "Ostatnia aktywność",
|
||||
"from": "Od",
|
||||
"user": "Użytkownik",
|
||||
"expiry": "Wygasa",
|
||||
"userExpiry": "Użytkownik wygasa",
|
||||
"userExpiryDescription": "",
|
||||
"aboutProgram": "O",
|
||||
"version": "Wersja",
|
||||
"commitNoun": "",
|
||||
"newUser": "",
|
||||
"profile": "",
|
||||
"unknown": "",
|
||||
"label": "",
|
||||
"logs": "",
|
||||
"announce": "",
|
||||
"templates": "",
|
||||
"subject": "",
|
||||
"message": "Wiadomość",
|
||||
"variables": "",
|
||||
"conditionals": "",
|
||||
"preview": "",
|
||||
"reset": "Zresetuj",
|
||||
"edit": "Edytuj",
|
||||
"donate": "",
|
||||
"sendPWR": "",
|
||||
"contactThrough": "",
|
||||
"extendExpiry": "",
|
||||
"sendPWRManual": "",
|
||||
"sendPWRSuccess": "",
|
||||
"sendPWRSuccessManual": "",
|
||||
"sendPWRValidFor": "",
|
||||
"customizeMessages": "",
|
||||
"customizeMessagesDescription": "",
|
||||
"markdownSupported": "",
|
||||
"modifySettings": "Zmień ustawienia",
|
||||
"modifySettingsDescription": "",
|
||||
"applyHomescreenLayout": "",
|
||||
"sendDeleteNotificationEmail": "",
|
||||
"sendDeleteNotifiationExample": "",
|
||||
"settingsRestart": "",
|
||||
"settingsRestarting": "",
|
||||
"settingsRestartRequired": "",
|
||||
"settingsRestartRequiredDescription": "",
|
||||
"settingsApplyRestartLater": "",
|
||||
"settingsApplyRestartNow": "",
|
||||
"settingsApplied": "",
|
||||
"settingsRefreshPage": "",
|
||||
"settingsRequiredOrRestartMessage": "",
|
||||
"settingsSave": "",
|
||||
"ombiProfile": "",
|
||||
"ombiUserDefaultsDescription": "",
|
||||
"userProfiles": "",
|
||||
"userProfilesDescription": "",
|
||||
"userProfilesIsDefault": "",
|
||||
"userProfilesLibraries": "",
|
||||
"addProfile": "Dodaj Profil",
|
||||
"addProfileDescription": "",
|
||||
"addProfileNameOf": "Nazwa profilu",
|
||||
"addProfileStoreHomescreenLayout": "",
|
||||
"inviteNoUsersCreated": "",
|
||||
"inviteUsersCreated": "",
|
||||
"inviteNoProfile": "",
|
||||
"inviteDateCreated": "Utworzone",
|
||||
"inviteRemainingUses": "",
|
||||
"inviteNoInvites": "",
|
||||
"inviteExpiresInTime": "",
|
||||
"notifyEvent": "",
|
||||
"notifyInviteExpiry": "",
|
||||
"notifyUserCreation": "",
|
||||
"sendPIN": "Poproś użytkownika aby wysłał kod PIN przy użyciu bota.",
|
||||
"searchDiscordUser": "",
|
||||
"findDiscordUser": "",
|
||||
"linkMatrixDescription": "",
|
||||
"matrixHomeServer": "",
|
||||
"saveAsTemplate": "",
|
||||
"deleteTemplate": "Usuń szablon",
|
||||
"templateEnterName": "Wprowadź nazwę aby zapisać szablon.",
|
||||
"accessJFA": "",
|
||||
"accessJFASettings": ""
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Zmieniono adres email {n}.",
|
||||
"userCreated": "Użytkownik {n} utworzony.",
|
||||
"createProfile": "Stworzono profil {n}.",
|
||||
"saveSettings": "Ustawienia zostały zapisane",
|
||||
"saveEmail": "Email zapisany.",
|
||||
"sentAnnouncement": "Ogłoszenie wysłane.",
|
||||
"savedAnnouncement": "Ogłoszenie zostało zapisane.",
|
||||
"setOmbiProfile": "Zapisany profil ombi.",
|
||||
"updateApplied": "Aktualizacja zastosowana, uruchom ponownie.",
|
||||
"updateAppliedRefresh": "Aktualizacja zastosowana, odśwież.",
|
||||
"telegramVerified": "Konto telegramu zweryfikowane.",
|
||||
"accountConnected": "Konto połączone.",
|
||||
"errorConnection": "Nie udało się połączyć z jfa-go.",
|
||||
"error401Unauthorized": "Nieautoryzowany. Spróbuj odświeżyć stronę.",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "Zastosowano ustawienia, ale zastosowanie układu ekranu głównego mogło się nie powieść.",
|
||||
"errorHomescreenAppliedNoSettings": "",
|
||||
"errorSettingsFailed": "",
|
||||
"errorLoginBlank": "",
|
||||
"errorUnknown": "Nieznany błąd.",
|
||||
"errorSaveEmail": "",
|
||||
"errorBlankFields": "",
|
||||
"errorDeleteProfile": "",
|
||||
"errorLoadProfiles": "",
|
||||
"errorCreateProfile": "",
|
||||
"errorSetDefaultProfile": "",
|
||||
"errorLoadUsers": "",
|
||||
"errorSaveSettings": "",
|
||||
"errorLoadSettings": "",
|
||||
"errorSetOmbiProfile": "",
|
||||
"errorLoadOmbiUsers": "",
|
||||
"errorChangedEmailAddress": "",
|
||||
"errorFailureCheckLogs": "",
|
||||
"errorPartialFailureCheckLogs": "",
|
||||
"errorUserCreated": "",
|
||||
"errorSendWelcomeEmail": "",
|
||||
"errorApplyUpdate": "",
|
||||
"errorCheckUpdate": "",
|
||||
"updateAvailable": "",
|
||||
"noUpdatesAvailable": ""
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"deleteNUsers": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"addUser": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"deleteUser": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"deletedUser": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"disabledUser": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"enabledUser": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"announceTo": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"appliedSettings": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"extendExpiry": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@
|
||||
"settingsRequiredOrRestartMessage": "Nota: {n} indica campo obrigatório, {n} indica que as alterações requer um reinício.",
|
||||
"settingsSave": "Salve",
|
||||
"ombiUserDefaults": "Padrões do usuário Ombi",
|
||||
"ombiUserDefaultsDescription": "Crie um usuário Ombi, configure-o e selecione-o abaixo. Suas configurações/permissões serão armazenadas e aplicadas aos novos usuários Ombi criados pelo jfa-go",
|
||||
"ombiUserDefaultsDescription": "Crie um usuário Ombi e configure-o, depois selecione-o abaixo. Suas configurações/permissões serão armazenadas e aplicadas a novos usuários Ombi criados pelo jfa-go quando este perfil for selecionado.",
|
||||
"userProfiles": "Perfil de usuário",
|
||||
"userProfilesDescription": "Os perfis são aplicados aos usuários quando eles criam uma conta. Um perfil inclui direitos de acesso à biblioteca e layout da tela inicial.",
|
||||
"userProfilesIsDefault": "Padrão",
|
||||
@@ -72,7 +72,7 @@
|
||||
"customizeMessagesDescription": "Se não quiser usar os modelos de email do jfa-go, você pode criar o seu próprio usando o Markdown.",
|
||||
"variables": "Variáveis",
|
||||
"preview": "Pre-visualizar",
|
||||
"reset": "Reiniciar",
|
||||
"reset": "Redefinir",
|
||||
"edit": "Editar",
|
||||
"customizeMessages": "Customizar Emails",
|
||||
"disabled": "Desativado",
|
||||
@@ -94,7 +94,7 @@
|
||||
"conditionals": "Condicionais",
|
||||
"donate": "Doar",
|
||||
"contactThrough": "Contato através:",
|
||||
"sendPIN": "Peça ao usuário para enviar o PIN abaixo para o bot.",
|
||||
"sendPIN": "Peça que o usuário envie o PIN abaixo para o bot.",
|
||||
"searchDiscordUser": "Digite o nome de usuário do Discord.",
|
||||
"findDiscordUser": "Encontrar usuário Discord",
|
||||
"add": "Adicionar",
|
||||
@@ -104,7 +104,17 @@
|
||||
"matrixHomeServer": "Endereço do servidor local",
|
||||
"saveAsTemplate": "Salvar o modelo",
|
||||
"deleteTemplate": "Deletar modelo",
|
||||
"templateEnterName": "Digite um nome para salvar este modelo."
|
||||
"templateEnterName": "Digite um nome para salvar este modelo.",
|
||||
"ombiProfile": "Ombi perfil de usuário",
|
||||
"setExpiry": "Definir vencimento",
|
||||
"logs": "Histórico",
|
||||
"sendPWRManual": "O usuário {a} não tem método de contato, pressione copiar para obter um link para enviar a ele.",
|
||||
"accessJFA": "Acessar o jfa-go",
|
||||
"sendPWR": "Enviar redefinição de senha",
|
||||
"sendPWRSuccess": "Link de redefinição de senha enviado.",
|
||||
"sendPWRSuccessManual": "Se o usuário não o recebeu, pressione copiar para obter um link para enviar manualmente a ele.",
|
||||
"sendPWRValidFor": "O link é válido por 30m.",
|
||||
"accessJFASettings": "Não pode ser alterado porque \"Só Administrador\" ou \"Permitir todos\" foi definido em Configurações> Geral."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Endereço de e-mail alterado de {n}.",
|
||||
@@ -145,7 +155,9 @@
|
||||
"telegramVerified": "Conta do Telegram verificada.",
|
||||
"updateAppliedRefresh": "Atualização instalada, atualize.",
|
||||
"accountConnected": "Conta conectada.",
|
||||
"savedAnnouncement": "Anúncio salvo."
|
||||
"savedAnnouncement": "Anúncio salvo.",
|
||||
"setOmbiProfile": "Perfil ombi armazenado.",
|
||||
"errorSetOmbiProfile": "Falha ao armazenar o perfil ombi."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@@ -199,6 +211,10 @@
|
||||
"enabledUser": {
|
||||
"singular": "{n} Usuário habilitado.",
|
||||
"plural": "{n} Usuários habilitado."
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "Definir expiração para {a} usuário",
|
||||
"plural": "Definir expiração para {a} usuários"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Vietnamese (VN)"
|
||||
"name": "Tiếng Anh (Mỹ)"
|
||||
},
|
||||
"strings": {
|
||||
"invites": "Lời mời",
|
||||
@@ -110,7 +110,9 @@
|
||||
"matrixHomeServer": "Địa chỉ máy chủ",
|
||||
"saveAsTemplate": "Lưu thành mẫu",
|
||||
"deleteTemplate": "Xóa mẫu",
|
||||
"templateEnterName": "Nhập tên mẫu để lưu mẫu này."
|
||||
"templateEnterName": "Nhập tên mẫu để lưu mẫu này.",
|
||||
"logs": "Nhật ký",
|
||||
"accessJFA": "Truy cập jfa-go"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Đã đổi địa chỉ email của {n}.",
|
||||
|
||||
217
lang/admin/zh-Hant.json
Normal file
217
lang/admin/zh-Hant.json
Normal file
@@ -0,0 +1,217 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"invites": "邀請",
|
||||
"accounts": "帳戶",
|
||||
"settings": "設置",
|
||||
"inviteMonths": "月",
|
||||
"inviteDays": "日",
|
||||
"inviteHours": "小時",
|
||||
"inviteMinutes": "分鐘",
|
||||
"inviteNumberOfUses": "使用次數",
|
||||
"inviteDuration": "邀請時長",
|
||||
"warning": "警告",
|
||||
"inviteInfiniteUsesWarning": "無限使用次數的邀請碼可能被濫用",
|
||||
"inviteSendToEmail": "發送到",
|
||||
"login": "登錄",
|
||||
"logout": "登出",
|
||||
"create": "創建",
|
||||
"apply": "應用",
|
||||
"delete": "刪除",
|
||||
"add": "添加",
|
||||
"select": "選擇",
|
||||
"name": "帳戶名稱",
|
||||
"date": "日期",
|
||||
"enabled": "已啟用",
|
||||
"disabled": "已禁用",
|
||||
"reEnable": "重新啟用",
|
||||
"setExpiry": "設置到期時間",
|
||||
"disable": "禁用",
|
||||
"admin": "管理員",
|
||||
"updates": "更新",
|
||||
"update": "更新",
|
||||
"download": "下載",
|
||||
"search": "搜尋",
|
||||
"advancedSettings": "高級設置",
|
||||
"lastActiveTime": "上次啟用時間",
|
||||
"from": "從",
|
||||
"user": "帳戶",
|
||||
"expiry": "到期",
|
||||
"userExpiry": "帳戶到期",
|
||||
"userExpiryDescription": "每次註冊后指定的時間,jfa-go 將刪除/禁用該帳戶。您可以在設定中更改此行為。",
|
||||
"aboutProgram": "關於",
|
||||
"version": "版本",
|
||||
"commitNoun": "提交",
|
||||
"newUser": "新帳戶",
|
||||
"profile": "帳戶資料",
|
||||
"unknown": "未知",
|
||||
"label": "標籤",
|
||||
"logs": "日誌",
|
||||
"announce": "公告",
|
||||
"templates": "範本",
|
||||
"subject": "主題",
|
||||
"message": "訊息",
|
||||
"variables": "變數",
|
||||
"conditionals": "條件",
|
||||
"preview": "預覽",
|
||||
"reset": "重設",
|
||||
"edit": "編輯",
|
||||
"donate": "捐贈",
|
||||
"sendPWR": "發送密碼重置",
|
||||
"contactThrough": "聯繫方式:",
|
||||
"extendExpiry": "延長到期時間",
|
||||
"sendPWRManual": "使用者 {n} 沒有聯繫方式,請按 “複製” 以獲取連結並手動發送給使用者。",
|
||||
"sendPWRSuccess": "已發送密碼重置連結。",
|
||||
"sendPWRSuccessManual": "如果使用者沒收到,請按 “複製” 以獲取連結並手動發送給使用者。",
|
||||
"sendPWRValidFor": "該連結的有效期為 30 分鐘。",
|
||||
"customizeMessages": "自定義訊息",
|
||||
"customizeMessagesDescription": "如果您不想使用 jfa-go 的訊息範本,可以使用 Markdown 創建自己的訊息範本。",
|
||||
"markdownSupported": "支持 Markdown。",
|
||||
"modifySettings": "修改設置",
|
||||
"modifySettingsDescription": "應用現有配置文件中的設置,或直接從帳戶處獲取設置。",
|
||||
"applyHomescreenLayout": "應用主螢幕佈局",
|
||||
"sendDeleteNotificationEmail": "發送通知訊息",
|
||||
"sendDeleteNotifiationExample": "您的帳戶已被刪除。",
|
||||
"settingsRestart": "重新啟動",
|
||||
"settingsRestarting": "正在重新啟動…",
|
||||
"settingsRestartRequired": "需要重新啟動",
|
||||
"settingsRestartRequiredDescription": "需要重新啟動才能應用您更改的某些設定。 現在重新啟動還是稍後重新啟動?",
|
||||
"settingsApplyRestartLater": "應用,稍後重新啟動",
|
||||
"settingsApplyRestartNow": "應用並重新啟動",
|
||||
"settingsApplied": "已應用設置。",
|
||||
"settingsRefreshPage": "幾秒鐘後刷新頁面。",
|
||||
"settingsRequiredOrRestartMessage": "注意: {n} 表示必填欄位, {n} 表示更改需要重新啟動。",
|
||||
"settingsSave": "儲存",
|
||||
"ombiProfile": "Ombi 帳戶資料",
|
||||
"ombiUserDefaultsDescription": "創建一個 Ombi 帳戶並對其進行配置,然後在下面選擇它。選擇此設定時,它的設置/權限將被存儲並應用於由 jfa-go 創建的新 Ombi 帳戶。",
|
||||
"userProfiles": "帳戶資料",
|
||||
"userProfilesDescription": "配置文件在使用者創建帳戶時應用於使用者。配置文件包括庫訪問權限和主螢幕佈局。",
|
||||
"userProfilesIsDefault": "預設",
|
||||
"userProfilesLibraries": "庫",
|
||||
"addProfile": "添加配置文件",
|
||||
"addProfileDescription": "創建一個 Jellyfin 帳戶並對其進行配置,然後在下面選擇它。將此設定文件應用於邀請時,將使用這些設置創建新帳戶。",
|
||||
"addProfileNameOf": "配置文件名稱",
|
||||
"addProfileStoreHomescreenLayout": "保存主螢幕佈局",
|
||||
"inviteNoUsersCreated": "暫無!",
|
||||
"inviteUsersCreated": "創建的帳戶",
|
||||
"inviteNoProfile": "無資料",
|
||||
"inviteDateCreated": "已創建",
|
||||
"inviteRemainingUses": "剩餘使用次數",
|
||||
"inviteNoInvites": "無",
|
||||
"inviteExpiresInTime": "在 {n} 到期",
|
||||
"notifyEvent": "通知:",
|
||||
"notifyInviteExpiry": "在到期時",
|
||||
"notifyUserCreation": "在創建用戶時",
|
||||
"sendPIN": "要求使用者將下面的 PIN 發送給機器人。",
|
||||
"searchDiscordUser": "開始鍵入 Discord 帳戶名稱以查找帳戶。",
|
||||
"findDiscordUser": "查尋 Discord 帳戶",
|
||||
"linkMatrixDescription": "輸入要用作機器人的帳戶的帳戶名稱和密碼。提交后,應用程序將重新啟動。",
|
||||
"matrixHomeServer": "主伺服器位址",
|
||||
"saveAsTemplate": "儲存為範本",
|
||||
"deleteTemplate": "刪除範本",
|
||||
"templateEnterName": "輸入名稱以儲存此範本。",
|
||||
"accessJFA": "訪問 jfa-go",
|
||||
"accessJFASettings": "無法更改,因為已在「一般設置」中設置了「僅限管理員帳戶」或「允許全部帳戶」。"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "更改了 {n} 的電子郵件地址。",
|
||||
"userCreated": "帳戶 {n} 已創建。",
|
||||
"createProfile": "創建了配置文件 {n}。",
|
||||
"saveSettings": "設置已儲存",
|
||||
"saveEmail": "電子郵件已儲存。",
|
||||
"sentAnnouncement": "已發送公告。",
|
||||
"savedAnnouncement": "公告已儲存。",
|
||||
"setOmbiProfile": "ombi 設定已存儲。",
|
||||
"updateApplied": "已應用更新,請重新啟動。",
|
||||
"updateAppliedRefresh": "更新已應用,請重新整理。",
|
||||
"telegramVerified": "Telegram 帳戶已驗證。",
|
||||
"accountConnected": "帳戶已連接。",
|
||||
"errorConnection": "無法連接到 jfa-go。",
|
||||
"error401Unauthorized": "未經授權。嘗試重新整理頁面。",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "已應用設置,但應用主螢幕佈局可能失敗。",
|
||||
"errorHomescreenAppliedNoSettings": "已應用主螢幕佈局,但應用設置可能失敗。",
|
||||
"errorSettingsFailed": "應用失敗。",
|
||||
"errorLoginBlank": "帳戶名稱和/或密碼留空。",
|
||||
"errorUnknown": "未知的錯誤。",
|
||||
"errorSaveEmail": "無法儲存電子郵件。",
|
||||
"errorBlankFields": "欄位留空",
|
||||
"errorDeleteProfile": "無法刪除設置文件 {n}",
|
||||
"errorLoadProfiles": "無法讀取設置文件。",
|
||||
"errorCreateProfile": "無法創建設置文件 {n}",
|
||||
"errorSetDefaultProfile": "無法設置預設設置文件。",
|
||||
"errorLoadUsers": "無法讀取帳戶。",
|
||||
"errorSaveSettings": "無法儲存設置。",
|
||||
"errorLoadSettings": "無法讀取設置。",
|
||||
"errorSetOmbiProfile": "無法儲存 ombi 設置文件。",
|
||||
"errorLoadOmbiUsers": "無法讀取 ombi 帳戶。",
|
||||
"errorChangedEmailAddress": "無法更改 {n} 的電子郵件地址。",
|
||||
"errorFailureCheckLogs": "失敗(請檢查主控台/紀錄)",
|
||||
"errorPartialFailureCheckLogs": "部分故障(請檢查主控台/日誌)",
|
||||
"errorUserCreated": "無法創建帳戶 {n}。",
|
||||
"errorSendWelcomeEmail": "無法送出歡迎訊息(請檢查主控台/紀錄)",
|
||||
"errorApplyUpdate": "無法應用更新,請手動嘗試。",
|
||||
"errorCheckUpdate": "無法檢查更新。",
|
||||
"updateAvailable": "有新的更新可用,請檢查設置。",
|
||||
"noUpdatesAvailable": "沒有新的更新可用。"
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
"singular": "修改 {n} 個帳戶的設置",
|
||||
"plural": "修改 {n} 個帳戶的設置"
|
||||
},
|
||||
"deleteNUsers": {
|
||||
"singular": "刪除 {n} 個帳戶",
|
||||
"plural": "刪除 {n} 個帳戶"
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "禁用 {n} 個帳戶",
|
||||
"plural": "禁用 {n} 個帳戶"
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "重新啟用 {n} 個帳戶",
|
||||
"plural": "重新啟用 {n} 個帳戶"
|
||||
},
|
||||
"addUser": {
|
||||
"singular": "添加帳戶",
|
||||
"plural": "添加帳戶"
|
||||
},
|
||||
"deleteUser": {
|
||||
"singular": "刪除帳戶",
|
||||
"plural": "刪除帳戶"
|
||||
},
|
||||
"deletedUser": {
|
||||
"singular": "刪除 {n} 個帳戶。",
|
||||
"plural": "刪除 {n} 個帳戶。"
|
||||
},
|
||||
"disabledUser": {
|
||||
"singular": "禁用 {n} 個帳戶。",
|
||||
"plural": "禁用 {n} 個帳戶。"
|
||||
},
|
||||
"enabledUser": {
|
||||
"singular": "已啟用 {n} 個帳戶。",
|
||||
"plural": "已啟用 {n} 個帳戶。"
|
||||
},
|
||||
"announceTo": {
|
||||
"singular": "公告給 {n} 個帳戶",
|
||||
"plural": "公告給 {n} 個帳戶"
|
||||
},
|
||||
"appliedSettings": {
|
||||
"singular": "將設置應用到 {n} 個帳戶。",
|
||||
"plural": "將設置應用到 {n} 個帳戶。"
|
||||
},
|
||||
"extendExpiry": {
|
||||
"singular": "延長 {n} 個帳戶的到期時間",
|
||||
"plural": "延長 {n} 個帳戶的到期時間"
|
||||
},
|
||||
"setExpiry": {
|
||||
"singular": "設置 {n} 個帳戶的到期時間",
|
||||
"plural": "設置 {n} 個帳戶的到期時間"
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"singular": "已延長 {n} 個帳戶的到期時間。",
|
||||
"plural": "已延長 {n} 個帳戶的到期時間。"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -78,7 +78,7 @@
|
||||
"settingsRequiredOrRestartMessage": "注意:{n} 表示必填字段,{n} 表示更改需要重新启动。",
|
||||
"settingsSave": "保存",
|
||||
"ombiUserDefaults": "Ombi 用户默认值",
|
||||
"ombiUserDefaultsDescription": "创建并配置 Ombi 用户,然后在下面选择它。它的设置/权限将被存储并应用于由 jfa-go 创建的新 Ombi 用户",
|
||||
"ombiUserDefaultsDescription": "创建并配置 Ombi 用户,然后在下面选择它。它的设置/权限将被存储并应用于由 jfa-go 创建的新 Ombi 用户。",
|
||||
"userProfiles": "用户档案",
|
||||
"userProfilesDescription": "配置文件在用户创建帐户时应用于用户。配置文件包括库访问权限和主屏幕布局。",
|
||||
"userProfilesIsDefault": "默认",
|
||||
@@ -97,14 +97,24 @@
|
||||
"notifyEvent": "通知:",
|
||||
"notifyInviteExpiry": "在到期时",
|
||||
"notifyUserCreation": "在创建用户时",
|
||||
"sendPIN": "要求用户将下面的 PIN 发送给机器人。",
|
||||
"sendPIN": "需要用户将下面的 PIN 发送给机器人。",
|
||||
"searchDiscordUser": "开始输入 Discord 用户名以查找用户。",
|
||||
"findDiscordUser": "查找 Discord 用户",
|
||||
"linkMatrixDescription": "输入要用作机器人的用户的用户名和密码。一旦提交,应用程序将重新启动。",
|
||||
"matrixHomeServer": "主服务器地址",
|
||||
"saveAsTemplate": "保存为模板",
|
||||
"deleteTemplate": "删除模板",
|
||||
"templateEnterName": "输入名称以保存此模板。"
|
||||
"templateEnterName": "输入名称以保存此模板。",
|
||||
"sendPWRManual": "用户 {n} 没有联系方式,请按下钮复制能发给用户的链接。",
|
||||
"sendPWRSuccess": "密码重置链接已发了。",
|
||||
"sendPWR": "发送密码重置",
|
||||
"sendPWRSuccessManual": "如果用户没收到,请按下钮复制链接,手动发给用户。",
|
||||
"setExpiry": "设置到期",
|
||||
"logs": "记录",
|
||||
"sendPWRValidFor": "此链接有效30分钟。",
|
||||
"ombiProfile": "Ombi 用户配置文件",
|
||||
"accessJFASettings": "无法更改,因为“仅限管理员”或“允许所有”已在“设置”>“常规”中设置。",
|
||||
"accessJFA": "访问jfa-go"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "更改了 {n} 的电子邮件地址。",
|
||||
@@ -145,7 +155,9 @@
|
||||
"errorApplyUpdate": "无法应用更新,请手动尝试。",
|
||||
"errorCheckUpdate": "检查更新失败。",
|
||||
"updateAvailable": "有新更新可用,请检查设置。",
|
||||
"noUpdatesAvailable": "没有可用的更新。"
|
||||
"noUpdatesAvailable": "没有可用的更新。",
|
||||
"setOmbiProfile": "保存ombi配置文件。",
|
||||
"errorSetOmbiProfile": "无法保存ombi配置文件。"
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@@ -199,6 +211,10 @@
|
||||
"extendedExpiry": {
|
||||
"singular": "延长了 {n} 个用户的有效期。",
|
||||
"plural": "延长了 {n} 个用户的有效期。"
|
||||
},
|
||||
"setExpiry": {
|
||||
"plural": "为{n}用户设置到期时间",
|
||||
"singular": "为{n}用户设置到期时间"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Kontakt gennem Discord",
|
||||
"theme": "Tema"
|
||||
"theme": "Tema",
|
||||
"refresh": "Opdater",
|
||||
"required": "Påkrævet"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
"username": "Benutzername",
|
||||
"name": "Name",
|
||||
"password": "Passwort",
|
||||
"emailAddress": "E-Mail-Adresse",
|
||||
"emailAddress": "E-Mail Adresse",
|
||||
"submit": "Absenden",
|
||||
"success": "Erfolgreich",
|
||||
"continue": "Weiter",
|
||||
@@ -22,6 +22,8 @@
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"send": "Senden",
|
||||
"contactDiscord": "Kontakt über Discord"
|
||||
"contactDiscord": "Kontakt über Discord",
|
||||
"refresh": "Aktualisieren",
|
||||
"required": "Erforderlich"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,29 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"strings": {
|
||||
"continue": "Continue",
|
||||
"time24h": "24h Time",
|
||||
"linkTelegram": "Link Telegram",
|
||||
"send": "Send",
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Contact through Discord",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"emailAddress": "Email Address",
|
||||
"copy": "Copy",
|
||||
"copied": "Copied",
|
||||
"submit": "Submit",
|
||||
"success": "Success",
|
||||
"error": "Error",
|
||||
"time12h": "12h Time",
|
||||
"theme": "Theme",
|
||||
"contactEmail": "Contact through Email",
|
||||
"contactTelegram": "Contact through Telegram",
|
||||
"name": "Name",
|
||||
"refresh": "Refresh",
|
||||
"required": "Required"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"strings": {
|
||||
"username": "Nombre de usuario",
|
||||
"password": "Contraseña",
|
||||
"emailAddress": "Dirección de correo electrónico",
|
||||
"emailAddress": "Correo electrónico",
|
||||
"name": "Nombre",
|
||||
"submit": "Enviar",
|
||||
"success": "Éxito",
|
||||
@@ -22,6 +22,8 @@
|
||||
"contactTelegram": "Contactar por Telegram",
|
||||
"linkMatrix": "Enlace Matrix",
|
||||
"linkDiscord": "Enlace Discord",
|
||||
"linkTelegram": "Enlace Telegram"
|
||||
"linkTelegram": "Enlace Telegram",
|
||||
"refresh": "Refrescar",
|
||||
"required": "Requerido"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
"copy": "Salin",
|
||||
"time24h": "Waktu 24 jam",
|
||||
"time12h": "Waktu 12 jam",
|
||||
"theme": "Tema"
|
||||
"theme": "Tema",
|
||||
"send": "Kirim"
|
||||
}
|
||||
}
|
||||
|
||||
29
lang/common/it-IT.json
Normal file
29
lang/common/it-IT.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Inglese (US)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"emailAddress": "Indirizzo Email",
|
||||
"name": "Nome",
|
||||
"submit": "Invia",
|
||||
"send": "Invia",
|
||||
"success": "Successo",
|
||||
"continue": "Continua",
|
||||
"error": "Errore",
|
||||
"copy": "Copia",
|
||||
"copied": "Copiato",
|
||||
"time24h": "Formato 24h",
|
||||
"time12h": "Formato 12h",
|
||||
"linkTelegram": "Link Telegram",
|
||||
"contactEmail": "Contatta tramite Email",
|
||||
"contactTelegram": "Contatta tramite Telegram",
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Contatta tramite Discord",
|
||||
"theme": "Tema",
|
||||
"refresh": "Aggiorna",
|
||||
"required": "Richiesto"
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@
|
||||
"send": "Verstuur",
|
||||
"linkDiscord": "Koppel Discord",
|
||||
"linkMatrix": "Koppel Matrix",
|
||||
"contactDiscord": "Stuur Discord bericht"
|
||||
"contactDiscord": "Stuur Discord bericht",
|
||||
"refresh": "Ververs",
|
||||
"required": "Verplicht"
|
||||
}
|
||||
}
|
||||
|
||||
29
lang/common/pl-PL.json
Normal file
29
lang/common/pl-PL.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Nazwa Użytkownika",
|
||||
"password": "Hasło",
|
||||
"emailAddress": "E-mail",
|
||||
"name": "Imię",
|
||||
"submit": "Akceptuj",
|
||||
"send": "Wyślij",
|
||||
"success": "Sukces",
|
||||
"continue": "Kontynuuj",
|
||||
"error": "Błąd",
|
||||
"copy": "Kopiuj",
|
||||
"copied": "Skopiowano",
|
||||
"time24h": "24 godziny",
|
||||
"time12h": "12 godzin",
|
||||
"linkTelegram": "Link Telegram",
|
||||
"contactEmail": "Kontakt drogą mailową",
|
||||
"contactTelegram": "Kontakt przez Telegram",
|
||||
"linkDiscord": "Link do Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Kontakt przez Discord",
|
||||
"theme": "Motyw",
|
||||
"refresh": "Odśwież",
|
||||
"required": "Wymagane"
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"username": "Nome do Usuário",
|
||||
"name": "Nome",
|
||||
"password": "Senha",
|
||||
"emailAddress": "Endereço de Email",
|
||||
"emailAddress": "Endereço de e-mail",
|
||||
"submit": "Enviar",
|
||||
"success": "Sucesso",
|
||||
"continue": "Continuar",
|
||||
@@ -22,6 +22,8 @@
|
||||
"send": "Enviar",
|
||||
"linkDiscord": "Link do Discord",
|
||||
"linkMatrix": "Link do Matrix",
|
||||
"contactDiscord": "Contato através do Discord"
|
||||
"contactDiscord": "Contato através do Discord",
|
||||
"refresh": "Atualizar",
|
||||
"required": "Requeridos"
|
||||
}
|
||||
}
|
||||
|
||||
29
lang/common/sl-si.json
Normal file
29
lang/common/sl-si.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Angleščina (ZDA)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Uporabniško ime",
|
||||
"password": "Geslo",
|
||||
"emailAddress": "E-poštni naslov",
|
||||
"name": "Ime",
|
||||
"submit": "Potrdi",
|
||||
"send": "Pošlji",
|
||||
"success": "Uspeh",
|
||||
"continue": "Nadaljuj",
|
||||
"error": "Napaka",
|
||||
"copy": "Kopiraj",
|
||||
"copied": "Kopirano",
|
||||
"time24h": "24ur format čas",
|
||||
"time12h": "12ur format časa",
|
||||
"linkTelegram": "Poveži Telegram",
|
||||
"contactEmail": "Kontakt preko e-pošte",
|
||||
"contactTelegram": "Kontakt preko Telegrama",
|
||||
"linkDiscord": "Poveži Discord",
|
||||
"linkMatrix": "Poveži Matrix",
|
||||
"contactDiscord": "Kontakt preko Discorda",
|
||||
"theme": "Tema",
|
||||
"refresh": "Osveži",
|
||||
"required": "Obvezno"
|
||||
}
|
||||
}
|
||||
29
lang/common/zh-Hant.json
Normal file
29
lang/common/zh-Hant.json
Normal file
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "帳戶名稱",
|
||||
"password": "密碼",
|
||||
"emailAddress": "電子郵件",
|
||||
"name": "帳戶名稱",
|
||||
"submit": "提交",
|
||||
"send": "發送",
|
||||
"success": "成功",
|
||||
"continue": "繼續",
|
||||
"error": "錯誤",
|
||||
"copy": "複製",
|
||||
"copied": "已複製",
|
||||
"time24h": "24小時制",
|
||||
"time12h": "12小時制",
|
||||
"linkTelegram": "連結 Telegram",
|
||||
"contactEmail": "通過電子郵件聯繫",
|
||||
"contactTelegram": "通過 Telegram 聯繫",
|
||||
"linkDiscord": "連結 Discord",
|
||||
"linkMatrix": "連結 Matrix",
|
||||
"contactDiscord": "通過 Discord 聯繫",
|
||||
"theme": "主題",
|
||||
"refresh": "重新整理",
|
||||
"required": "必填"
|
||||
}
|
||||
}
|
||||
@@ -22,6 +22,8 @@
|
||||
"linkDiscord": "关联Discord",
|
||||
"linkMatrix": "关联Matrix",
|
||||
"contactDiscord": "通过Discord联系",
|
||||
"theme": "主题"
|
||||
"theme": "主题",
|
||||
"refresh": "刷新",
|
||||
"required": "必需的"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,14 @@
|
||||
"title": "Mitteilung: Benutzer erstellt",
|
||||
"aUserWasCreated": "Ein Benutzer wurde unter Verwendung des Codes {code} erstellt.",
|
||||
"time": "Zeit",
|
||||
"notificationNotice": "Hinweis: Benachrichtigungs-E-Mails können auf dem Administrator-Dashboard umgeschalten werden.",
|
||||
"notificationNotice": "Hinweis: Benachrichtigungen können auf dem Administrator-Dashboard umgeschalten werden.",
|
||||
"name": "Benutzererstellung"
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"title": "Mitteilung: Invite abgelaufen",
|
||||
"inviteExpired": "Invite abgelaufen.",
|
||||
"expiredAt": "Code {code} lief um {time} ab.",
|
||||
"notificationNotice": "Hinweis: Benachrichtigungs-E-Mails können auf dem Administrator-Dashboard umgeschalten werden.",
|
||||
"notificationNotice": "Hinweis: Benachrichtigungen können auf dem Administrator-Dashboard umgeschalten werden.",
|
||||
"name": "Invite Ablaufdatum"
|
||||
},
|
||||
"passwordReset": {
|
||||
|
||||
@@ -1,5 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Confirm your email - Jellyfin",
|
||||
"confirmEmail": "Confirm Email",
|
||||
"name": "Confirmation email",
|
||||
"clickBelow": "Click the link below to confirm your email address and start using Jellyfin."
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "Welcome",
|
||||
"title": "Welcome to Jellyfin",
|
||||
"welcome": "Welcome to Jellyfin!",
|
||||
"yourAccountWillExpire": "Your account will expire on {date}.",
|
||||
"jellyfinURL": "URL",
|
||||
"youCanLoginWith": "You can login with the details below"
|
||||
},
|
||||
"strings": {
|
||||
"helloUser": "Hi {username},",
|
||||
"ifItWasNotYou": "If this wasn't you, please ignore this.",
|
||||
"reason": "Reason"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "User creation",
|
||||
"title": "Notice: User created",
|
||||
"time": "Time",
|
||||
"aUserWasCreated": "A user was created using code {code}.",
|
||||
"notificationNotice": "Note: Notification messages can be toggled on the admin dashboard."
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"expiredAt": "Code {code} expired at {time}.",
|
||||
"notificationNotice": "Note: Notification messages can be toggled on the admin dashboard.",
|
||||
"name": "Invite expiry",
|
||||
"title": "Notice: Invite expired",
|
||||
"inviteExpired": "Invite expired."
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "Password reset",
|
||||
"title": "Password reset requested - Jellyfin",
|
||||
"ifItWasYou": "If this was you, enter the pin below into the prompt.",
|
||||
"ifItWasYouLink": "If this was you, click the link below.",
|
||||
"pin": "PIN",
|
||||
"someoneHasRequestedReset": "Someone has recently requested a password reset on Jellyfin.",
|
||||
"codeExpiry": "The code will expire on {date}, at {time} UTC, which is in {expiresInMinutes}."
|
||||
},
|
||||
"userDeleted": {
|
||||
"title": "Your account was deleted - Jellyfin",
|
||||
"yourAccountWasDeleted": "Your Jellyfin account was deleted.",
|
||||
"name": "User deletion"
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "Invite email",
|
||||
"hello": "Hi",
|
||||
"toJoin": "To join, follow the below link.",
|
||||
"inviteExpiry": "This invite will expire on {date} at {time}, which is in {expiresInMinutes}, so act quick.",
|
||||
"linkButton": "Setup your account",
|
||||
"title": "Invite - Jellyfin",
|
||||
"youHaveBeenInvited": "You've been invited to Jellyfin."
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "User expiry",
|
||||
"title": "Your account has expired - Jellyfin",
|
||||
"yourAccountHasExpired": "Your account has expired.",
|
||||
"contactTheAdmin": "Contact the administrator for more info."
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "User disabled",
|
||||
"title": "Your account has been disabled - Jellyfin",
|
||||
"yourAccountWasDisabled": "Your account was disabled."
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "User enabled",
|
||||
"title": "Your account has been re-enabled - Jellyfin",
|
||||
"yourAccountWasEnabled": "Your account was re-enabled."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Bahasa Indonesia (ID)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Jika ini bukan kamu, silahkan mengabaikan email ini.",
|
||||
"ifItWasNotYou": "Jika ini bukan kamu, silahkan abaikan email ini.",
|
||||
"reason": "Alasan",
|
||||
"helloUser": "Halo {username},"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Italiano (IT)"
|
||||
"name": "Inglese (US)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Se non sei stato tu, puoi ignorare questa email.",
|
||||
|
||||
77
lang/email/pl-PL.json
Normal file
77
lang/email/pl-PL.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Jeśli to nie ty, zignoruj tą wiadomość.",
|
||||
"helloUser": "Hi {username},",
|
||||
"reason": "Przyczyna"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "Tworzenie użytkownika",
|
||||
"title": "Uwaga: Użytkownik utworzony",
|
||||
"aUserWasCreated": "Użytkownik został utworzony przy użyciu kodu {code}.",
|
||||
"time": "Czas",
|
||||
"notificationNotice": "Uwaga: Powiadomienia mogą być włączone z panelu administratora."
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "Zaproszenie wygaśnie",
|
||||
"title": "Uwaga: Zaproszenie wygasło",
|
||||
"inviteExpired": "Zaproszenie wygasło.",
|
||||
"expiredAt": "Kod {code} wygaśnie za {time}.",
|
||||
"notificationNotice": "Uwaga: Powiadomienia mogą zostać włączone w panelu administratora."
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "Resetowanie hasła",
|
||||
"title": "Prośba o reset hasła -Jellyfin",
|
||||
"someoneHasRequestedReset": "Ktoś niedawno poprosił o zresetowanie hasła w Jellyfin.",
|
||||
"ifItWasYou": "Jeśli to byłeś ty, wprowadź PIN poniżej.",
|
||||
"ifItWasYouLink": "Jeśli to byłeś ty, kliknij link poniżej.",
|
||||
"codeExpiry": "Ten kod wygaśnie {date}, o {time} UTC, dokładnie za {expiresInMinutes}.",
|
||||
"pin": "PIN"
|
||||
},
|
||||
"userDeleted": {
|
||||
"name": "Usuwanie użytownika",
|
||||
"title": "Twoje konto zostało usunięte - Jellyfin",
|
||||
"yourAccountWasDeleted": "Twoje konto Jellyfin zostało usunięte."
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "Użytkownik wyłączony",
|
||||
"title": "Twoje konto zostało wyłączone - Jellyfin",
|
||||
"yourAccountWasDisabled": "Twoje konto zostało wyłączone."
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "Użytkownik włączony",
|
||||
"title": "Twoje konto zostało ponownie włączony - Jellyfin",
|
||||
"yourAccountWasEnabled": "Twoje konto zostało włączone ponownie."
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "Email z zaproszeniem",
|
||||
"title": "Zaproszenie - Jellyfin",
|
||||
"hello": "Cześć",
|
||||
"youHaveBeenInvited": "Zostałeś zaproszony na Jellyfin.",
|
||||
"toJoin": "Aby dołączyć, przejdź używając linku poniżej.",
|
||||
"inviteExpiry": "To zaproszenie wygaśnie {date} o {time}, czyli za {expiresInMinutes}, więc się pośpiesz.",
|
||||
"linkButton": "Skonfiguruj swoje konto"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "Witaj",
|
||||
"title": "Witaj w Jellyfin",
|
||||
"welcome": "Witaj w Jellyfin!",
|
||||
"youCanLoginWith": "Możesz się teraz zalogować używając poniższych danych",
|
||||
"yourAccountWillExpire": "Twoje konto wygaśnie {date}.",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"name": "Potwierdź adres email",
|
||||
"title": "Potwierdź adres email - Jellyfin",
|
||||
"clickBelow": "Naciśnij link poniżej aby potwierdzić adres email.",
|
||||
"confirmEmail": "Potwierdź adres email"
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "Użytkownik wygasł",
|
||||
"title": "Twoje konto wygasło - Jellyfin",
|
||||
"yourAccountHasExpired": "Twoje konto wygasło.",
|
||||
"contactTheAdmin": "Skontaktuj się z administratorem aby uzyskać więcej szczegółów."
|
||||
}
|
||||
}
|
||||
@@ -11,14 +11,14 @@
|
||||
"title": "Aviso: Usuário criado",
|
||||
"aUserWasCreated": "Um usuário foi criado usando o código {code}.",
|
||||
"time": "Tempo",
|
||||
"notificationNotice": "Nota: Os emails de notificação podem ser alternados no painel do administrador.",
|
||||
"notificationNotice": "Nota: As mensagens de notificação podem ser alternadas no painel do administrador.",
|
||||
"name": "Criação de usuário"
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"title": "Aviso: Convite expirado",
|
||||
"inviteExpired": "Convite expirado.",
|
||||
"expiredAt": "O código {code} expirou em {time}.",
|
||||
"notificationNotice": "Nota: Os emails de notificação podem ser alternados no painel do administrador.",
|
||||
"notificationNotice": "Nota: As mensagens de notificação podem ser alternadas no painel do administrador.",
|
||||
"name": "Convite Expirado"
|
||||
},
|
||||
"passwordReset": {
|
||||
|
||||
77
lang/email/ro-RO.json
Normal file
77
lang/email/ro-RO.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Română (ROU)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Dacă nu ați fost dvs., vă rugăm să ignorați asta.",
|
||||
"helloUser": "Salut {username},",
|
||||
"reason": "Motiv"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "Crearea utilizatorului",
|
||||
"title": "Notă: Utilizator creat",
|
||||
"aUserWasCreated": "Un utilizator a fost creat folosind codul {code}.",
|
||||
"time": "Oră",
|
||||
"notificationNotice": "Notă: Mesajele de notificare pot fi comutate în Tabloul de Bord."
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "Expirare invitație",
|
||||
"title": "Notă: Invitația a expirat",
|
||||
"inviteExpired": "Invitația a expirat.",
|
||||
"expiredAt": "Codul {code} a expirat la {time}.",
|
||||
"notificationNotice": "Notă: Mesajele de notificare pot fi comutate în Tabloul de Bord."
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "Resetare parolă",
|
||||
"title": "Solicitată resetarea parolei - Jellyfin",
|
||||
"someoneHasRequestedReset": "Cineva a cerut recent o resetare a parolei pe Jellyfin.",
|
||||
"ifItWasYou": "Dacă acesta ați fost dvs., introduceți codul de mai jos în solicitare.",
|
||||
"ifItWasYouLink": "Dacă acesta ați fost dvs., faceți clic pe linkul de mai jos.",
|
||||
"codeExpiry": "Codul va expira pe {date}, la {time} UTC, adică în {expiresInMinutes}.",
|
||||
"pin": "PIN"
|
||||
},
|
||||
"userDeleted": {
|
||||
"name": "Ștergere utilizator",
|
||||
"title": "Contul dvs. a fost șters - Jellyfin",
|
||||
"yourAccountWasDeleted": "Contul dvs. Jellyfin a fost șters."
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "Utilizator dezactivat",
|
||||
"title": "Contul dvs. a fost dezactivat - Jellyfin",
|
||||
"yourAccountWasDisabled": "Contul dvs. a fost dezactivat."
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "Utilizator activat",
|
||||
"title": "Contul dvs. a fost reactivat - Jellyfin",
|
||||
"yourAccountWasEnabled": "Contul dvs. a fost reactivat."
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "E-mail de invitație",
|
||||
"title": "Invitație - Jellyfin",
|
||||
"hello": "Salut",
|
||||
"youHaveBeenInvited": "Ai fost invitat la Jellyfin.",
|
||||
"toJoin": "Pentru a vă alătura, urmați linkul de mai jos.",
|
||||
"inviteExpiry": "Această invitație va expira pe {date} la {time}, care este în {expiresInMinutes}, așa că acționați rapid.",
|
||||
"linkButton": "Configurați-vă contul"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "Bun venit",
|
||||
"title": "Bun venit la Jellyfin",
|
||||
"welcome": "Bun venit la Jellyfin!",
|
||||
"youCanLoginWith": "Vă puteți autentifica cu detaliile de mai jos",
|
||||
"yourAccountWillExpire": "Contul dvs. va expira pe {date}.",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"name": "E-mail de confirmare",
|
||||
"title": "Confirmați e-mailul dvs. - Jellyfin",
|
||||
"clickBelow": "Faceți clic pe linkul de mai jos pentru a vă confirma adresa de e-mail și pentru a începe să utilizați Jellyfin.",
|
||||
"confirmEmail": "Confirmați adresa de e-mail"
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "Expirarea utilizatorului",
|
||||
"title": "Contul dvs. a expirat - Jellyfin",
|
||||
"yourAccountHasExpired": "Contul dvs. a expirat.",
|
||||
"contactTheAdmin": "Contactați administratorul pentru mai multe informații."
|
||||
}
|
||||
}
|
||||
77
lang/email/zh-Hant.json
Normal file
77
lang/email/zh-Hant.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "如果這不是您,請忽略本信件。",
|
||||
"helloUser": "你好 {username},",
|
||||
"reason": "原因"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "帳戶創建",
|
||||
"title": "注意:帳戶已創建",
|
||||
"aUserWasCreated": "已使用邀請碼 {code} 創建了一個帳戶。",
|
||||
"time": "時間",
|
||||
"notificationNotice": "注意:可以在管理儀錶板上切換通知訊息。"
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "邀請到期",
|
||||
"title": "通知:邀請已過期",
|
||||
"inviteExpired": "邀請已過期。",
|
||||
"expiredAt": "邀請碼 {code} 在 {time} 過期。",
|
||||
"notificationNotice": "注意:可以在管理儀錶板上切換通知訊息。"
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "重置密碼",
|
||||
"title": "忘記密碼 - Jellfin",
|
||||
"someoneHasRequestedReset": "最近在 Jellyfin 上有一個您的密碼重置申請。",
|
||||
"ifItWasYou": "如果是您本人,請在密碼重置提示框中輸入下方的 PIN 碼。",
|
||||
"ifItWasYouLink": "如果是您本人,請點選下方的連結。",
|
||||
"codeExpiry": "該 PIN 碼將在 {expiresInMinutes} 内到期(UTC 時間 {date} {time})。",
|
||||
"pin": "PIN 碼"
|
||||
},
|
||||
"userDeleted": {
|
||||
"name": "帳戶刪除",
|
||||
"title": "您的帳戶已被刪除 - Jellyfin",
|
||||
"yourAccountWasDeleted": "您的 Jellyfin 帳戶已被刪除。"
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "帳戶已被禁用",
|
||||
"title": "您的帳戶已被禁用 - Jellyfin",
|
||||
"yourAccountWasDisabled": "您的帳戶已被禁用。"
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "帳戶已被重新啟用",
|
||||
"title": "您的帳戶已被重新啟用 - Jellyfin",
|
||||
"yourAccountWasEnabled": "您的帳戶已被重新啟用。"
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "邀請電子郵件",
|
||||
"title": "邀請 - Jellyfin",
|
||||
"hello": "您好",
|
||||
"youHaveBeenInvited": "您已受邀註冊 Jellyfin。",
|
||||
"toJoin": "請點選以下連結來加入。",
|
||||
"inviteExpiry": "此邀請將於 {date} {time} 到期,即 {expiresInMinutes} 內,請儘快註冊。",
|
||||
"linkButton": "設置您的帳戶"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "歡迎",
|
||||
"title": "歡迎使用 Jellyfin",
|
||||
"welcome": "歡迎使用 Jellyfin!",
|
||||
"youCanLoginWith": "您可以使用以下資訊登錄",
|
||||
"yourAccountWillExpire": "您的帳戶將在 {date} 到期。",
|
||||
"jellyfinURL": "網址"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"name": "確認電子郵件",
|
||||
"title": "確認您的電子郵件 - Jellyfin",
|
||||
"clickBelow": "點選下面的連結以確認您的電子郵件地址並開始使用 Jellyfin。",
|
||||
"confirmEmail": "確認電子郵件"
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "帳戶到期",
|
||||
"title": "您的帳號已過期 - Jellyfin",
|
||||
"yourAccountHasExpired": "您的帳號已過期。",
|
||||
"contactTheAdmin": "請聯繫管理員瞭解更多資訊。"
|
||||
}
|
||||
}
|
||||
@@ -4,46 +4,46 @@
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "如果这不是您,请忽略本邮件。",
|
||||
"helloUser": "你好{username},",
|
||||
"helloUser": "你好 {username},",
|
||||
"reason": "原因"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "创建用户",
|
||||
"title": "注意:用户已创建",
|
||||
"aUserWasCreated": "使用代码{code}创建了一个用户。",
|
||||
"name": "用户创建",
|
||||
"title": "通知:用户已创建",
|
||||
"aUserWasCreated": "使用邀请码 {code} 创建了一个用户。",
|
||||
"time": "时间",
|
||||
"notificationNotice": "注意:通知邮件可以在管理仪表板上进行切换。"
|
||||
"notificationNotice": "提示:您可以在管理面板上开关邮件通知。"
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "邀请到期",
|
||||
"title": "注意:邀请已过期",
|
||||
"title": "通知:邀请已过期",
|
||||
"inviteExpired": "邀请已过期。",
|
||||
"expiredAt": "代码 {code} 已于 {time} 过期。",
|
||||
"notificationNotice": "注意:通知邮件可以在管理仪表板上进行切换。"
|
||||
"expiredAt": "邀请码 {code} 已于 {time} 过期。",
|
||||
"notificationNotice": "提示:您可以在管理面板上开关邮件通知。"
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "重设密码",
|
||||
"title": "要求重设密码 - Jellyfin",
|
||||
"someoneHasRequestedReset": "最近在Jellyfin上有一个重设密码的请求。",
|
||||
"ifItWasYou": "如果这是您,请在提示中输入下面的PIN。",
|
||||
"ifItWasYouLink": "如果这是您,请单击下面的链接。",
|
||||
"codeExpiry": "该代码将在UTC时间{日期} {时间}到期,也就是{expires In Minutes}。",
|
||||
"pin": "PIN"
|
||||
"name": "密码重置",
|
||||
"title": "忘记密码 - Jellyfin",
|
||||
"someoneHasRequestedReset": "刚刚在 Jellyfin 上有一个密码重置请求。",
|
||||
"ifItWasYou": "如果是您本人,请在密码重置提示框中输入下面的 PIN 码。",
|
||||
"ifItWasYouLink": "如果是您本人,请单击下面的链接。",
|
||||
"codeExpiry": "该 PIN 码将在 {expiresInMinutes} 内到期(UTC 时间 {date} {time})。",
|
||||
"pin": "PIN 码"
|
||||
},
|
||||
"userDeleted": {
|
||||
"name": "删除用户",
|
||||
"title": "您的账户已被删除 - Jellyfin",
|
||||
"yourAccountWasDeleted": "您的 Jellyfin 帐户已被删除。"
|
||||
"name": "用户删除",
|
||||
"title": "您的账号已被删除 - Jellyfin",
|
||||
"yourAccountWasDeleted": "您的 Jellyfin 账号已被删除。"
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "用户禁用",
|
||||
"title": "您的帐户已被禁用 - Jellyfin",
|
||||
"yourAccountWasDisabled": "您的帐户已被禁用。"
|
||||
"title": "您的账号已被禁用 - Jellyfin",
|
||||
"yourAccountWasDisabled": "您的账号已被禁用。"
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "用户已启用",
|
||||
"title": "您的帐户已重新启用 - Jellyfin",
|
||||
"yourAccountWasEnabled": "您的帐户已重新启用。"
|
||||
"name": "用户重新启用",
|
||||
"title": "您的账号已被重新启用 - Jellyfin",
|
||||
"yourAccountWasEnabled": "您的账号已被重新启用。"
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "邀请邮件",
|
||||
@@ -51,15 +51,15 @@
|
||||
"hello": "您好",
|
||||
"youHaveBeenInvited": "您已受邀注册 Jellyfin。",
|
||||
"toJoin": "若要加入,请点击以下链接。",
|
||||
"inviteExpiry": "此邀请将于 {date} 的 {time} 到期,即 {expires In Minutes},因此请迅速行动。",
|
||||
"linkButton": "设置您的帐户"
|
||||
"inviteExpiry": "此邀请将于 {date} {time} 到期,即 {expires In Minutes} 内,请尽快注册。",
|
||||
"linkButton": "设置您的账号"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "欢迎",
|
||||
"title": "欢迎使用Jellyfin",
|
||||
"welcome": "欢迎使用Jellyfin!",
|
||||
"title": "欢迎使用 Jellyfin",
|
||||
"welcome": "欢迎使用 Jellyfin!",
|
||||
"youCanLoginWith": "您可以使用以下信息登录",
|
||||
"yourAccountWillExpire": "您的帐户将于 {date}到期。",
|
||||
"yourAccountWillExpire": "您的账号将于 {date} 到期。",
|
||||
"jellyfinURL": "链接"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
@@ -70,8 +70,8 @@
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "用户到期",
|
||||
"title": "您的帐户已过期 - Jellyfin",
|
||||
"yourAccountHasExpired": "您的帐户已过期。",
|
||||
"title": "您的账号已过期 - Jellyfin",
|
||||
"yourAccountHasExpired": "您的账号已过期。",
|
||||
"contactTheAdmin": "请联系管理员了解更多信息。"
|
||||
}
|
||||
}
|
||||
|
||||
60
lang/form/ar-aa.json
Normal file
60
lang/form/ar-aa.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "العربية (AR)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "أنشاء حساب",
|
||||
"createAccountHeader": "أنشاء حساب",
|
||||
"accountDetails": "التفاصيل",
|
||||
"emailAddress": "البريد الالكتروني",
|
||||
"username": "اسم المستخدم",
|
||||
"password": "كلمة المرور",
|
||||
"reEnterPassword": "تأكيد كلمة المرور",
|
||||
"reEnterPasswordInvalid": "كلمة المرور غير مطابقة.",
|
||||
"createAccountButton": "أنشاء حساب",
|
||||
"passwordRequirementsHeader": "متطلبات كلمة المرور",
|
||||
"successHeader": "تم!",
|
||||
"confirmationRequired": "مطلوب تأكيد البريد الإلكتروني",
|
||||
"confirmationRequiredMessage": "يرجى التحقق من صندوق البريد الإلكتروني الخاص بك للتحقق من عنوانك.",
|
||||
"yourAccountIsValidUntil": "سيكون حسابك ساري المفعول حتى {date}.",
|
||||
"sendPIN": "أرسل رقم التعريف الشخصي أدناه إلى الروبوت ، ثم ارجع إلى هنا لربط حسابك.",
|
||||
"sendPINDiscord": "اكتب {command} في {server_channel} على Discord ، ثم أرسل رقم التعريف الشخصي أدناه.",
|
||||
"matrixEnterUser": "أدخل معرف المستخدم الخاص بك ، واضغط على إرسال ، وسيتم إرسال رمز PIN إليك. أدخله هنا للمتابعة."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "المستخدم موجود مسبقا.",
|
||||
"errorInvalidCode": "رمز دعوة غير صالح.",
|
||||
"errorTelegramVerification": "مطلوب التحقق من Telegram.",
|
||||
"errorDiscordVerification": "مطلوب التحقق من الخلاف.",
|
||||
"errorMatrixVerification": "مطلوب التحقق من المصفوفة.",
|
||||
"errorInvalidPIN": "رقم التعريف الشخصي غير صالح.",
|
||||
"errorUnknown": "خطأ غير معروف.",
|
||||
"errorNoEmail": "البريد الإلكتروني مطلوب.",
|
||||
"errorCaptcha": "كلمة التحقق غير صحيحة.",
|
||||
"errorPassword": "تحقق من متطلبات كلمة المرور.",
|
||||
"errorNoMatch": "كلمات المرور غير متطابقة.",
|
||||
"verified": "تم التحقق من الحساب."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "يجب أن يتألف من {n} حرف على الأقل",
|
||||
"plural": "يجب ألا يقل عدد الأحرف عن {n}"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "يجب أن تحتوي على {n} حرف كبير على الأقل",
|
||||
"plural": "يجب ألا يقل عدد الأحرف الكبيرة عن {n}"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "يجب أن يتألف من {n} حرف صغير على الأقل",
|
||||
"plural": "يجب ألا يقل عدد الأحرف الصغيرة عن {n}"
|
||||
},
|
||||
"number": {
|
||||
"singular": "يجب أن يحتوي على {n} رقم على الأقل",
|
||||
"plural": "يجب أن يحتوي على {n} رقم على الأقل"
|
||||
},
|
||||
"special": {
|
||||
"singular": "يجب أن يتألف من {n} حرف خاص على الأقل",
|
||||
"plural": "يجب أن يتألف من {n} حرف خاص على الأقل"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,10 +15,10 @@
|
||||
"passwordRequirementsHeader": "Adgangskodekrav",
|
||||
"successHeader": "Succes!",
|
||||
"confirmationRequired": "E-mail bekræftelse er påkrævet",
|
||||
"confirmationRequiredMessage": "Tjek venligst din e-mail indbakke for at verificere din adresse.",
|
||||
"confirmationRequiredMessage": "Tjek venligst din e-mail indbakke for at bekræfte din adresse.",
|
||||
"yourAccountIsValidUntil": "Din konto er gyldig indtil {date}.",
|
||||
"sendPIN": "Send nedenstående pinkode til botten, og kom derefter tilbage her for at sammenkoble din konto.",
|
||||
"sendPINDiscord": "Skriv {command} i {server_channel} på Discord, og send PIN-koden nedenfor via. DM til botten.",
|
||||
"sendPINDiscord": "Skriv {command} i {server_channel} på Discord, og send PIN-koden nedenfor.",
|
||||
"matrixEnterUser": "Skriv dit Bruger ID, tryk Indsend, og en PIN-kode vil blive sendt til dig. Skriv den her efter, for at fortsætte."
|
||||
},
|
||||
"notifications": {
|
||||
@@ -29,8 +29,11 @@
|
||||
"errorMatrixVerification": "Matrix verifikation påkrævet.",
|
||||
"errorInvalidPIN": "PIN-koden er ugyldig.",
|
||||
"errorUnknown": "Ukendt fejl.",
|
||||
"verified": "Konto verificeret.",
|
||||
"errorNoEmail": "E-mail er påkrævet."
|
||||
"verified": "Konto bekræftet.",
|
||||
"errorNoEmail": "E-mail er påkrævet.",
|
||||
"errorCaptcha": "Forkert Captcha.",
|
||||
"errorPassword": "Tjek krav til adgangskode.",
|
||||
"errorNoMatch": "Adgangskoder stemmer ikke overens."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Deutsch (DE)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Jellyfin-Konto erstellen",
|
||||
"pageTitle": "Jellyfin Konto erstellen",
|
||||
"createAccountHeader": "Konto erstellen",
|
||||
"accountDetails": "Kontodaten",
|
||||
"emailAddress": "E-Mail",
|
||||
@@ -14,11 +14,11 @@
|
||||
"createAccountButton": "Konto erstellen",
|
||||
"passwordRequirementsHeader": "Passwortanforderungen",
|
||||
"successHeader": "Erfolgreich!",
|
||||
"confirmationRequired": "E-Mail-Bestätigung erforderlich",
|
||||
"confirmationRequiredMessage": "Bitte überprüfe dein Posteingang und bestätige deine E-Mail-Adresse.",
|
||||
"confirmationRequired": "E-Mail Bestätigung erforderlich",
|
||||
"confirmationRequiredMessage": "Bitte überprüfe deinen Posteingang und bestätige deine E-Mail-Adresse.",
|
||||
"yourAccountIsValidUntil": "Dein Konto wird bis zum {date} gültig sein.",
|
||||
"sendPIN": "Sende die untenstehende PIN an den Bot und komm dann hierher zurück, um dein Konto zu verbinden.",
|
||||
"sendPINDiscord": "Gib auf Discord {command} in {server_channel} ein und sende die untenstehende PIN als DM an den Bot.",
|
||||
"sendPINDiscord": "Gib auf Discord {command} in {server_channel} ein und sende die untenstehende PIN.",
|
||||
"matrixEnterUser": "Gib deine Benutzer-ID ein und drücke auf Absenden. Anschließend erhälst du ein PIN, die hier eingegeben wird um fortzufahren."
|
||||
},
|
||||
"validationStrings": {
|
||||
@@ -53,6 +53,9 @@
|
||||
"errorMatrixVerification": "Matrix-Verifizierung erforderlich.",
|
||||
"errorUnknown": "Unbekannter Fehler.",
|
||||
"verified": "Konto verifiziert.",
|
||||
"errorNoEmail": "E-Mail Adresse erforderlich."
|
||||
"errorNoEmail": "E-Mail Adresse erforderlich.",
|
||||
"errorCaptcha": "Captcha falsch.",
|
||||
"errorPassword": "Prüfe die Passwortanforderungen.",
|
||||
"errorNoMatch": "Passwörter stimmen nicht überein."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"strings": {
|
||||
"confirmationRequired": "Email confirmation required",
|
||||
"createAccountHeader": "Create Account",
|
||||
"accountDetails": "Details",
|
||||
"emailAddress": "Email",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"reEnterPassword": "Re-enter Password",
|
||||
"createAccountButton": "Create Account",
|
||||
"passwordRequirementsHeader": "Password Requirements",
|
||||
"successHeader": "Success!",
|
||||
"pageTitle": "Create Jellyfin Account",
|
||||
"reEnterPasswordInvalid": "Passwords are not the same.",
|
||||
"confirmationRequiredMessage": "Please check your email inbox to verify your address.",
|
||||
"yourAccountIsValidUntil": "Your account will be valid until {date}.",
|
||||
"sendPIN": "Send the PIN below to the bot, then come back here to link your account.",
|
||||
"sendPINDiscord": "Type {command} in {server_channel} on Discord, then send the PIN below.",
|
||||
"matrixEnterUser": "Enter your User ID, press submit, and a PIN will be sent to you. Enter it here to continue."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUnknown": "Unknown error.",
|
||||
"verified": "Account verified.",
|
||||
"errorCaptcha": "Captcha incorrect.",
|
||||
"errorPassword": "Check password requirements.",
|
||||
"errorNoMatch": "Passwords don't match.",
|
||||
"errorTelegramVerification": "Telegram verification required.",
|
||||
"errorInvalidPIN": "PIN is invalid.",
|
||||
"errorUserExists": "User already exists.",
|
||||
"errorInvalidCode": "Invalid invite code.",
|
||||
"errorMatrixVerification": "Matrix verification required.",
|
||||
"errorDiscordVerification": "Discord verification required.",
|
||||
"errorNoEmail": "Email required."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Must have at least {n} character",
|
||||
"plural": "Must have at least {n} characters"
|
||||
},
|
||||
"number": {
|
||||
"plural": "Must have at least {n} numbers",
|
||||
"singular": "Must have at least {n} number"
|
||||
},
|
||||
"special": {
|
||||
"plural": "Must have at least {n} special characters",
|
||||
"singular": "Must have at least {n} special character"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Must have at least {n} uppercase character",
|
||||
"plural": "Must have at least {n} uppercase characters"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "Must have at least {n} lowercase character",
|
||||
"plural": "Must have at least {n} lowercase characters"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,8 @@
|
||||
"notifications": {
|
||||
"errorUserExists": "User already exists.",
|
||||
"errorInvalidCode": "Invalid invite code.",
|
||||
"errorAccountLinked": "Account already in use.",
|
||||
"errorEmailLinked": "Email already in use.",
|
||||
"errorTelegramVerification": "Telegram verification required.",
|
||||
"errorDiscordVerification": "Discord verification required.",
|
||||
"errorMatrixVerification": "Matrix verification required.",
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Español (ES)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Crear cuenta de Jellyfin",
|
||||
"pageTitle": "Crea una cuenta en Jellyfin",
|
||||
"createAccountHeader": "Crear una cuenta",
|
||||
"accountDetails": "Detalles",
|
||||
"emailAddress": "Correo electrónico",
|
||||
@@ -17,7 +17,7 @@
|
||||
"confirmationRequired": "Se requiere confirmación por correo electrónico",
|
||||
"confirmationRequiredMessage": "Por favor, revise la bandeja de entrada de su correo electrónico para verificar su dirección.",
|
||||
"yourAccountIsValidUntil": "Su cuenta será válida hasta el {date}.",
|
||||
"sendPINDiscord": "Escribe {command} en {server_channel} en Discord, luego envía el PIN a continuación a través de DM al bot.",
|
||||
"sendPINDiscord": "Escribe {command} en {server_channel} en Discord, luego envía el PIN a través de DM al bot.",
|
||||
"sendPIN": "Envíe el PIN a continuación al bot, luego regrese aquí para vincular su cuenta.",
|
||||
"matrixEnterUser": "Ingrese su ID de usuario, presione enviar y se le enviará un PIN. Ingrese aquí para continuar."
|
||||
},
|
||||
@@ -30,7 +30,10 @@
|
||||
"errorTelegramVerification": "Se requiere verificación de Telegram.",
|
||||
"errorInvalidPIN": "PIN inválido.",
|
||||
"errorMatrixVerification": "Se requiere verificación de Matrix.",
|
||||
"errorNoEmail": "Correo electrónico requerido."
|
||||
"errorNoEmail": "Correo electrónico requerido.",
|
||||
"errorCaptcha": "Captcha Incorrecto.",
|
||||
"errorPassword": "Requisitos para la contraseña.",
|
||||
"errorNoMatch": "Las contraseñas no coinciden."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Magyar (HU)"
|
||||
"name": "English (US)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Jellyfin fiók létrehozása",
|
||||
@@ -18,7 +18,7 @@
|
||||
"confirmationRequiredMessage": "Kérjük ellenőrizze az e-mail címére küldött üzenetet, a fiók ellenőrzéséhez.",
|
||||
"yourAccountIsValidUntil": "A fiókja eddig lesz érvényes: {date}.",
|
||||
"sendPIN": "Az alábbi kódot küldje el a botnak, majd itt csatolja össze a fiókját.",
|
||||
"sendPINDiscord": "Discordon haszánlja a {command} parancsot, a {server_channel} csatornában, majd küldje el a kódot a botnak privát üzenetben.",
|
||||
"sendPINDiscord": "Discordon haszánlja a {command} parancsot, a {server_channel} csatornában, majd írja be a PIN-t.",
|
||||
"matrixEnterUser": "Írja be a felhasználója azonosítóját majd nyomja meg a beküldés gombot. A kapott kódot ide írja be."
|
||||
},
|
||||
"notifications": {
|
||||
@@ -30,7 +30,10 @@
|
||||
"errorInvalidPIN": "A PIN-kód érvénytelen.",
|
||||
"errorUnknown": "Ismeretlen hiba.",
|
||||
"errorNoEmail": "E-mail szükséges.",
|
||||
"verified": "Fiók ellenőrizve."
|
||||
"verified": "Fiók ellenőrizve.",
|
||||
"errorPassword": "Ellenőrizze a jelszó követelményeket.",
|
||||
"errorCaptcha": "Hibás Captcha.",
|
||||
"errorNoMatch": "A jelszavak nem egyeznek."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
@@ -46,12 +49,12 @@
|
||||
"plural": "Legalább {n} kisbetüs karakter"
|
||||
},
|
||||
"number": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
"singular": "Tartalmaznia kell legalább {n} számot",
|
||||
"plural": "Legalább {n} számot kell tartalmazzon"
|
||||
},
|
||||
"special": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
"singular": "Legalább {n} speciális karaktert kell tartalmazzon",
|
||||
"plural": "Legalább {n} speciális karaktert kell tartalmazzon"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,11 +15,25 @@
|
||||
"passwordRequirementsHeader": "Persyaratan Kata Sandi",
|
||||
"successHeader": "Sukses!",
|
||||
"confirmationRequired": "Konfirmasi email diperlukan",
|
||||
"confirmationRequiredMessage": "Silakan periksa kotak masuk email Anda untuk memverifikasi alamat Anda."
|
||||
"confirmationRequiredMessage": "Silakan periksa kotak masuk email Anda untuk memverifikasi alamat Anda.",
|
||||
"sendPINDiscord": "Ketik {command} di {server_channel} pada Discord, lalu kirim PIN di bawah ini.",
|
||||
"yourAccountIsValidUntil": "Akun kamu berlaku hingga {date}.",
|
||||
"sendPIN": "Kirim PIN di bawah ini ke bot, lalu kembali kesini untuk menerima link ke akun kamu.",
|
||||
"matrixEnterUser": "Masukkan User ID kamu, tekan submit, nomor PIN akan dikirimkan ke kamu. Masukkan untuk melanjutkan."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Pengguna sudah ada.",
|
||||
"errorInvalidCode": "Kode undangan tidak valid."
|
||||
"errorInvalidCode": "Kode undangan tidak valid.",
|
||||
"errorDiscordVerification": "Butuh verifikasi pada Discord.",
|
||||
"errorUnknown": "Terjadi kesalahan.",
|
||||
"errorTelegramVerification": "Butuh verifikasi pada Telegram.",
|
||||
"errorInvalidPIN": "Kode PIN salah.",
|
||||
"errorCaptcha": "Captcha salah.",
|
||||
"errorPassword": "Perhatikan persyaratan password.",
|
||||
"errorNoMatch": "Password tidak sama.",
|
||||
"verified": "Akun terverifikasi.",
|
||||
"errorNoEmail": "Butuh Email.",
|
||||
"errorMatrixVerification": "Butuh verifikasi pada Matrix."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Italiano (IT)"
|
||||
"name": "Inglese (US)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Crea Un Account Jellyfin",
|
||||
"createAccountHeader": "Crea Un Account",
|
||||
"accountDetails": "Dettagli",
|
||||
"emailAddress": "Email",
|
||||
"username": "Nome utente",
|
||||
"username": "Username",
|
||||
"password": "Password",
|
||||
"reEnterPassword": "Riscrivi La Password",
|
||||
"reEnterPasswordInvalid": "Le password non sono uguali.",
|
||||
@@ -15,16 +15,21 @@
|
||||
"passwordRequirementsHeader": "Requisiti Password",
|
||||
"successHeader": "Successo!",
|
||||
"confirmationRequired": "Richiesta la conferma Email",
|
||||
"confirmationRequiredMessage": "Controlla la tua casella email per verificare il tuo indirizzo."
|
||||
"confirmationRequiredMessage": "Controlla la tua casella email per verificare il tuo indirizzo.",
|
||||
"yourAccountIsValidUntil": "Il tuo account sarà valido fino al {date}.",
|
||||
"sendPIN": "Scrivi il PIN qui sotto al bot, poi torna qui per connettere il tuo account.",
|
||||
"sendPINDiscord": "Scrivi {command} in {server_channel} su Discord, poi invia il PIN qui sotto.",
|
||||
"matrixEnterUser": "Inserisci il tuo ID utente, premi invia e ti verrò inviato un PIN. Inseriscilo qui per continuare."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "L'utente è già esistente.",
|
||||
"errorInvalidCode": "Codice di invito non valido."
|
||||
"errorInvalidCode": "Codice di invito non valido.",
|
||||
"errorTelegramVerification": "Verifica Telegram richiesta."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Deve avere almeno {n} caratteri",
|
||||
"plural": "Deve aveere almeno {n} caratteri"
|
||||
"plural": "Deve avere almeno {n} caratteri"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Deve avere almeno {n} carattere maiuscolo",
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
"yourAccountIsValidUntil": "Je account zal geldig zijn tot {date}.",
|
||||
"sendPIN": "Stuur onderstaande pincode naar de bot, en kom daarna hier terug om je account te koppelen.",
|
||||
"matrixEnterUser": "Voer je gebruikers ID in, druk op versturen, en er wordt je een pincode toegestuurd. Vul die hier in om door te gaan.",
|
||||
"sendPINDiscord": "Typ {command} in {server_channel} op Discord, stuur daarna onderstaande pincode via DM naar de bot."
|
||||
"sendPINDiscord": "Typ {command} in {server_channel} op Discord, stuur daarna onderstaande pincode."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
@@ -53,6 +53,9 @@
|
||||
"errorUnknown": "Onbekende fout.",
|
||||
"errorMatrixVerification": "Matrix-verificatie vereist.",
|
||||
"verified": "Account geverifieerd.",
|
||||
"errorNoEmail": "E-mail vereist."
|
||||
"errorNoEmail": "E-mail vereist.",
|
||||
"errorPassword": "Controleer wachtwoordeisen.",
|
||||
"errorNoMatch": "Wachtwoorden komen niet overeen.",
|
||||
"errorCaptcha": "Captcha incorrect."
|
||||
}
|
||||
}
|
||||
|
||||
60
lang/form/pl-PL.json
Normal file
60
lang/form/pl-PL.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Ustawienia - jfa-go",
|
||||
"createAccountHeader": "Utwórz Konto",
|
||||
"accountDetails": "Szczegóły",
|
||||
"emailAddress": "E-mail",
|
||||
"username": "Nazwa Użytkownika",
|
||||
"password": "Hasło",
|
||||
"reEnterPassword": "Powtórz Haslo",
|
||||
"reEnterPasswordInvalid": "Hasła się różnią.",
|
||||
"createAccountButton": "Utwórz Konto",
|
||||
"passwordRequirementsHeader": "Wymagane Hasło",
|
||||
"successHeader": "Sukces!",
|
||||
"confirmationRequired": "Potwierdź email",
|
||||
"confirmationRequiredMessage": "Sprawdź swoją skrzynkę pocztową aby zweryfikować adres.",
|
||||
"yourAccountIsValidUntil": "Twoje konto pozostanie aktywne do {date}.",
|
||||
"sendPIN": "Wyślij poniższy kod PIN do bota, a następnie wróć tutaj, aby połączyć swoje konto.",
|
||||
"sendPINDiscord": "Wpisz {command} w {server_channel} na Discordzie, a następnie wpisz kod PIN poniżej.",
|
||||
"matrixEnterUser": "Wprowadź swój identyfikator użytkownika, naciśnij Prześlij, a kod PIN zostanie wysłany do Ciebie. Wpisz go tutaj, aby kontynuować."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Nazwa użytkownika zajęta.",
|
||||
"errorInvalidCode": "Błędny kod zaproszenia.",
|
||||
"errorTelegramVerification": "Wymagana weryfikacja Telegram.",
|
||||
"errorDiscordVerification": "Wymagana weryfikacja Discord.",
|
||||
"errorMatrixVerification": "Wymagana weryfikacja Matrix.",
|
||||
"errorInvalidPIN": "Błędny kod PIN.",
|
||||
"errorUnknown": "Nieznany błąd.",
|
||||
"errorNoEmail": "Wymagany adres email.",
|
||||
"errorCaptcha": "Błędnie rozwiązana captcha.",
|
||||
"errorPassword": "Sprawdź wymagania dotyczące hasła.",
|
||||
"errorNoMatch": "Hasła się różnią.",
|
||||
"verified": "Konto zweryfikowane."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Musisz użyć przynajmniej {n} znaków",
|
||||
"plural": "Musisz użyć przynajmniej {n} znak"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Musisz użyć co najmniej {n} wielkich liter",
|
||||
"plural": "Musisz użyć co najmniej {n} wielkich liter"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "Musisz użyć co najmniej {n} małych liter",
|
||||
"plural": "Musisz użyć co najmniej {n} małych liter"
|
||||
},
|
||||
"number": {
|
||||
"singular": "Musisz użyć co najmniej {n} liczbę",
|
||||
"plural": "Musisz użyć co najmniej {n} liczb"
|
||||
},
|
||||
"special": {
|
||||
"singular": "Musisz użyć co najmniej {n} znak specjalny",
|
||||
"plural": "Musisz użyć co najmniej {n} znaków specjalnych"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@
|
||||
"pageTitle": "Criar Conta Jellyfin",
|
||||
"createAccountHeader": "Criar Conta",
|
||||
"accountDetails": "Detalhes",
|
||||
"emailAddress": "Email",
|
||||
"emailAddress": "E-mail",
|
||||
"username": "Nome do Usuário",
|
||||
"password": "Senha",
|
||||
"reEnterPassword": "Digite a Senha Novamente",
|
||||
@@ -18,7 +18,7 @@
|
||||
"confirmationRequiredMessage": "Verifique sua caixa de email para finalizar o cadastro.",
|
||||
"yourAccountIsValidUntil": "Sua conta é válida até {date}.",
|
||||
"sendPIN": "Envie o PIN abaixo para o bot e volte aqui para vincular sua conta.",
|
||||
"sendPINDiscord": "Digite {command} em {server_channel} no Discord e envie o PIN abaixo via DM para o bot.",
|
||||
"sendPINDiscord": "Digite {command} em {server_channel} no Discord e envie o PIN abaixo.",
|
||||
"matrixEnterUser": "Digite sua ID de usuário, pressione enviar e um PIN será enviado. E digite aqui para continuar."
|
||||
},
|
||||
"notifications": {
|
||||
@@ -30,7 +30,11 @@
|
||||
"errorDiscordVerification": "Necessária verificação pelo Discord.",
|
||||
"errorMatrixVerification": "Necessária verificação Matrix.",
|
||||
"errorUnknown": "Erro desconhecido.",
|
||||
"verified": "Conta verificada."
|
||||
"verified": "Conta verificada.",
|
||||
"errorNoEmail": "Email necessário.",
|
||||
"errorCaptcha": "Captcha incorreto.",
|
||||
"errorPassword": "Verifique os requisitos de senha.",
|
||||
"errorNoMatch": "As senhas não coincidem."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
60
lang/form/ro-RO.json
Normal file
60
lang/form/ro-RO.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Română (ROU)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Crează un Cont Jellyfin",
|
||||
"createAccountHeader": "Înregistrare",
|
||||
"accountDetails": "Detalii",
|
||||
"emailAddress": "Email",
|
||||
"username": "Utilizator",
|
||||
"password": "Parolă",
|
||||
"reEnterPassword": "Reintroduce Parola",
|
||||
"reEnterPasswordInvalid": "Parolele nu sunt la fel.",
|
||||
"createAccountButton": "Înregistrare",
|
||||
"passwordRequirementsHeader": "Cerințe Parolă",
|
||||
"successHeader": "Succes!",
|
||||
"confirmationRequired": "Necesară confirmarea emailului",
|
||||
"confirmationRequiredMessage": "Vă rugăm să vă verificați căsuța de e-mail pentru a vă verifica adresa.",
|
||||
"yourAccountIsValidUntil": "Contul dvs. va fi valabil până la {date}.",
|
||||
"sendPIN": "Trimiteți codul PIN de mai jos botului, apoi reveniți aici pentru a vă conecta contul.",
|
||||
"sendPINDiscord": "Scrie {command} în {server_channel} pe Discord, apoi trimite codul PIN de mai jos.",
|
||||
"matrixEnterUser": "Introduceți ID-ul dvs. de utilizator, apăsați pe trimitere și vi se va trimite un PIN. Introduceți-l aici pentru a continua."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Utilizatorul deja există.",
|
||||
"errorInvalidCode": "Cod de invitație nevalid.",
|
||||
"errorTelegramVerification": "Este necesară verificarea pe Telegram.",
|
||||
"errorDiscordVerification": "Este necesară verificarea pe Discord.",
|
||||
"errorMatrixVerification": "Este necesară verificarea pe Matrix.",
|
||||
"errorInvalidPIN": "PIN-ul este invalid.",
|
||||
"errorUnknown": "Eroare necunoscută.",
|
||||
"errorNoEmail": "E-mail necesar.",
|
||||
"errorCaptcha": "Captcha incorect.",
|
||||
"errorPassword": "Verificați cerințele privind parola.",
|
||||
"errorNoMatch": "Parolele nu se potrivesc.",
|
||||
"verified": "Cont verificat."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Trebuie să aibă cel puțin {n} caracter",
|
||||
"plural": "Trebuie să aibă cel puțin {n} caractere"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Trebuie să aibă cel puțin {n} literă mare",
|
||||
"plural": "Trebuie să aibă cel puțin {n} litere mari"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "Trebuie să aibă cel puțin {n} literă mică",
|
||||
"plural": "Trebuie să aibă cel puțin {n} litere mici"
|
||||
},
|
||||
"number": {
|
||||
"singular": "Trebuie să aibă cel puțin {n} număr",
|
||||
"plural": "Trebuie să aibă cel puțin {n} numere"
|
||||
},
|
||||
"special": {
|
||||
"singular": "Trebuie să aibă cel puțin {n} caracter special",
|
||||
"plural": "Trebuie să aibă cel puțin {n} caractere speciale"
|
||||
}
|
||||
}
|
||||
}
|
||||
60
lang/form/sl-si.json
Normal file
60
lang/form/sl-si.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Angleščina (ZDA)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Ustvari Jellyfin Račun",
|
||||
"createAccountHeader": "Ustvari Račun",
|
||||
"accountDetails": "Podrobnosti",
|
||||
"emailAddress": "E-pošta",
|
||||
"username": "Uporabniško ime",
|
||||
"password": "Geslo",
|
||||
"reEnterPassword": "Ponovno vnesi Geslo",
|
||||
"reEnterPasswordInvalid": "Gesli se ne ujemata.",
|
||||
"createAccountButton": "Ustvari Račun",
|
||||
"passwordRequirementsHeader": "Zahteve za geslo",
|
||||
"successHeader": "Uspeh!",
|
||||
"confirmationRequired": "Potrebna potrditev e-pošte",
|
||||
"confirmationRequiredMessage": "Prosimo preverite svojo e-pošto da potrdite račun.",
|
||||
"yourAccountIsValidUntil": "Vaš račun bo veljaven do {date}.",
|
||||
"sendPIN": "Pošljite spodnji PIN botu, nato pa pridite nazaj da povežete svoj račun.",
|
||||
"sendPINDiscord": "Napišite {command} v {server_channel} na Discordu, nato pa vnesite PIN spodaj.",
|
||||
"matrixEnterUser": "Vnesite svoj uporabniški ID, pritisnite potrdi, in poslan vam bo PIN. Tega vnesite tu, da nadaljujete."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Uporabnik že obstaja.",
|
||||
"errorInvalidCode": "Neveljavna koda povabila.",
|
||||
"errorTelegramVerification": "Potrebna je potrditev preko telegrama.",
|
||||
"errorDiscordVerification": "Potrebna je potrditev preko Discorda.",
|
||||
"errorMatrixVerification": "Potrebna je potrditev preko Matrix.",
|
||||
"errorInvalidPIN": "PIN ni veljaven.",
|
||||
"errorUnknown": "Neznana napaka.",
|
||||
"errorNoEmail": "E-pošta obvezna.",
|
||||
"errorCaptcha": "Captcha je nepravilna.",
|
||||
"errorPassword": "Prosimo preverite zahteve za geslo.",
|
||||
"errorNoMatch": "Gesli se ne ujemata.",
|
||||
"verified": "Račun potrjen."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Potrebnih je vsaj {n} znakov",
|
||||
"plural": "Potrebnih je vsaj {n} znakov"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Potreben je vsaj {n} velik znak",
|
||||
"plural": "Potrebnih je vsaj {n} velikih znakov"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "Potreben je vsaj {n} majhen znak",
|
||||
"plural": "Potrebnih je vsaj {n} majhnih znakov"
|
||||
},
|
||||
"number": {
|
||||
"singular": "Potrebna je vsaj {n} števka",
|
||||
"plural": "Potrebnih je vsaj {n} števk"
|
||||
},
|
||||
"special": {
|
||||
"singular": "Poteben je vsaj {n} poseben znak",
|
||||
"plural": "Potrebnih je vsaj {n} posebnih znakov"
|
||||
}
|
||||
}
|
||||
}
|
||||
60
lang/form/vi-VN.json
Normal file
60
lang/form/vi-VN.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Tiếng Anh (Mỹ)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Tạo tài khoản Jellyfin",
|
||||
"createAccountHeader": "Tạo tài khoản",
|
||||
"accountDetails": "Chi tiết",
|
||||
"emailAddress": "Email",
|
||||
"username": "Tên đăng nhập",
|
||||
"password": "Mật khẩu",
|
||||
"reEnterPassword": "Nhập lại mật khẩu",
|
||||
"reEnterPasswordInvalid": "Mật khẩu không giống nhau.",
|
||||
"createAccountButton": "Tạo tài khoản",
|
||||
"passwordRequirementsHeader": "Yêu cầu mật khẩu",
|
||||
"successHeader": "Thành công!",
|
||||
"confirmationRequired": "Cần xác nhận email",
|
||||
"confirmationRequiredMessage": "Hãy kiểm tra email của bạn để xác minh địa chỉ email.",
|
||||
"yourAccountIsValidUntil": "",
|
||||
"sendPIN": "",
|
||||
"sendPINDiscord": "",
|
||||
"matrixEnterUser": ""
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "",
|
||||
"errorInvalidCode": "",
|
||||
"errorTelegramVerification": "",
|
||||
"errorDiscordVerification": "",
|
||||
"errorMatrixVerification": "",
|
||||
"errorInvalidPIN": "",
|
||||
"errorUnknown": "",
|
||||
"errorNoEmail": "",
|
||||
"errorCaptcha": "",
|
||||
"errorPassword": "",
|
||||
"errorNoMatch": "",
|
||||
"verified": ""
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"number": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
},
|
||||
"special": {
|
||||
"singular": "",
|
||||
"plural": ""
|
||||
}
|
||||
}
|
||||
}
|
||||
60
lang/form/zh-Hant.json
Normal file
60
lang/form/zh-Hant.json
Normal file
@@ -0,0 +1,60 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "創建 Jellfin 帳戶",
|
||||
"createAccountHeader": "創建帳戶",
|
||||
"accountDetails": "詳細資訊",
|
||||
"emailAddress": "電子郵件",
|
||||
"username": "帳戶名稱",
|
||||
"password": "密碼",
|
||||
"reEnterPassword": "重新輸入密碼",
|
||||
"reEnterPasswordInvalid": "密碼不一樣。",
|
||||
"createAccountButton": "創建帳戶",
|
||||
"passwordRequirementsHeader": "密碼格式要求",
|
||||
"successHeader": "成功!",
|
||||
"confirmationRequired": "需要電子郵件確認",
|
||||
"confirmationRequiredMessage": "請檢查您的電子郵件收件匣以驗證您的地址。",
|
||||
"yourAccountIsValidUntil": "您的帳戶有效期至 {date}。",
|
||||
"sendPIN": "將下面的 PIN 碼發送給機器人,然後返回此處連結您的帳戶。",
|
||||
"sendPINDiscord": "在 Discord 上的 {server_channel} 中輸入 {command},然後發送下方的 PIN 碼。",
|
||||
"matrixEnterUser": "輸入您的帳戶 ID 並點擊提交。在此處輸入發送給您的PIN 碼以繼續。"
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "帳戶已存在。",
|
||||
"errorInvalidCode": "邀請碼無效。",
|
||||
"errorTelegramVerification": "需要 Telegram 驗證。",
|
||||
"errorDiscordVerification": "需要 Discord 驗證。",
|
||||
"errorMatrixVerification": "需要 Matrix 驗證。",
|
||||
"errorInvalidPIN": "無效的PIN碼。",
|
||||
"errorUnknown": "未知的錯誤。",
|
||||
"errorNoEmail": "電子郵件必填。",
|
||||
"errorCaptcha": "CAPTCHA 驗證碼不正確。",
|
||||
"errorPassword": "請您檢查密碼要求後再試。",
|
||||
"errorNoMatch": "密碼不匹配。",
|
||||
"verified": "帳戶已驗證。"
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "必須至少包含 {n} 個字元",
|
||||
"plural": "必須至少包含 {n} 個字元"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "必須至少包含 {n} 個大寫字母",
|
||||
"plural": "必須至少包含 {n} 個大寫字母"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "必須至少包含 {n} 個小寫字母",
|
||||
"plural": "必須至少包含 {n} 個小寫字母"
|
||||
},
|
||||
"number": {
|
||||
"singular": "必須至少包含 {n} 個數字",
|
||||
"plural": "必須至少包含 {n} 個數字"
|
||||
},
|
||||
"special": {
|
||||
"singular": "必須至少包含 {n} 個特殊字元",
|
||||
"plural": "必須至少包含 {n} 個特殊字元"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,19 +17,23 @@
|
||||
"confirmationRequired": "需要邮件确认",
|
||||
"confirmationRequiredMessage": "请登录您的邮箱收件箱来验证您的地址。",
|
||||
"yourAccountIsValidUntil": "您的账户将在 {date} 之前有效。",
|
||||
"sendPIN": "把PIN码发送给下面的bot,然后回到这里来关联您的账户。",
|
||||
"sendPINDiscord": "在 Discord 上,在 {server_channel} 中输入 {command} 并将下面的 PIN 码作为 DM 发送给机器人。",
|
||||
"sendPIN": "把下面的PIN码发给机器人,然后回到这页绑定您的账户。",
|
||||
"sendPINDiscord": "在Discord {server_channel} 频道中,输入 {command} 并将下面的PIN码。",
|
||||
"matrixEnterUser": "输入您的用户ID并点击提交,将发送给您的PIN码输入到这里并继续。"
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "用户已经存在。",
|
||||
"errorInvalidCode": "无效的邀请码",
|
||||
"errorTelegramVerification": "需要Telegram验证",
|
||||
"errorInvalidCode": "无效的邀请码。",
|
||||
"errorTelegramVerification": "需要Telegram验证码。",
|
||||
"errorDiscordVerification": "需要Discord验证。",
|
||||
"errorMatrixVerification": "需要Matrix验证。",
|
||||
"errorInvalidPIN": "无效的PIN码",
|
||||
"errorInvalidPIN": "无效的PIN码。",
|
||||
"errorUnknown": "未知错误。",
|
||||
"verified": "账户已验证。"
|
||||
"verified": "账户已验证。",
|
||||
"errorNoEmail": "必要输入电邮地址。",
|
||||
"errorCaptcha": "验证码不对。",
|
||||
"errorPassword": "请您检查密码要求再试。",
|
||||
"errorNoMatch": "密码不匹配。"
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
16
lang/pwreset/ar-aa.json
Normal file
16
lang/pwreset/ar-aa.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "العربية (AR)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "إعادة تعيين كلمة المرور",
|
||||
"reset": "إعادة تعيين",
|
||||
"resetFailed": "فشل إعادة تعيين كلمة المرور",
|
||||
"tryAgain": "حاول مرة اخرى.",
|
||||
"youCanLogin": "يمكنك الآن تسجيل الدخول باستخدام الرمز أدناه ككلمة المرور الخاصة بك.",
|
||||
"youCanLoginOmbi": "يمكنك الآن تسجيل الدخول باستخدام الرمز أدناه ككلمة المرور الخاصة بك.",
|
||||
"youCanLoginPassword": "يمكنك الآن تسجيل الدخول باستخدام الرمز أدناه ككلمة المرور الخاصة بك.",
|
||||
"changeYourPassword": "تأكد من تغيير كلمة المرور الخاصة بك بعد تسجيل الدخول.",
|
||||
"enterYourPassword": "أدخل كلمة المرور الجديدة أدناه."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
"tryAgain": "Bitte versuche es erneut.",
|
||||
"youCanLogin": "Du kannst dich nun mit dem unten stehenden Code als Passwort anmelden.",
|
||||
"youCanLoginOmbi": "Du kannst dich jetzt bei Jellyfin und Ombi mit dem unten stehenden Code als Passwort anmelden.",
|
||||
"changeYourPassword": "Achte darauf, dass du dein Passwort nach der Anmeldung änderst."
|
||||
"changeYourPassword": "Vergiss nicht, dein Passwort nach der Anmeldung zu ändern.",
|
||||
"youCanLoginPassword": "Du kannst dich nun mit deinem neuen Passwort anmelden. Klicke unten um zu Jellyfin zu gehen.",
|
||||
"reset": "Zurücksetzen",
|
||||
"enterYourPassword": "Gib unten dein neues Passwort ein."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"strings": {
|
||||
"youCanLoginOmbi": "You can now log in to Jellyfin & Ombi with the below code as your password.",
|
||||
"passwordReset": "Password reset",
|
||||
"resetFailed": "Password reset failed",
|
||||
"tryAgain": "Please try again.",
|
||||
"youCanLogin": "You can now log in with the below code as your password.",
|
||||
"changeYourPassword": "Make sure to change your password after you log in.",
|
||||
"reset": "Reset",
|
||||
"enterYourPassword": "Enter your new password below.",
|
||||
"youCanLoginPassword": "You can now login with your new password. Press below to continue to Jellyfin."
|
||||
}
|
||||
}
|
||||
|
||||
16
lang/pwreset/pl-PL.json
Normal file
16
lang/pwreset/pl-PL.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Zresetuj hasło",
|
||||
"reset": "Zresetuj",
|
||||
"resetFailed": "Hasło nie zostało zrestartowane",
|
||||
"tryAgain": "Spróbuj ponownie.",
|
||||
"youCanLogin": "Możesz się teraz zalogować używając kodu jako hasła.",
|
||||
"youCanLoginOmbi": "Możesz się teraz zalogować do Jellyfin & Ombi używając poniższego kodu jako swojego hasła.",
|
||||
"youCanLoginPassword": "Możesz się teraz zalogować przy użyciu swojego nowego hasła. Naciśnij poniżej aby przejść do Jellyfin.",
|
||||
"changeYourPassword": "Upewnij się, że zmieniłeś swoje hasło po zalogowaniu.",
|
||||
"enterYourPassword": "Podaj swoje hasło poniżej."
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,9 @@
|
||||
"tryAgain": "Tente novamente.",
|
||||
"youCanLogin": "Agora você pode fazer login com o código abaixo como senha.",
|
||||
"youCanLoginOmbi": "Agora você pode fazer login no Jellyfin & Ombi com o código abaixo como senha.",
|
||||
"changeYourPassword": "Certifique-se de alterar sua senha depois de fazer o login."
|
||||
"changeYourPassword": "Certifique-se de alterar sua senha depois de fazer o login.",
|
||||
"reset": "Redefinir",
|
||||
"enterYourPassword": "Digite sua nova senha abaixo.",
|
||||
"youCanLoginPassword": "Agora você pode fazer login com sua nova senha. Pressione abaixo para continuar até Jellyfin."
|
||||
}
|
||||
}
|
||||
|
||||
16
lang/pwreset/ro-RO.json
Normal file
16
lang/pwreset/ro-RO.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Română (ROU)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Resetare parolă",
|
||||
"reset": "Resetare",
|
||||
"resetFailed": "Resetarea parolei a eșuat",
|
||||
"tryAgain": "Te rugăm să încerci din nou.",
|
||||
"youCanLogin": "Acum vă puteți autentifica cu codul de mai jos ca parolă.",
|
||||
"youCanLoginOmbi": "Vă puteți conecta acum la Jellyfin & Ombi cu codul de mai jos ca parolă.",
|
||||
"youCanLoginPassword": "Acum vă puteți autentifica cu noua parolă. Apăsați mai jos pentru a continua spre Jellyfin.",
|
||||
"changeYourPassword": "Asigurați-vă că vă schimbați parola după ce vă conectați.",
|
||||
"enterYourPassword": "Introduceți noua parolă mai jos."
|
||||
}
|
||||
}
|
||||
16
lang/pwreset/sl-si.json
Normal file
16
lang/pwreset/sl-si.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Angleščina (ZDA)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Ponastavitev gesla",
|
||||
"reset": "Ponastavi",
|
||||
"resetFailed": "Ponastavitev gesla neuspešna",
|
||||
"tryAgain": "Prosimo poskusite ponovno.",
|
||||
"youCanLogin": "Sedaj se lahko prijavite s spodnjo kodo kot svojim geslom.",
|
||||
"youCanLoginOmbi": "Sedaj se lahko prijavite v Jellyfin in Ombi s spodnjo kodo kot svojim geslom.",
|
||||
"youCanLoginPassword": "Sedaj se lahko prijavite s svojim novim geslom. Pritisnite spodnji gumb da nadaljujete na Jellyfin.",
|
||||
"changeYourPassword": "Spremenite svoje geslo po prijavi.",
|
||||
"enterYourPassword": "Vnesite svoje novo geslo spodaj."
|
||||
}
|
||||
}
|
||||
16
lang/pwreset/zh-Hant.json
Normal file
16
lang/pwreset/zh-Hant.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "重設密碼",
|
||||
"reset": "重設",
|
||||
"resetFailed": "重設密碼失敗",
|
||||
"tryAgain": "請重試。",
|
||||
"youCanLogin": "您現在可以使用下方的代碼作為您的密碼登錄。",
|
||||
"youCanLoginOmbi": "您現在可以使用下方的代碼作為您的密碼登錄 Jellyfin和Ombi。",
|
||||
"youCanLoginPassword": "您現在可以使用新密碼登錄。 請按下方按鈕跳轉至 Jellyfin。",
|
||||
"changeYourPassword": "請務必在登錄后更改密碼。",
|
||||
"enterYourPassword": "在下方輸入您的新密碼。"
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
"youCanLogin": "您现在可以使用下面的代码作为您的密码进行登录。",
|
||||
"youCanLoginOmbi": "您现在可以使用下面的代码作为您的密码登录Jellyfin和Ombi。",
|
||||
"changeYourPassword": "确保在登录状态下修改您的密码。",
|
||||
"enterYourPassword": "在下面输入您的新密码。"
|
||||
"enterYourPassword": "在下面输入您的新密码。",
|
||||
"youCanLoginPassword": "您现在可以使用新密码登录。请按下面按钮跳转到Jellyfin。"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"errorNotAdmin": "Brugeren har ikke tilladelse til at administrere server.",
|
||||
"errorInvalidUserPass": "Ugyldigt brugernavn/adgangskode.",
|
||||
"errorUserDisabled": "Bruger kan være deaktiveret.",
|
||||
"error404": "404, tjek den interne URL."
|
||||
"error404": "404, tjek den interne URL.",
|
||||
"errorConnectionRefused": "Tilslutning afvist."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Velkommen!",
|
||||
@@ -65,7 +66,9 @@
|
||||
"authorizeWithJellyfin": "Autoriser med Jellyfin/Emby: Loginoplysninger deles med Jellyfin, hvilket giver mulighed for flere brugere.",
|
||||
"authorizeManual": "Brugernavn og adgangskode: indtast brugernavn og adgangskode manuelt.",
|
||||
"adminOnly": "Kun administratorbrugere (anbefalet)",
|
||||
"emailNotice": "Din e-mail adresse kan bruges til at modtage underretninger."
|
||||
"emailNotice": "Din e-mail adresse kan bruges til at modtage underretninger.",
|
||||
"allowAll": "Tillad alle Jellyfin brugere at logge ind",
|
||||
"allowAllDescription": "Det anbefales ikke, du bør tillade individuelle brugere at logge ind, når de er konfigureret."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
|
||||
@@ -15,7 +15,12 @@
|
||||
"serverAddress": "Serveradresse",
|
||||
"emailSubject": "E-Mail-Betreff",
|
||||
"URL": "URL",
|
||||
"apiKey": "API-Schlüssel"
|
||||
"apiKey": "API-Schlüssel",
|
||||
"errorInvalidUserPass": "Benutzername/Passwort ungültig.",
|
||||
"errorNotAdmin": "Dieser Benutzer darf den Server nicht verwalten.",
|
||||
"errorUserDisabled": "Konto ist eventuell deaktiviert.",
|
||||
"error404": "404, prüfe die interne URL.",
|
||||
"errorConnectionRefused": "Verbindung abgelehnt."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Willkommen!",
|
||||
@@ -25,7 +30,7 @@
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Fertig!",
|
||||
"restartMessage": "Es gibt weitere Einstellungen, die du auf der Admin-Seite konfigurieren kannst. Klicke unten, um neu zu starten, dann aktualisiere die Seite.",
|
||||
"restartMessage": "In den Einstellungen kannst du Discord/Telegram/Matrix Bots konfigurieren, Benachrichtigungen anpassen und vieles mehr. Klicke unten, um neu zu starten, aktualisiere dann die Seite.",
|
||||
"refreshPage": "Aktualisieren"
|
||||
},
|
||||
"language": {
|
||||
@@ -54,7 +59,9 @@
|
||||
"authorizeWithJellyfin": "Mit Jellyfin/Emby autorisieren: Anmeldedaten werden mit Jellyfin geteilt, was mehrere Benutzer ermöglicht.",
|
||||
"authorizeManual": "Benutzername und Passwort: Lege Benutzername und Passwort manuell fest.",
|
||||
"adminOnly": "Nur Admin-Benutzer (empfohlen)",
|
||||
"emailNotice": "Deine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten."
|
||||
"emailNotice": "Deine E-Mail-Adresse kann verwendet werden, um Benachrichtigungen zu erhalten.",
|
||||
"allowAll": "Erlaube allen Jellyfin-Nutzern sich anzumelden",
|
||||
"allowAllDescription": "Nicht empfohlen. Nach der Einrichtung solltest du einzelnen Benutzern erlauben, sich anzumelden."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
@@ -86,16 +93,16 @@
|
||||
"mailgunApiURL": "API-URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Benachrichtigungen",
|
||||
"description": "Wenn aktiviert, kannst du (pro Invite) wählen, eine E-Mail zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast."
|
||||
"title": "Admin-Benachrichtigungen",
|
||||
"description": "Wenn aktiviert, kannst du (pro Invite) wählen, eine Benachrichtigung zu erhalten, wenn ein Invite abläuft oder ein Benutzer erstellt wird. Wenn du nicht die Jellyfin-Login-Methode gewählt hast, stelle sicher, dass du deine E-Mail-Adresse angegeben hast, oder füge später eine andere Kontaktmöglichkeit hinzu."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Willkommens-E-Mails",
|
||||
"description": "Wenn aktiviert, wird eine E-Mail an neue Benutzer gesendet mit der Jellyfin-/Emby-URL und ihrem Benutzername."
|
||||
"title": "Willkommens-Benachrichtigungen",
|
||||
"description": "Wenn aktiviert, wird eine Benachrichtigung mit der Jellyfin-/Emby-URL und dem Benutzernamen an neue Benutzer gesendet."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Einladungs-E-Mails",
|
||||
"description": "Wenn aktiviert, kannst du Invites direkt an die E-Mail-Adresse eines Benutzers schicken. Weil du möglicherweise einen Reverse-Proxy verwendest, musst du die URL angeben, von welcher auf Invites zugegriffen wird. Schreibe deine URL-Basis, und füge '/invite' hinzu."
|
||||
"title": "Einladungs-Benachrichtigungen",
|
||||
"description": "Wenn aktiviert, kannst du Invites direkt an die E-Mail-Adresse oder das Discord-/Matrix-Konto eines Benutzers schicken. Weil du möglicherweise einen Reverse-Proxy verwendest, musst du die URL angeben, von welcher auf Invites zugegriffen wird. Schreibe deine URL-Basis, und füge '/invite' hinzu."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Passwortzurücksetzungen",
|
||||
@@ -104,7 +111,9 @@
|
||||
"pathToJellyfinNotice": "Wenn du nicht weißt, wo das ist, versuche dein Passwort in Jellyfin zurückzusetzen. Ein Popup mit '<Pfad zu Jellyfin>/passwordreset-*.json' wird angezeigt werden.",
|
||||
"resetLinks": "Einen Link statt einer PIN senden",
|
||||
"resetLinksNotice": "Wenn die Ombi-Integration aktiviert ist, verwende dies, um zurückgesetzte Passwörter von Jellyfin mit Ombi zu synchronisieren.",
|
||||
"resetLinksLanguage": "Standardsprache für den Link zum Zurücksetzen des Passworts"
|
||||
"resetLinksLanguage": "Standardsprache für den Link zum Zurücksetzen des Passworts",
|
||||
"setPassword": "Setze Password durch Link",
|
||||
"setPasswordNotice": "Wenn aktiviert, muss der Benutzer sein Passwort nicht über eine PIN ändern. So wird ebenfalls die Passwortvalidierung erzwungen."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Passwortüberprüfung",
|
||||
@@ -133,5 +142,9 @@
|
||||
"stable": "Stable",
|
||||
"title": "Aktualisierungen",
|
||||
"description": "Aktiviere, um informiert zu werden, wenn neue Aktualisierungen verfügbar sind. jfa-go wird {n} alle 30 Minuten überprüfen. Keine IP-Adressen oder personenbezogene Daten werden gesammelt."
|
||||
},
|
||||
"messages": {
|
||||
"title": "Mitteilungen",
|
||||
"description": "jfa-go kann Passwortrücksetzungen und verschiedene Benachrichtigungen per E-Mail, Discord, Telegram und/oder Matrix verschicken. E-Mail kannst du unten einrichten, die Anderen später in den Einstellungen. Anweisungen findest du im {n}. Falls nicht benötigt, kannst du diese Funktionen hier deaktivieren."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,150 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"special": "Special characters (%, *, etc.)",
|
||||
"numbers": "Numbers",
|
||||
"title": "Password Validation",
|
||||
"lowercase": "Lowercase characters",
|
||||
"length": "Length",
|
||||
"uppercase": "Uppercase characters",
|
||||
"description": "If enabled, a set of password requirements will show on the account creation page, such as minimum length, uppercase/lowercase characters, etc."
|
||||
},
|
||||
"email": {
|
||||
"method": "Sending method",
|
||||
"dateFormat": "Date Format",
|
||||
"useEmailAsUsername": "Use email addresses as username",
|
||||
"useEmailAsUsernameNotice": "If enabled, new users will login to Jellyfin/Emby with their email address instead of a username.",
|
||||
"title": "Email",
|
||||
"fromAddress": "From Address",
|
||||
"senderName": "Sender Name",
|
||||
"encryption": "Encryption",
|
||||
"mailgunApiURL": "API URL",
|
||||
"description": "jfa-go can send password reset PINs and various notifications through email. You can connect to an SMTP server, or use the {n} API.",
|
||||
"dateFormatNotice": "Date follows the strftime format. For more info, visit {n}."
|
||||
},
|
||||
"passwordResets": {
|
||||
"resetLinks": "Send a link instead of a PIN",
|
||||
"setPassword": "Set password through link",
|
||||
"resetLinksNotice": "If Ombi integration is enabled, use this to sync Jellyfin password resets with Ombi.",
|
||||
"title": "Password Resets",
|
||||
"description": "When a user tries to reset their password, Jellyfin creates a file named 'passwordreset-*.json' which contains a PIN. jfa-go reads the file and sends the PIN to the user.",
|
||||
"pathToJellyfin": "Path to Jellyfin configuration directory",
|
||||
"pathToJellyfinNotice": "If you don't know where this is, try resetting your password in Jellyfin. A popup with '<path to jellyfin>/passwordreset-*.json' will appear.",
|
||||
"resetLinksLanguage": "Default reset link language",
|
||||
"setPasswordNotice": "Enabling this means the user doesn't have to change their password from the PIN after the reset. Password validation will also be enforced."
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "Help Messages",
|
||||
"description": "These messages will display in the account creation page and in some emails.",
|
||||
"contactMessage": "Contact Message",
|
||||
"contactMessageNotice": "Displays at the bottom of all pages except admin.",
|
||||
"helpMessage": "Help Message",
|
||||
"helpMessageNotice": "Displays on the account creation page.",
|
||||
"successMessage": "Success Message",
|
||||
"successMessageNotice": "Displays when a user creates their account.",
|
||||
"emailMessage": "Email Message",
|
||||
"emailMessageNotice": "Displays at the bottom of emails."
|
||||
},
|
||||
"strings": {
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"next": "Next",
|
||||
"back": "Back",
|
||||
"optional": "Optional",
|
||||
"serverType": "Server Type",
|
||||
"port": "Port",
|
||||
"serverAddress": "Server Address",
|
||||
"emailSubject": "Email Subject",
|
||||
"URL": "URL",
|
||||
"apiKey": "API Key",
|
||||
"errorUserDisabled": "User may be disabled.",
|
||||
"error404": "404, check the internal URL.",
|
||||
"message": "Message",
|
||||
"pageTitle": "Setup - jfa-go",
|
||||
"errorInvalidUserPass": "Invalid username/password.",
|
||||
"errorNotAdmin": "User is not allowed to manage server.",
|
||||
"errorConnectionRefused": "Connection refused."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Welcome!",
|
||||
"httpsNotice": "Make sure you're accessing this page via HTTPS or on a private network.",
|
||||
"start": "Start",
|
||||
"pressStart": "You'll need to do a few things to set up jfa-go. Press start to continue."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
"embyNotice": "Emby support is limited and does not support password resets.",
|
||||
"internal": "Internal",
|
||||
"external": "External",
|
||||
"description": "An admin account is needed because the API does not allow user creation using an API key. You should create a separate account and check 'Allow this user to manage the server'. You can disable everything else. Once done, enter the login details here.",
|
||||
"replaceJellyfin": "Server name",
|
||||
"replaceJellyfinNotice": "If given, this will replace any occurrence of 'Jellyfin' in the app.",
|
||||
"addressExternalNotice": "Leave blank to use the same address.",
|
||||
"testConnection": "Test Connection"
|
||||
},
|
||||
"endPage": {
|
||||
"refreshPage": "Refresh",
|
||||
"finished": "Finished!",
|
||||
"restartMessage": "You can configure Discord/Telegram/Matrix bots, customise your messages and more in Settings. Click below to restart, then refresh the page."
|
||||
},
|
||||
"language": {
|
||||
"title": "Language",
|
||||
"defaultAdminLang": "Default admin language",
|
||||
"defaultFormLang": "Default account creation language",
|
||||
"defaultEmailLang": "Default email language",
|
||||
"description": "Community translations are available for most parts of jfa-go. You can choose the default languages below, but users can still change it if they wish. If you want to help translate, sign up to {n} to start contributing!"
|
||||
},
|
||||
"general": {
|
||||
"lightTheme": "Light",
|
||||
"title": "General",
|
||||
"listenAddress": "Listen Address",
|
||||
"darkTheme": "Dark",
|
||||
"useHTTPS": "Use HTTPS",
|
||||
"httpsPort": "HTTPS Port",
|
||||
"pathToCertificate": "Path to certificate",
|
||||
"pathToKeyFile": "Path to key file",
|
||||
"urlBase": "URL Base",
|
||||
"urlBaseNotice": "Only needed if using a reverse proxy on a subdomain (e.g 'jellyf.in/accounts').",
|
||||
"useHTTPSNotice": "Only recommended if you aren't using a reverse proxy."
|
||||
},
|
||||
"updates": {
|
||||
"title": "Updates",
|
||||
"updateChannel": "Update Channel",
|
||||
"stable": "Stable",
|
||||
"unstable": "Unstable",
|
||||
"description": "Enable to be notified when new updates are available. jfa-go will check {n} every 30 minutes. No IPs or personally identifiable information are collected."
|
||||
},
|
||||
"login": {
|
||||
"title": "Login",
|
||||
"description": "To access the admin page, you need to login with a method below:",
|
||||
"authorizeManual": "Username and Password: Manually set the username and password.",
|
||||
"adminOnly": "Admin users only (recommended)",
|
||||
"authorizeWithJellyfin": "Authorise with Jellyfin/Emby: Login details are shared with Jellyfin, which allows for multiple users.",
|
||||
"allowAll": "Allow all Jellyfin users to login",
|
||||
"allowAllDescription": "Not recommended, you should allow individual users to login once setup.",
|
||||
"emailNotice": "Your email address can be used to receive notifications."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Welcome messages",
|
||||
"description": "If enabled, a message will be sent to new users with the Jellyfin/Emby URL and their username."
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "By connecting to Ombi, both a Jellyfin and Ombi account will be created when a user joins through jfa-go. After setup is finished, go to Settings to set a default profile for new ombi users.",
|
||||
"apiKeyNotice": "Find this in the first tab of Ombi settings."
|
||||
},
|
||||
"messages": {
|
||||
"description": "jfa-go can send password resets and various messages through Email, Discord, Telegram, and/or Matrix. You can set up email below, and the others can be configured in Settings later. Instructions can be found on the {n}. If you don't need this, you can disable these features here.",
|
||||
"title": "Messages"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Admin Notifications",
|
||||
"description": "If enabled, you can choose (per invite) to receive an message when an invite expires, or a user is created. If you didn't choose the Jellyfin login method, make sure you provided your email address, or add another contact method later."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Invite Messages",
|
||||
"description": "If enabled, you can send invites directly to a user's email address, Discord or Matrix user. Because you might be using a reverse proxy, you need to provide the URL invites are accessed from. Write your URL Base, and append '/invite'."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
"emailSubject": "Email Subject",
|
||||
"URL": "URL",
|
||||
"apiKey": "API Key",
|
||||
"error": "Error",
|
||||
"errorInvalidUserPass": "Invalid username/password.",
|
||||
"errorNotAdmin": "User is not allowed to manage server.",
|
||||
"errorUserDisabled": "User may be disabled.",
|
||||
"error404": "404, check the internal URL."
|
||||
"error404": "404, check the internal URL.",
|
||||
"errorConnectionRefused": "Connection refused.",
|
||||
"errorUnknown": "Unknown error, check app logs."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Welcome!",
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
"errorInvalidUserPass": "Usuario/contraseña inválido.",
|
||||
"errorNotAdmin": "El usuario no tiene permitido administrar el servidor.",
|
||||
"errorUserDisabled": "El usuario puede estar desactivado.",
|
||||
"error404": "404, verifique la URL interna."
|
||||
"error404": "404, verifique la URL interna.",
|
||||
"errorConnectionRefused": "Conexión rechazada."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "¡Bienvenido!",
|
||||
@@ -65,7 +66,9 @@
|
||||
"authorizeWithJellyfin": "Autorizar con Jellyfin/Emby: los detalles de inicio de sesión se comparten con Jellyfin, lo que permite a varios usuarios.",
|
||||
"authorizeManual": "Nombre de usuario y contraseña: establezca manualmente el nombre de usuario y la contraseña.",
|
||||
"adminOnly": "Solo usuarios administradores (recomendado)",
|
||||
"emailNotice": "Su dirección de correo electrónico se puede utilizar para recibir notificaciones."
|
||||
"emailNotice": "Su dirección de correo electrónico se puede utilizar para recibir notificaciones.",
|
||||
"allowAll": "Permitir el acceso a todos los usuarios de Jellyfin",
|
||||
"allowAllDescription": "No se recomienda, debe permitir que los usuarios individuales se conecten una vez configurados."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
|
||||
150
lang/setup/hu-HU.json
Normal file
150
lang/setup/hu-HU.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (US)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Telepítés - jfa-go",
|
||||
"next": "Következő",
|
||||
"back": "Vissza",
|
||||
"optional": "Opcionális",
|
||||
"serverType": "Szerver típus",
|
||||
"disabled": "Letiltva",
|
||||
"enabled": "Engedélyezve",
|
||||
"port": "Port",
|
||||
"message": "Üzenet",
|
||||
"serverAddress": "Szerver cím",
|
||||
"emailSubject": "E-mail tárgy",
|
||||
"URL": "URL",
|
||||
"apiKey": "API kulcs",
|
||||
"errorInvalidUserPass": "Érvénytelen felhasználónév / jelszó.",
|
||||
"errorNotAdmin": "A felhasználó számára nincs engedélyezve a szerver kezelése.",
|
||||
"errorUserDisabled": "Lehetséges, hogy a felhasználó le lett tiltva.",
|
||||
"error404": "404, ellenőrizze a belső URL-t.",
|
||||
"errorConnectionRefused": ""
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Üdv!",
|
||||
"pressStart": "",
|
||||
"httpsNotice": "",
|
||||
"start": ""
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "",
|
||||
"restartMessage": "",
|
||||
"refreshPage": ""
|
||||
},
|
||||
"language": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"defaultAdminLang": "",
|
||||
"defaultFormLang": "",
|
||||
"defaultEmailLang": ""
|
||||
},
|
||||
"general": {
|
||||
"title": "",
|
||||
"listenAddress": "",
|
||||
"urlBase": "",
|
||||
"urlBaseNotice": "",
|
||||
"lightTheme": "",
|
||||
"darkTheme": "",
|
||||
"useHTTPS": "",
|
||||
"httpsPort": "",
|
||||
"useHTTPSNotice": "",
|
||||
"pathToCertificate": "",
|
||||
"pathToKeyFile": ""
|
||||
},
|
||||
"updates": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"updateChannel": "",
|
||||
"stable": "",
|
||||
"unstable": ""
|
||||
},
|
||||
"login": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"authorizeWithJellyfin": "",
|
||||
"authorizeManual": "",
|
||||
"adminOnly": "",
|
||||
"allowAll": "",
|
||||
"allowAllDescription": "",
|
||||
"emailNotice": ""
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"embyNotice": "",
|
||||
"internal": "",
|
||||
"external": "",
|
||||
"replaceJellyfin": "",
|
||||
"replaceJellyfinNotice": "",
|
||||
"addressExternalNotice": "",
|
||||
"testConnection": ""
|
||||
},
|
||||
"ombi": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"apiKeyNotice": ""
|
||||
},
|
||||
"messages": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"email": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"method": "",
|
||||
"useEmailAsUsername": "",
|
||||
"useEmailAsUsernameNotice": "",
|
||||
"fromAddress": "",
|
||||
"senderName": "",
|
||||
"dateFormat": "",
|
||||
"dateFormatNotice": "",
|
||||
"encryption": "",
|
||||
"mailgunApiURL": ""
|
||||
},
|
||||
"notifications": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"pathToJellyfin": "",
|
||||
"pathToJellyfinNotice": "",
|
||||
"resetLinks": "",
|
||||
"resetLinksNotice": "",
|
||||
"resetLinksLanguage": "",
|
||||
"setPassword": "",
|
||||
"setPasswordNotice": ""
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"length": "",
|
||||
"uppercase": "",
|
||||
"lowercase": "",
|
||||
"numbers": "",
|
||||
"special": ""
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"contactMessage": "",
|
||||
"contactMessageNotice": "",
|
||||
"helpMessage": "",
|
||||
"helpMessageNotice": "",
|
||||
"successMessage": "",
|
||||
"successMessageNotice": "",
|
||||
"emailMessage": "",
|
||||
"emailMessageNotice": ""
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,8 @@
|
||||
"errorInvalidUserPass": "Ongeldige gebruikersnaam/wachtwoord.",
|
||||
"errorUserDisabled": "De gebruiker kan uitgeschakeld zijn.",
|
||||
"error404": "404, controleer de interne URL.",
|
||||
"errorNotAdmin": "Gebruiker heeft geen beheersrechten."
|
||||
"errorNotAdmin": "Gebruiker heeft geen beheersrechten.",
|
||||
"errorConnectionRefused": "Verbinding geweigerd."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Welkom!",
|
||||
@@ -58,7 +59,9 @@
|
||||
"authorizeWithJellyfin": "Jellyfin/Emby authorisatie: Inloggegevens worden gedeeld met Jellyfin, meerdere gebruikers mogelijk.",
|
||||
"authorizeManual": "Gebruikersnaam en wachtwoord: Stel handmatig een gebruikersnaam en wachtwoord in.",
|
||||
"adminOnly": "Alleen beheerders (aanbevolen)",
|
||||
"emailNotice": "Je e-mailadres kan gebruikt worden om meldingen te ontvangen."
|
||||
"emailNotice": "Je e-mailadres kan gebruikt worden om meldingen te ontvangen.",
|
||||
"allowAll": "Laat alle Jellyfin-gebruikers inloggen",
|
||||
"allowAllDescription": "Afgeraden, je kunt beter individuele gebruikers toegang geven na de setup."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
|
||||
150
lang/setup/pl-PL.json
Normal file
150
lang/setup/pl-PL.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Polski (PL)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Ustawienia - jfa-go",
|
||||
"next": "Dalej",
|
||||
"back": "Cofnij",
|
||||
"optional": "Opcjonalne",
|
||||
"serverType": "Typ Serwera",
|
||||
"disabled": "Wyłączone",
|
||||
"enabled": "Włączone",
|
||||
"port": "Port",
|
||||
"message": "Wiadomość",
|
||||
"serverAddress": "Adres Serwera",
|
||||
"emailSubject": "Tytuł wiadomości email",
|
||||
"URL": "URL",
|
||||
"apiKey": "API Key",
|
||||
"errorInvalidUserPass": "Niepoprawna nazwa użytkownika/hasło.",
|
||||
"errorNotAdmin": "Użytkownik nie jest upoważniony do zarządzania serwerem.",
|
||||
"errorUserDisabled": "Użytkownik może być wyłączony.",
|
||||
"error404": "404, nie znaleziono URL.",
|
||||
"errorConnectionRefused": "Brak dostępu."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Witaj!",
|
||||
"pressStart": "Musisz wykonać kilka czynności aby skonfigurować jfa-go. Wciśnij start aby kontynuować.",
|
||||
"httpsNotice": "Upewnij się , że masz dostęp do strony przy użyciu HTTPS lub sieci LAN.",
|
||||
"start": "Start"
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Ukończono!",
|
||||
"restartMessage": "Możesz skonfigurować boty Discord/Telegram/Matrix, dostosować wiadomości i nie tylko w Ustawieniach. Kliknij poniżej, aby ponownie uruchomić, a następnie odśwież stronę.",
|
||||
"refreshPage": "Odśwież"
|
||||
},
|
||||
"language": {
|
||||
"title": "Język",
|
||||
"description": "Tłumaczenia społeczności są dostępne dla większości jfa-go. Poniżej możesz wybrać języki domyślne, ale użytkownicy mogą je zmienić, jeśli chcą. Jeśli chcesz pomóc w tłumaczeniu, zarejestruj się do {n}, aby zacząć współtworzyć!",
|
||||
"defaultAdminLang": "Domyślny język administratora",
|
||||
"defaultFormLang": "Domyślny język tworzenia konta",
|
||||
"defaultEmailLang": "Domyślny język email"
|
||||
},
|
||||
"general": {
|
||||
"title": "Ogólne",
|
||||
"listenAddress": "",
|
||||
"urlBase": "",
|
||||
"urlBaseNotice": "Wymagane tylko jeśli używasz reverse proxy na subdomenie np. jellyf.in/accounts.",
|
||||
"lightTheme": "Jasny",
|
||||
"darkTheme": "Ciemny",
|
||||
"useHTTPS": "Użyj HTTPS",
|
||||
"httpsPort": "Port HTTPS",
|
||||
"useHTTPSNotice": "Zalecane tylko jeśli nie używasz reverse proxy.",
|
||||
"pathToCertificate": "Ścieżka do certyfikatu",
|
||||
"pathToKeyFile": "Ścieżka do .key"
|
||||
},
|
||||
"updates": {
|
||||
"title": "Aktualizacje",
|
||||
"description": "",
|
||||
"updateChannel": "",
|
||||
"stable": "Stabilny",
|
||||
"unstable": "Niestabilne"
|
||||
},
|
||||
"login": {
|
||||
"title": "Zaloguj",
|
||||
"description": "",
|
||||
"authorizeWithJellyfin": "",
|
||||
"authorizeManual": "",
|
||||
"adminOnly": "Tylko administratorzy (zalecane)",
|
||||
"allowAll": "Zezwój wszystkim użytkownikom na logowanie do Jellyfin",
|
||||
"allowAllDescription": "",
|
||||
"emailNotice": ""
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"embyNotice": "",
|
||||
"internal": "",
|
||||
"external": "",
|
||||
"replaceJellyfin": "Nazwa serwera",
|
||||
"replaceJellyfinNotice": "",
|
||||
"addressExternalNotice": "",
|
||||
"testConnection": ""
|
||||
},
|
||||
"ombi": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"apiKeyNotice": ""
|
||||
},
|
||||
"messages": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"email": {
|
||||
"title": "E-mail",
|
||||
"description": "",
|
||||
"method": "",
|
||||
"useEmailAsUsername": "",
|
||||
"useEmailAsUsernameNotice": "",
|
||||
"fromAddress": "",
|
||||
"senderName": "",
|
||||
"dateFormat": "",
|
||||
"dateFormatNotice": "",
|
||||
"encryption": "",
|
||||
"mailgunApiURL": ""
|
||||
},
|
||||
"notifications": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"pathToJellyfin": "",
|
||||
"pathToJellyfinNotice": "",
|
||||
"resetLinks": "",
|
||||
"resetLinksNotice": "",
|
||||
"resetLinksLanguage": "",
|
||||
"setPassword": "",
|
||||
"setPasswordNotice": ""
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"length": "",
|
||||
"uppercase": "",
|
||||
"lowercase": "",
|
||||
"numbers": "",
|
||||
"special": ""
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"contactMessage": "",
|
||||
"contactMessageNotice": "",
|
||||
"helpMessage": "",
|
||||
"helpMessageNotice": "",
|
||||
"successMessage": "",
|
||||
"successMessageNotice": "",
|
||||
"emailMessage": "",
|
||||
"emailMessageNotice": ""
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,12 @@
|
||||
"serverAddress": "Endereço do Servidor",
|
||||
"emailSubject": "Assunto do Email",
|
||||
"URL": "URL",
|
||||
"apiKey": "Chave API"
|
||||
"apiKey": "Chave API",
|
||||
"errorNotAdmin": "O usuário não tem permissão para gerenciar o servidor.",
|
||||
"errorUserDisabled": "O usuário pode estar desabilitado.",
|
||||
"error404": "404, verifique a URL interna.",
|
||||
"errorInvalidUserPass": "Usuário ou Senha Inválidos.",
|
||||
"errorConnectionRefused": "Conexão recusada."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Bem Vindo!",
|
||||
@@ -38,7 +43,7 @@
|
||||
"general": {
|
||||
"title": "Geral",
|
||||
"listenAddress": "Endereço de Escuta",
|
||||
"urlBase": "URL Base",
|
||||
"urlBase": "local URL",
|
||||
"urlBaseNotice": "Necessário apenas se estiver usando um proxy reverso em um subdomínio (por exemplo, 'jellyf.in/accounts').",
|
||||
"lightTheme": "Claro",
|
||||
"darkTheme": "Escuro",
|
||||
@@ -54,7 +59,9 @@
|
||||
"authorizeWithJellyfin": "Autorizar com Jellyfin/Emby: Os detalhes de login são compartilhados com Jellyfin, o que permite vários usuários.",
|
||||
"authorizeManual": "Nome de usuário e senha: Defina manualmente o nome de usuário e a senha.",
|
||||
"adminOnly": "Apenas usuários administradores (recomendado)",
|
||||
"emailNotice": "Seu endereço de email pode ser usado para receber notificações."
|
||||
"emailNotice": "Seu endereço de email pode ser usado para receber notificações.",
|
||||
"allowAll": "Permitir que todos os usuários do Jellyfin façam login",
|
||||
"allowAllDescription": "Não recomendado, você deve permitir que usuários individuais façam login após a configuração."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
|
||||
149
lang/setup/sl-si.json
Normal file
149
lang/setup/sl-si.json
Normal file
@@ -0,0 +1,149 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Angleščina (ZDA)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "",
|
||||
"next": "",
|
||||
"back": "",
|
||||
"optional": "",
|
||||
"serverType": "",
|
||||
"disabled": "",
|
||||
"enabled": "",
|
||||
"port": "",
|
||||
"message": "",
|
||||
"serverAddress": "",
|
||||
"emailSubject": "",
|
||||
"URL": "",
|
||||
"apiKey": "",
|
||||
"errorInvalidUserPass": "",
|
||||
"errorNotAdmin": "",
|
||||
"errorUserDisabled": "",
|
||||
"error404": ""
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "",
|
||||
"pressStart": "",
|
||||
"httpsNotice": "",
|
||||
"start": ""
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "",
|
||||
"restartMessage": "",
|
||||
"refreshPage": ""
|
||||
},
|
||||
"language": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"defaultAdminLang": "",
|
||||
"defaultFormLang": "",
|
||||
"defaultEmailLang": ""
|
||||
},
|
||||
"general": {
|
||||
"title": "",
|
||||
"listenAddress": "",
|
||||
"urlBase": "",
|
||||
"urlBaseNotice": "",
|
||||
"lightTheme": "",
|
||||
"darkTheme": "",
|
||||
"useHTTPS": "",
|
||||
"httpsPort": "",
|
||||
"useHTTPSNotice": "",
|
||||
"pathToCertificate": "",
|
||||
"pathToKeyFile": ""
|
||||
},
|
||||
"updates": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"updateChannel": "",
|
||||
"stable": "",
|
||||
"unstable": ""
|
||||
},
|
||||
"login": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"authorizeWithJellyfin": "",
|
||||
"authorizeManual": "",
|
||||
"adminOnly": "",
|
||||
"allowAll": "",
|
||||
"allowAllDescription": "",
|
||||
"emailNotice": ""
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"embyNotice": "",
|
||||
"internal": "",
|
||||
"external": "",
|
||||
"replaceJellyfin": "",
|
||||
"replaceJellyfinNotice": "",
|
||||
"addressExternalNotice": "",
|
||||
"testConnection": ""
|
||||
},
|
||||
"ombi": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"apiKeyNotice": ""
|
||||
},
|
||||
"messages": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"email": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"method": "",
|
||||
"useEmailAsUsername": "",
|
||||
"useEmailAsUsernameNotice": "",
|
||||
"fromAddress": "",
|
||||
"senderName": "",
|
||||
"dateFormat": "",
|
||||
"dateFormatNotice": "",
|
||||
"encryption": "",
|
||||
"mailgunApiURL": ""
|
||||
},
|
||||
"notifications": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "",
|
||||
"description": ""
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"pathToJellyfin": "",
|
||||
"pathToJellyfinNotice": "",
|
||||
"resetLinks": "",
|
||||
"resetLinksNotice": "",
|
||||
"resetLinksLanguage": "",
|
||||
"setPassword": "",
|
||||
"setPasswordNotice": ""
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"length": "",
|
||||
"uppercase": "",
|
||||
"lowercase": "",
|
||||
"numbers": "",
|
||||
"special": ""
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "",
|
||||
"description": "",
|
||||
"contactMessage": "",
|
||||
"contactMessageNotice": "",
|
||||
"helpMessage": "",
|
||||
"helpMessageNotice": "",
|
||||
"successMessage": "",
|
||||
"successMessageNotice": "",
|
||||
"emailMessage": "",
|
||||
"emailMessageNotice": ""
|
||||
}
|
||||
}
|
||||
150
lang/setup/zh-Hant.json
Normal file
150
lang/setup/zh-Hant.json
Normal file
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "繁體中文 (TW)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "設置 - jfa-go",
|
||||
"next": "下一步",
|
||||
"back": "上一步",
|
||||
"optional": "可選的",
|
||||
"serverType": "伺服器類型",
|
||||
"disabled": "已禁用",
|
||||
"enabled": "已啟用",
|
||||
"port": "通訊埠",
|
||||
"message": "訊息",
|
||||
"serverAddress": "伺服器地址",
|
||||
"emailSubject": "電子郵件主題",
|
||||
"URL": "網址",
|
||||
"apiKey": "API密鑰",
|
||||
"errorInvalidUserPass": "無效的帳戶名稱/密碼。",
|
||||
"errorNotAdmin": "此帳戶不允許管理伺服器。",
|
||||
"errorUserDisabled": "此帳戶可能已被禁用。",
|
||||
"error404": "404, 請檢查內部網址(internal URL)。",
|
||||
"errorConnectionRefused": "連線遭拒。"
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "歡迎!",
|
||||
"pressStart": "您需要完成幾個步驟來設置jfa-go。點擊 開始 以繼續。",
|
||||
"httpsNotice": "請確保您通過 HTTPS 或專用網路訪問此頁面。",
|
||||
"start": "開始"
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "已完成!",
|
||||
"restartMessage": "您可以設置Discord/Telegram/Matrix機器人,在“設置”中自定義您的訊息和其他內容。點擊下方重新啟動,然後重整頁面。",
|
||||
"refreshPage": "重新整理"
|
||||
},
|
||||
"language": {
|
||||
"title": "語言",
|
||||
"description": "jfa-go 的大部分內容都仰賴社群翻譯。您可以選擇下面的預設語言,但使用者仍然可以根據需要進行更改。如果您想改進翻譯,請在 {n} 註冊以開始貢獻您的一份力量!",
|
||||
"defaultAdminLang": "預設管理語言",
|
||||
"defaultFormLang": "預設帳戶創建語言",
|
||||
"defaultEmailLang": "預設電子郵件語言"
|
||||
},
|
||||
"general": {
|
||||
"title": "一般",
|
||||
"listenAddress": "監聽埠",
|
||||
"urlBase": "基底URL",
|
||||
"urlBaseNotice": "只有在子網域上使用反向代理時才需要(例如“jellyf.in/accounts”)。",
|
||||
"lightTheme": "明亮",
|
||||
"darkTheme": "黑暗",
|
||||
"useHTTPS": "使用HTTPS",
|
||||
"httpsPort": "HTTPS 通訊埠",
|
||||
"useHTTPSNotice": "只有在您不使用反向代理時才推薦使用。",
|
||||
"pathToCertificate": "證書文件路徑",
|
||||
"pathToKeyFile": "密鑰文件路徑"
|
||||
},
|
||||
"updates": {
|
||||
"title": "更新",
|
||||
"description": "啟用此選項可在有新更新可用時收到通知。jfa-go 每 30 分鐘將對 {n} 檢查一次。不會收集任何IP或個人身份資訊。",
|
||||
"updateChannel": "更新頻道",
|
||||
"stable": "穩定版",
|
||||
"unstable": "非穩定版"
|
||||
},
|
||||
"login": {
|
||||
"title": "登錄",
|
||||
"description": "要存取管理頁面,您需要使用以下方法登錄:",
|
||||
"authorizeWithJellyfin": "使用Jellyfin/Emby授權:登錄詳細資訊與Jellyfin共用,允許使用多個帳戶。",
|
||||
"authorizeManual": "帳戶名稱和密碼:手動設置帳戶名稱和密碼。",
|
||||
"adminOnly": "僅限管理員帳戶(推薦)",
|
||||
"allowAll": "允許所有Jellyfin帳戶登錄",
|
||||
"allowAllDescription": "不建議,您應該允許個別使用者在登錄后設置。",
|
||||
"emailNotice": "您的電子郵件地址可用於接收通知。"
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
"description": "需要管理員帳戶,因為 API 不允許使用 API 金鑰創建帳戶。您應該創建一個單獨的帳戶並選取「 允許此使用者管理伺服器」。您可以關閉其他所有內容。完成後,在此處輸入登錄詳細資訊。",
|
||||
"embyNotice": "對 Emby 提供有限支持,不支持密碼重置功能。",
|
||||
"internal": "內部",
|
||||
"external": "外部",
|
||||
"replaceJellyfin": "伺服器名稱",
|
||||
"replaceJellyfinNotice": "如果填寫,則替換應用程式中出現的所有 'Jellyfin' 字樣。",
|
||||
"addressExternalNotice": "留空以使用相同的地址。",
|
||||
"testConnection": "測試連接"
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "通過連接到 Ombi,當使用者通過 jfa-go 加入時,將創建 Jellyfin 和 Ombi 帳戶。設置完成後,轉到 “設置” 為新的 ombi 帳戶設置預設配置檔。",
|
||||
"apiKeyNotice": "在 Ombi “設置”的第一個選項卡中找到它。"
|
||||
},
|
||||
"messages": {
|
||||
"title": "訊息",
|
||||
"description": "jfa-go 可以通過電子郵件、Discord、Telegram 和/或 Matrix 發送密碼重置和各種消息。您可以在下面設置電子郵件,其他電子郵件可以稍後在「設置」中進行配置。說明可以在 {n} 上找到。如果不需要此功能,可以在此處禁用這些功能。"
|
||||
},
|
||||
"email": {
|
||||
"title": "電子郵件",
|
||||
"description": "jfa-go 可以通過電子郵件發送密碼重置PIN和各種通知。您可以連接到 SMTP 伺服器,或使用 {n} API。",
|
||||
"method": "發送方式",
|
||||
"useEmailAsUsername": "使用電子郵件地址作為使用者名稱",
|
||||
"useEmailAsUsernameNotice": "如果啟用,新使用者將使用他們的電子郵件地址而不是帳戶名稱登錄Jellyfin/Emby。",
|
||||
"fromAddress": "寄件者地址",
|
||||
"senderName": "寄件者名稱",
|
||||
"dateFormat": "日期格式",
|
||||
"dateFormatNotice": "日期遵循 strftime 格式。有關詳細資訊,請訪問 {n}。",
|
||||
"encryption": "加密",
|
||||
"mailgunApiURL": "API URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "管理員通知",
|
||||
"description": "如果啟用,您可以選擇(每個邀請)在邀請過期或創建帳戶時接收消息。如果您沒有選擇 Jellyfin 登錄方式,請確保您提供了電子郵件地址,或稍後添加其他聯繫方式。"
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "歡迎訊息",
|
||||
"description": "如果啟用,將向新帳戶發送一條消息,其中包含 Jellyfin/Emby URL 及其帳戶名稱。"
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "邀請通知",
|
||||
"description": "如果啟用,您可以直接向使用者的電子郵件、Discord 或 Matrix 帳戶發送邀請。由於您可能使用的是反向代理,因此需要提供從中訪問邀請的URL。寫下您的 URL 庫,並附加 “/invite”。"
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "重置密碼",
|
||||
"description": "當用戶嘗試重置密碼時,Jellyfin 會創建一個名為 “passwordreset-*.json” 的檔,其中包含一個 PIN 碼。jfa-go 讀取該文件並將 PIN 碼發送給使用者。",
|
||||
"pathToJellyfin": "Jellyfin 配置目錄的路徑",
|
||||
"pathToJellyfinNotice": "如果您不知道它在哪裡,請嘗試在Jellyfin中重置密碼。將出現一個帶有 “<path to jellyfin>/passwordreset-*.json” 的彈出視窗。",
|
||||
"resetLinks": "發送連結而不是 PIN 碼",
|
||||
"resetLinksNotice": "如果啟用了 Ombi 集成,請使用此選項將 Jellyfin 密碼重置與 Ombi 同步。",
|
||||
"resetLinksLanguage": "預設重置連結語言",
|
||||
"setPassword": "通過連結設置密碼",
|
||||
"setPasswordNotice": "啟用此功能意味著使用者不必在重置後從 PIN 更改其密碼。並將強制執行密碼驗證。"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "密碼驗證",
|
||||
"description": "如果啟用,帳戶創建頁面上將顯示一組密碼要求,例如最小長度、大寫/小寫字元等。",
|
||||
"length": "長度",
|
||||
"uppercase": "大寫字元",
|
||||
"lowercase": "小寫字元",
|
||||
"numbers": "數字",
|
||||
"special": "特殊字元(%、* 等)"
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "幫助訊息",
|
||||
"description": "這些訊息將顯示在帳戶創建頁面和某些電子郵件中。",
|
||||
"contactMessage": "聯繫方式",
|
||||
"contactMessageNotice": "顯示在除管理員之外的所有頁面的底部。",
|
||||
"helpMessage": "幫助訊息",
|
||||
"helpMessageNotice": "顯示在帳戶創建頁面上。",
|
||||
"successMessage": "成功訊息",
|
||||
"successMessageNotice": "在使用者創建其帳戶時顯示。",
|
||||
"emailMessage": "電子郵件訊息",
|
||||
"emailMessageNotice": "顯示在電子郵件的底部。"
|
||||
}
|
||||
}
|
||||
@@ -15,11 +15,12 @@
|
||||
"serverAddress": "服务地址",
|
||||
"emailSubject": "邮件主题",
|
||||
"URL": "链接",
|
||||
"apiKey": "API Key",
|
||||
"apiKey": "API 密钥",
|
||||
"errorInvalidUserPass": "无效的用户名/密码。",
|
||||
"errorNotAdmin": "此用户不允许管理服务。",
|
||||
"errorUserDisabled": "此永固可能已被禁用。",
|
||||
"error404": "404,请检查内部URL。"
|
||||
"error404": "404,请检查内部URL。",
|
||||
"errorConnectionRefused": "连接被拒绝。"
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "欢迎!",
|
||||
@@ -42,7 +43,7 @@
|
||||
"general": {
|
||||
"title": "常规",
|
||||
"listenAddress": "监听端口",
|
||||
"urlBase": "URL Base",
|
||||
"urlBase": "URL地址",
|
||||
"urlBaseNotice": "仅在子域上使用反向代理时才需要(例如“jellyf.in/accounts”)。",
|
||||
"lightTheme": "明亮",
|
||||
"darkTheme": "暗黑",
|
||||
@@ -65,7 +66,9 @@
|
||||
"authorizeWithJellyfin": "从Jellyfin/Emby 授权:登录信息与 Jellyfin 同步,允许使用多个用户。",
|
||||
"authorizeManual": "用户名和密码:手动设置用户名和密码。",
|
||||
"adminOnly": "仅允许管理员账户(推荐)",
|
||||
"emailNotice": "您的电子邮件地址可以用来接收通知。"
|
||||
"emailNotice": "您的电子邮件地址可以用来接收通知。",
|
||||
"allowAllDescription": "不建议,您应该允许单个用户在设置后登录。",
|
||||
"allowAll": "允许所有Jellyfin用户登录"
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
@@ -98,7 +101,7 @@
|
||||
"dateFormat": "日期格式",
|
||||
"dateFormatNotice": "日期遵循 strftime 格式。如需更多信息,请访问 {n}。",
|
||||
"encryption": "加密",
|
||||
"mailgunApiURL": "API URL"
|
||||
"mailgunApiURL": "API地址"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "管理员通知",
|
||||
|
||||
16
lang/telegram/ar-AA.json
Normal file
16
lang/telegram/ar-AA.json
Normal file
@@ -0,0 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "العربية (AR)"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "مرحبا!\nضع رقمك السري للتحقق من حسابك",
|
||||
"discordStartMessage": "مرحبا!\nضع رقمك السري `/pin <PIN>` للتحقق من حسابك.",
|
||||
"matrixStartMessage": "أهلا\nأدخل رقم التعريف الشخصي أدناه في صفحة الاشتراك في Jellyfin للتحقق من حسابك.",
|
||||
"invalidPIN": "رقم التعريف الشخصي هذا غير صالح ، حاول مرة أخرى.",
|
||||
"pinSuccess": "تم! يمكنك الآن العودة إلى صفحة التسجيل.",
|
||||
"languageMessage": "ملاحظة: اطلع على اللغات المتاحة باستخدام {command} ، وقم بتعيين اللغة باستخدام {command} <language code>.",
|
||||
"languageMessageDiscord": "ملاحظة: اضبط لغتك باستخدام / lang <language name>.",
|
||||
"languageSet": "تم تعيين اللغة على {language}.",
|
||||
"discordDMs": "يرجى التحقق من الرسائل المباشرة الخاصة بك للحصول على رد."
|
||||
}
|
||||
}
|
||||
@@ -3,10 +3,14 @@
|
||||
"name": "Dansk (DK)"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "Hej!\nIndtast din Jellyfin PIN-kode her for at verificere din konto.",
|
||||
"matrixStartMessage": "Hej!\nIndtast PIN-koden på Jellyfin tilmeldingssiden for at verificere din konto.",
|
||||
"startMessage": "Hej!\nIndtast din Jellyfin PIN-kode her for at bekræfte din konto.",
|
||||
"matrixStartMessage": "Hej!\nIndtast PIN-koden på Jellyfin tilmeldingssiden for at bekræfte din konto.",
|
||||
"invalidPIN": "Den PIN-kode var ugyldig, prøv igen.",
|
||||
"pinSuccess": "Sådan! Du kan nu gå tilbage til tilmeldingssiden.",
|
||||
"languageMessage": "Note: Se tilgængelige sprog med {command}, og vælg sprog med {command} <sprog kode>."
|
||||
"languageMessage": "Note: Se tilgængelige sprog med {command}, og vælg sprog med {command} <sprog kode>.",
|
||||
"discordStartMessage": "Hej!\n Indtast din pinkode med `/pin <PIN>` for at bekræfte din konto.",
|
||||
"languageMessageDiscord": "Bemærk: Indstil dit sprog med /lang <sprognavn>.",
|
||||
"languageSet": "Sprog indstillet til {language}.",
|
||||
"discordDMs": "Tjek venligst dine DM's for et svar."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,10 +3,14 @@
|
||||
"name": "Deutsch (DE)"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "Hallo,\ngib deinen Jellyfin-PIN-Code ein, um dein Konto zu verifizieren.",
|
||||
"matrixStartMessage": "Hallo,\ngib den untenstehenden PIN auf der Anmeldeseite von Jellyfin ein, um dein Konto zu verifizieren.",
|
||||
"startMessage": "Hi!\nGib deinen Jellyfin-PIN-Code ein, um dein Konto zu verifizieren.",
|
||||
"matrixStartMessage": "Hi!\nGib die untenstehende PIN auf der Anmeldeseite von Jellyfin ein, um dein Konto zu verifizieren.",
|
||||
"invalidPIN": "Diese PIN war ungültig, versuche es erneut.",
|
||||
"pinSuccess": "Erfolg! Du kannst nun zur Anmeldeseite zurückkehren.",
|
||||
"languageMessage": "Hinweis: Zeige verfügbare Sprachen mit {command} an und stelle mit {command} <Sprachcode> die gewünschte ein."
|
||||
"languageMessage": "Hinweis: Mit {command} kannst du alle verfügbaren Sprachen sehen und mit {command} <Sprachcode> die gewünschte Sprache einstellen.",
|
||||
"discordStartMessage": "Hi!\n Gib \"/pin\" gefolgt von deiner PIN ein, um dein Konto zu verifizieren.",
|
||||
"languageMessageDiscord": "Hinweis: Du kannst deine Sprache mit \"/lang <Sprache>\" ändern.",
|
||||
"languageSet": "Sprache auf {language} geändert.",
|
||||
"discordDMs": "Schaue in deinen DMs nach einer Antwort."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,16 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "English (GB)"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "Hi!\nEnter your Jellyfin PIN code here to verify your account.",
|
||||
"languageMessage": "Note: See available languages with {command}, and set language with {command} <language code>.",
|
||||
"discordDMs": "Please check your DMs for a response.",
|
||||
"matrixStartMessage": "Hi\nEnter the below PIN in the Jellyfin sign-up page to verify your account.",
|
||||
"discordStartMessage": "Hi!\n Enter your PIN with `/pin <PIN>` to verify your account.",
|
||||
"invalidPIN": "That PIN was invalid, try again.",
|
||||
"pinSuccess": "Success! You can now return to the sign-up page.",
|
||||
"languageMessageDiscord": "Note: set your language with /lang <language name>.",
|
||||
"languageSet": "Language set to {language}."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
"matrixStartMessage": "Hola\nIngrese el PIN a continuación en la página de registro de Jellyfin para verificar su cuenta.",
|
||||
"invalidPIN": "Ese PIN no es válido, inténtalo de nuevo.",
|
||||
"pinSuccess": "¡Éxito! Ahora puedes volver a la página de registro.",
|
||||
"languageMessage": "Nota: Revisa los idiomas disponibles con {command}, y establece el idioma con {command} <language code>."
|
||||
"languageMessage": "Nota: Revisa los idiomas disponibles con {command}, y establece el idioma con {command} <language code>.",
|
||||
"discordStartMessage": "Hola\nIntroduzca su PIN con `/pin <PIN>` para verificar su cuenta.",
|
||||
"languageMessageDiscord": "Nota: configure su idioma con /lang <language name>.",
|
||||
"languageSet": "El idioma esta configurado como {language}.",
|
||||
"discordDMs": "Por favor, compruebe sus DMs para una respuesta."
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user