Compare commits
274 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fe72b41bf | ||
|
|
a1d93cd6af | ||
|
|
53ac01eda4 | ||
|
|
4cea755065 | ||
|
|
be4e83d69c | ||
|
|
1e58a33c68 | ||
|
|
15e1766920 | ||
|
|
a220ba8dfb | ||
|
|
b29c24a405 | ||
|
|
fbe3553b25 | ||
|
|
f727e2c5b2 | ||
|
|
6c6af623a6 | ||
|
|
548dceda28 | ||
|
|
e67b2e91fb | ||
|
|
412fe31da6 | ||
|
|
1bfec54c93 | ||
|
|
5b319d6612 | ||
|
|
626d623841 | ||
|
|
08343298fb | ||
|
|
7a343bbc08 | ||
|
|
2be34ed063 | ||
|
|
7e32c8c4f0 | ||
|
|
a0871e7c47 | ||
|
|
f6834ee63d | ||
|
|
54b8e30cff | ||
|
|
504d3e39de | ||
|
|
4e2dce7f18 | ||
|
|
b31506d94e | ||
|
|
5961bc6086 | ||
|
|
b0ffa457df | ||
|
|
9e3fa0ea9a | ||
|
|
ff69d0ba6d | ||
|
|
cf25472746 | ||
|
|
5e651d7b08 | ||
|
|
bcd1011b68 | ||
|
|
f8f0715a3b | ||
|
|
e27e08bfd7 | ||
|
|
ae4d47af43 | ||
|
|
b32271e375 | ||
|
|
753e233e27 | ||
|
|
d6669bfa70 | ||
|
|
94b288671d | ||
|
|
a444e53a99 | ||
|
|
792846f727 | ||
|
|
6b9fa7bf8a | ||
|
|
c4378d19db | ||
|
|
bdebd97dc0 | ||
|
|
cf2bd6c095 | ||
|
|
08f3675f71 | ||
|
|
8d53ddcf93 | ||
|
|
c20dc24ccf | ||
|
|
b60be0db6d | ||
|
|
756e7345cf | ||
|
|
eb3489b34f | ||
|
|
9693ce3dcd | ||
|
|
6e88c1f4fc | ||
|
|
67c60cb677 | ||
|
|
1a6b0d2b6e | ||
|
|
5aaab7904f | ||
|
|
9885c25a2e | ||
|
|
27ad7a4cf7 | ||
|
|
6551eeb938 | ||
|
|
36c23c1e4f | ||
|
|
6b4d4da455 | ||
|
|
aa2891fc87 | ||
|
|
db526fc611 | ||
|
|
a869acd5dc | ||
|
|
f763cfb53a | ||
|
|
25a8d3807e | ||
|
|
b10b558358 | ||
|
|
504b602c0b | ||
|
|
f04411e137 | ||
|
|
1336a87ae2 | ||
|
|
872c366384 | ||
|
|
762d5325fb | ||
|
|
7f37633423 | ||
|
|
8ec4031ba3 | ||
|
|
4c10996c09 | ||
|
|
4d3acb2c4c | ||
|
|
833d02b032 | ||
|
|
30198fab87 | ||
|
|
51768958c6 | ||
|
|
3e55cd1e31 | ||
|
|
35f0fead53 | ||
|
|
a95d8bff29 | ||
|
|
48332a4ffa | ||
|
|
2266bbc320 | ||
|
|
b682685a3b | ||
|
|
91411437e2 | ||
|
|
119bed7024 | ||
|
|
6d70a5b24b | ||
|
|
a99ee04aca | ||
|
|
3ca2315290 | ||
|
|
d4bcf229e9 | ||
|
|
3950455a3f | ||
|
|
7e8e242db0 | ||
|
|
cda90f20af | ||
|
|
8ba393ebc0 | ||
|
|
2de1570a98 | ||
|
|
6b01e0d44d | ||
|
|
af4dcd1e2a | ||
|
|
a8ce68959d | ||
|
|
05bc38565c | ||
|
|
574ca4734d | ||
|
|
0957dd58c2 | ||
|
|
4db5d96bb1 | ||
|
|
76c19731cb | ||
|
|
fea368aaae | ||
|
|
1f8bc027c8 | ||
|
|
f2240ebf0d | ||
|
|
9b9f34ae96 | ||
|
|
86559d5c76 | ||
|
|
40ec5b9933 | ||
|
|
fbb9f20026 | ||
|
|
d5a33cf242 | ||
|
|
c35fdc2cbe | ||
|
|
84d5bc8f67 | ||
|
|
b8d9d22545 | ||
|
|
788afa1025 | ||
|
|
6ca3ab899c | ||
|
|
d4096d0062 | ||
|
|
306ede47d6 | ||
|
|
fc0e86ffd8 | ||
|
|
729fc7baf7 | ||
|
|
2d83e9ff7e | ||
|
|
a0af76364a | ||
|
|
169622bf95 | ||
|
|
78b5136b9a | ||
|
|
e546f50141 | ||
|
|
e35fe8d425 | ||
|
|
6ed2f7aaa6 | ||
|
|
084e8ec432 | ||
|
|
fd7f74682b | ||
|
|
9950c158a1 | ||
|
|
21125033ff | ||
|
|
1dc0b2234a | ||
|
|
0ea5c7fdc0 | ||
|
|
b538922c05 | ||
|
|
f0f4e8118e | ||
|
|
2f501697db | ||
|
|
0a71d5b216 | ||
|
|
0014db44f0 | ||
|
|
885d2ebf0f | ||
|
|
6d089a9818 | ||
|
|
de81c7e29f | ||
|
|
e49996c401 | ||
|
|
aa40a72075 | ||
|
|
19b7341e80 | ||
|
|
73645a7569 | ||
|
|
a9dac8c04c | ||
|
|
43fbbbcd16 | ||
|
|
fc57a8c97f | ||
|
|
1fb2ef5675 | ||
|
|
e0d994c35c | ||
|
|
cab30eb628 | ||
|
|
71df011556 | ||
|
|
b2828110e3 | ||
|
|
50eb05776a | ||
|
|
19715f25f6 | ||
|
|
d41a281d53 | ||
|
|
a8229631bd | ||
|
|
0a2cf6132f | ||
|
|
d7ab01063a | ||
|
|
6fb8f1ed7f | ||
|
|
a9b11012bc | ||
|
|
e7cb1f516b | ||
|
|
555d5abf59 | ||
|
|
93937ec3b5 | ||
|
|
93c7a6e31b | ||
|
|
a9cabe3d74 | ||
|
|
d6fd1d6894 | ||
|
|
375022ba95 | ||
|
|
75fdf6ec3d | ||
|
|
561c461a18 | ||
|
|
59ebf52fe2 | ||
|
|
89fb3fa619 | ||
|
|
9bd6abadf4 | ||
|
|
953a66ec47 | ||
|
|
4e826f4167 | ||
|
|
e97b90d4d7 | ||
|
|
fb6256d1ed | ||
|
|
7035a3fe9c | ||
|
|
62c29d55cc | ||
|
|
a83dbcf3ab | ||
|
|
e48bdcc45b | ||
|
|
0b473ef01f | ||
|
|
e03525a1d1 | ||
|
|
087172c79e | ||
|
|
8fd919bf04 | ||
|
|
2ad84db482 | ||
|
|
85536ff79e | ||
|
|
8b62c91d13 | ||
|
|
e7d1693517 | ||
|
|
e78b4882b3 | ||
|
|
e01144950b | ||
|
|
86ef665b12 | ||
|
|
f419a57e6d | ||
|
|
d7e8ec95de | ||
|
|
5a9bc1c66f | ||
|
|
1f9af8df89 | ||
|
|
0676b6c41f | ||
|
|
ac842e6273 | ||
|
|
ce8cdced4d | ||
|
|
b8e3fc636c | ||
|
|
519a5615cc | ||
|
|
168b217553 | ||
|
|
7d698d63e3 | ||
|
|
035dbde819 | ||
|
|
c373d8b2d6 | ||
|
|
8698c3c6a4 | ||
|
|
0edd2ba68b | ||
|
|
b91f0b5a18 | ||
|
|
24fa841c0d | ||
|
|
44558b8109 | ||
|
|
478b40d0ff | ||
|
|
8b816dc725 | ||
|
|
81a58f628b | ||
|
|
e98c9b46f1 | ||
|
|
b3ce7acfcb | ||
|
|
9fac79b1f0 | ||
|
|
591e3c5ca1 | ||
|
|
35d407afef | ||
|
|
a6447165b7 | ||
|
|
23800bb892 | ||
|
|
b47cb91f55 | ||
|
|
2d9e3fbc1d | ||
|
|
bf67e27737 | ||
|
|
3427c97e3e | ||
|
|
81e69a7166 | ||
|
|
564098b9d8 | ||
|
|
ec659174fb | ||
|
|
1a42d8280c | ||
|
|
b14f10d79d | ||
|
|
ee8facd1bf | ||
|
|
811657b553 | ||
|
|
95936f7c29 | ||
|
|
613d4cd9af | ||
|
|
7beb3d9974 | ||
|
|
6f2bb7f0b5 | ||
|
|
315b5fda91 | ||
|
|
a6aa89e502 | ||
|
|
3bf722c5fe | ||
|
|
e931c09a34 | ||
|
|
f8f5f35cc1 | ||
|
|
524941da0c | ||
|
|
22bba922f9 | ||
|
|
d928df7ab2 | ||
|
|
4b11bbe21f | ||
|
|
18bcd55972 | ||
|
|
057f306ed9 | ||
|
|
76bbb3f147 | ||
|
|
0f3ad8bb69 | ||
|
|
1d47b9074f | ||
|
|
5167fde080 | ||
|
|
a62648ee68 | ||
|
|
5dee414596 | ||
|
|
8cf9b1f905 | ||
|
|
6bf1920160 | ||
|
|
33f8070e57 | ||
|
|
4d2a018032 | ||
|
|
ca7fb540ee | ||
|
|
beb0712ce9 | ||
|
|
a081b14794 | ||
|
|
e416acf6bd | ||
|
|
bf94f76509 | ||
|
|
ac239a309c | ||
|
|
0f12586166 | ||
|
|
b1b50ce561 | ||
|
|
8e2bf48ab4 | ||
|
|
6ec5022a0d | ||
|
|
ef97e0ac76 | ||
|
|
30736a055d | ||
|
|
d0905a29be | ||
|
|
fe5cf69b7a |
40
.drone.yml
@@ -9,23 +9,28 @@ steps:
|
||||
commands:
|
||||
- git fetch --tags
|
||||
- name: release
|
||||
image: golang:latest
|
||||
image: hrfee/jfa-go-build-docker:latest
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /id_rsa
|
||||
environment:
|
||||
BUILDRONE_KEY:
|
||||
from_secret: BUILDRONE_KEY
|
||||
GITHUB_TOKEN:
|
||||
from_secret: github_token
|
||||
commands:
|
||||
- apt-get update -y
|
||||
- apt-get install build-essential python3-pip curl software-properties-common sed upx -y
|
||||
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
|
||||
- apt-get install nodejs
|
||||
- curl -sL https://git.io/goreleaser > ../goreleaser
|
||||
- chmod +x ../goreleaser
|
||||
- ./scripts/version.sh ../goreleaser
|
||||
- wget https://builds.hrfee.pw/upload.py -P ../
|
||||
- pip3 install requests
|
||||
- bash -c 'sftp -P 2022 -i /id_rsa -o StrictHostKeyChecking=no root@161.97.102.153:/repo/incoming <<< $"put dist/*.deb"'
|
||||
- bash -c 'ssh -i /id_rsa root@161.97.102.153 -p 2022 "repo-process-deb trusty"'
|
||||
- bash -c 'python3 ../upload.py https://builds.hrfee.pw hrfee jfa-go --tag internal=true'
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/id_rsa_packaging
|
||||
trigger:
|
||||
event:
|
||||
- tag
|
||||
@@ -71,22 +76,29 @@ type: docker
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:latest
|
||||
image: hrfee/jfa-go-build-docker:latest
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
path: /id_rsa
|
||||
commands:
|
||||
- apt-get update -y
|
||||
- apt-get install build-essential python3-pip curl software-properties-common sed upx -y
|
||||
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
|
||||
- apt-get install nodejs
|
||||
- curl -sL https://git.io/goreleaser > goreleaser
|
||||
- chmod +x goreleaser
|
||||
- ./scripts/version.sh ./goreleaser --snapshot --skip-publish --rm-dist
|
||||
- wget https://builds.hrfee.pw/upload.py
|
||||
- pip3 install requests
|
||||
- bash -c 'python3 upload.py https://builds.hrfee.pw hrfee jfa-go --upload ./dist/*.tar.gz --tag internal-git=true'
|
||||
- bash -c 'sftp -P 2022 -i /id_rsa -o StrictHostKeyChecking=no root@161.97.102.153:/repo/incoming <<< $"put dist/*.deb"'
|
||||
# - bash -c 'ssh -i /id_rsa root@161.97.102.153 -p 2022 "reprepro -Vb /repo remove trusty-unstable jfa-go"'
|
||||
# - bash -c 'ssh -i /id_rsa root@161.97.102.153 -p 2022 "reprepro -Vb /repo remove trusty-unstable jfa-go-tray"'
|
||||
- bash -c 'ssh -i /id_rsa root@161.97.102.153 -p 2022 "repo-process-deb trusty"'
|
||||
- bash -c 'python3 upload.py https://builds.hrfee.pw hrfee jfa-go --upload ./dist/*.zip ./dist/*.rpm ./dist/*.apk --tag internal-git=true'
|
||||
environment:
|
||||
BUILDRONE_KEY:
|
||||
from_secret: BUILDRONE_KEY
|
||||
|
||||
volumes:
|
||||
- name: ssh_key
|
||||
host:
|
||||
path: /root/.ssh/id_rsa_packaging
|
||||
trigger:
|
||||
branch:
|
||||
- main
|
||||
@@ -141,12 +153,8 @@ type: docker
|
||||
|
||||
steps:
|
||||
- name: build
|
||||
image: golang:latest
|
||||
image: hrfee/jfa-go-build-docker:latest
|
||||
commands:
|
||||
- apt-get update -y
|
||||
- apt-get install build-essential python3-pip curl software-properties-common sed upx -y
|
||||
- (curl -sL https://deb.nodesource.com/setup_14.x | bash -)
|
||||
- apt-get install nodejs
|
||||
- curl -sL https://git.io/goreleaser > goreleaser
|
||||
- chmod +x goreleaser
|
||||
- ./scripts/version.sh ./goreleaser --snapshot --skip-publish --rm-dist
|
||||
|
||||
3
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -19,8 +19,11 @@ What to do to reproduce the problem.
|
||||
|
||||
**Logs**
|
||||
|
||||
**If you're using a build with a tray icon, right-click on it and press "Open logs" to access your logs.**
|
||||
|
||||
When you notice the problem, check the output of `jfa-go`. If the problem is not obvious (e.g a panic (red text) or 'ERROR' log), re-run jfa-go with the `-debug` argument and reproduce the problem. You should then take a screenshot of the output, or paste it here, preferably between \`\`\` tags (e.g \`\`\``Log here`\`\`\`). Remember to censor any personal information.
|
||||
|
||||
|
||||
If nothing catches your eye in the log, access the admin page via your browser, go into the console (Right click > Inspect Element > Console), refresh, reproduce the problem then paste the output here in the same way as above.
|
||||
|
||||
**Configuration**
|
||||
|
||||
4
.gitignore
vendored
@@ -1,4 +1,6 @@
|
||||
node_modules/
|
||||
site/node_modules/
|
||||
site/out/
|
||||
mail/*.html
|
||||
dist/
|
||||
build/
|
||||
@@ -15,3 +17,5 @@ server.crt
|
||||
instructions-debian.txt
|
||||
cl.md
|
||||
./telegram/
|
||||
mautrix/
|
||||
matacc.txt
|
||||
|
||||
118
.goreleaser.yml
@@ -25,24 +25,81 @@ before:
|
||||
- npx esbuild --bundle ts/pwr.ts --outfile=./data/web/js/pwr.js --minify
|
||||
- npx esbuild --bundle ts/form.ts --outfile=./data/web/js/form.js --minify
|
||||
- npx esbuild --bundle ts/setup.ts --outfile=./data/web/js/setup.js --minify
|
||||
- npx esbuild --bundle ts/crash.ts --outfile=./data/crash.js --minify
|
||||
- cp html/crash.html data/
|
||||
- npx uncss data/crash.html --csspath web/css --output data/bundle.css
|
||||
- npx inline-source --root data data/crash.html data/crash.html
|
||||
- rm data/bundle.css
|
||||
- mv data/crash.html data/html/
|
||||
- go get -u github.com/swaggo/swag/cmd/swag
|
||||
- swag init -g main.go
|
||||
builds:
|
||||
- dir: ./
|
||||
- id: notray
|
||||
dir: ./
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Env.JFA_GO_VERSION}} -X main.commit={{.ShortCommit}} -X main.updater=binary
|
||||
goos:
|
||||
- linux
|
||||
- windows
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- arm
|
||||
- arm64
|
||||
- amd64
|
||||
- id: windows-tray
|
||||
dir: ./
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
- CC=x86_64-w64-mingw32-gcc
|
||||
- CXX=x86_64-w64-mingw32-g++
|
||||
flags:
|
||||
- -tags=tray
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Env.JFA_GO_VERSION}} -X main.commit={{.ShortCommit}} -X main.updater=binary -H=windowsgui
|
||||
goos:
|
||||
- windows
|
||||
goarch:
|
||||
- amd64
|
||||
- id: linux-tray
|
||||
dir: ./
|
||||
env:
|
||||
- CGO_ENABLED=1
|
||||
flags:
|
||||
- -tags=tray
|
||||
ldflags:
|
||||
- -s -w -X main.version={{.Env.JFA_GO_VERSION}} -X main.commit={{.ShortCommit}} -X main.updater=binary
|
||||
goos:
|
||||
- linux
|
||||
goarch:
|
||||
- amd64
|
||||
archives:
|
||||
- replacements:
|
||||
- id: windows-tray
|
||||
builds:
|
||||
- windows-tray
|
||||
format: zip
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_TrayIcon_{{ .Os }}_{{ .Arch }}"
|
||||
replacements:
|
||||
darwin: macOS
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
amd64: x86_64
|
||||
- id: linux-tray
|
||||
builds:
|
||||
- linux-tray
|
||||
format: zip
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_TrayIcon_{{ .Os }}_{{ .Arch }}"
|
||||
replacements:
|
||||
darwin: macOS
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
amd64: x86_64
|
||||
- id: notray
|
||||
builds:
|
||||
- notray
|
||||
format: zip
|
||||
name_template: "{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}"
|
||||
replacements:
|
||||
darwin: macOS
|
||||
linux: Linux
|
||||
windows: Windows
|
||||
@@ -50,10 +107,61 @@ archives:
|
||||
checksum:
|
||||
name_template: 'checksums.txt'
|
||||
snapshot:
|
||||
name_template: "git-{{.ShortCommit}}"
|
||||
name_template: "0.0.0-{{ .Env.JFA_GO_NFPM_EPOCH }}"
|
||||
changelog:
|
||||
sort: asc
|
||||
filters:
|
||||
exclude:
|
||||
- '^docs:'
|
||||
- '^test:'
|
||||
nfpms:
|
||||
- id: notray
|
||||
file_name_template: '{{ .ProjectName }}{{ if .IsSnapshot }}-git{{ end }}_{{ .Arch }}_{{ if .IsSnapshot }}{{ .ShortCommit }}{{ else }}v{{ .Version }}{{ end }}'
|
||||
package_name: jfa-go
|
||||
homepage: https://github.com/hrfee/jfa-go
|
||||
description: A web app for managing users on Jellyfin
|
||||
maintainer: Harvey Tindall <hrfee@hrfee.dev>
|
||||
license: MIT
|
||||
vendor: hrfee.dev
|
||||
version_metadata: git
|
||||
builds:
|
||||
- notray
|
||||
contents:
|
||||
- src: ./LICENSE
|
||||
dst: /usr/share/licenses/jfa-go
|
||||
formats:
|
||||
- apk
|
||||
- deb
|
||||
- rpm
|
||||
- id: tray
|
||||
file_name_template: '{{ .ProjectName }}{{ if .IsSnapshot }}-git{{ end }}_TrayIcon_{{ .Arch }}_{{ if .IsSnapshot }}{{ .ShortCommit }}{{ else }}v{{ .Version }}{{ end }}'
|
||||
package_name: jfa-go-tray
|
||||
homepage: https://github.com/hrfee/jfa-go
|
||||
description: A web app for managing users on Jellyfin
|
||||
maintainer: Harvey Tindall <hrfee@hrfee.dev>
|
||||
license: MIT
|
||||
vendor: hrfee.dev
|
||||
version_metadata: git
|
||||
builds:
|
||||
- linux-tray
|
||||
contents:
|
||||
- src: ./LICENSE
|
||||
dst: /usr/share/licenses/jfa-go
|
||||
formats:
|
||||
- apk
|
||||
- deb
|
||||
- rpm
|
||||
overrides:
|
||||
deb:
|
||||
conflicts:
|
||||
- jfa-go
|
||||
replaces:
|
||||
- jfa-go
|
||||
dependencies:
|
||||
- libappindicator3-1
|
||||
rpm:
|
||||
dependencies:
|
||||
- libappindicator-gtk3
|
||||
apk:
|
||||
dependencies:
|
||||
- libappindicator
|
||||
|
||||
@@ -1,15 +1,44 @@
|
||||
#### Code
|
||||
---
|
||||
title: "Building/Contributing for developers"
|
||||
date: 2021-07-25T00:33:36+01:00
|
||||
draft: false
|
||||
---
|
||||
# Code
|
||||
I use 4 spaces for indentation. Go should ideally be formatted with `goimports` and/or `gofmt`. I don't use a formatter on typescript, so don't worry about that.
|
||||
|
||||
#### Compiling
|
||||
Code in Go should ideally use `PascalCase` for exported values, and `camelCase` for non-exported, JSON for transferring data should use `snake_case`, and Typescript should use `camelCase`. Forgive me for my many inconsistencies in this, and feel free to fix them if you want.
|
||||
|
||||
Prefix each of these with `make DEBUG=on INTERNAL=off `:
|
||||
Functions in Go that need to access `*appContext` should be generally be receivers, except when the behaviour could be seen as somewhat independent from it (`email.go` is the best example, its behaviour is broadly independent from the main app except from a couple config values).
|
||||
|
||||
|
||||
# Compiling
|
||||
|
||||
The Makefile is more suited towards development than other build methods, and provides separate build stages to speed up compilation when only making changes to specific aspects of the project.
|
||||
|
||||
Prefix each of these with `make DEBUG=on `:
|
||||
* `all` will download deps and build everything. The executable and data will be placed in `build`. This is only necessary the first time.
|
||||
* `npm` will download all node.js build-time dependencies.
|
||||
* `compile` will only compile go code into the `build/jfa-go` executable.
|
||||
* `typescript` will compile typescript w/ sourcemaps into `build/data/web/js`.
|
||||
* `bundle-css` will bundle CSS and place it in `build/data/web/css`.
|
||||
* `inline` will inline the css and javascript used in the single-file crash report webpage.
|
||||
* `configuration` will generate the `config-base.json` (used to render settings in the web ui) and `config-default.ini` and put them in `build/data`.
|
||||
* `email` will compile email mjml, and copy the text versions in to `build/data`.
|
||||
* `swagger`: generates swagger documentation for the API.
|
||||
* `copy` will copy iconography, html, language files and static data into `build/data`.
|
||||
|
||||
See the [wiki](https://github.com/hrfee/jfa-go/wiki/Build) for more info.
|
||||
## Environment variables
|
||||
|
||||
* `DEBUG=on/off`: If on, compiles with type-checking for typescript, sourcemaps, non-minified css and no symbol stripping.
|
||||
* `INTERNAL=on/off`: Whether or not to embed file assets into the binary itself, or store them separately beside the binary.
|
||||
* `UPDATER=on/off/docker`: Enable/Disable the updater, or set a special update type (currently only docker, which disables self-updating the binary).
|
||||
* `TRAY=on/off`: Enable/disable the tray icon, which lets you start/stop/autostart on login. For linux, requires `libappindicator3-dev` for debian or the equivalent on other distributions.
|
||||
* `GOESBUILD=on`: Use a locally installed `esbuild` binary. NPM doesn't provide builds for all os/architectures, so `npx esbuild` might not work for you, so the binary is compiled/installed with `go get`.
|
||||
* `GOBINARY=<path to go>`: Alternative path to go executable. Useful for testing with unstable go releases.
|
||||
* `VERSION=v<semver>`: Alternative verision number, useful to test update functionality.
|
||||
* `COMMIT=<short commit>`: Self explanatory.
|
||||
* `LDFLAGS=<ldflags>`: Passed to `go build -ldflags`.
|
||||
* `E2EE=on/off`: Enable/disable end-to-end encryption support for Matrix, which is currently very broken. Must subsequently be enabled (with Advanced settings enabled) in Settings > Matrix.
|
||||
* `TAGS=<tags>`: Passed to `go build -tags`.
|
||||
* `OS=<os>`: Unrelated to GOOS, if set to `windows`, `-H=windowsgui` is passed to ldflags, which stops a windows terminal popping up when run.
|
||||
* `RACE=on/off`: If on, compiles with the go race detector included.
|
||||
|
||||
@@ -6,7 +6,7 @@ RUN apt-get update -y \
|
||||
&& apt-get install build-essential python3-pip curl software-properties-common sed -y \
|
||||
&& (curl -sL https://deb.nodesource.com/setup_14.x | bash -) \
|
||||
&& apt-get install nodejs \
|
||||
&& (cd /opt/build; make configuration npm email typescript bundle-css swagger copy INTERNAL=off GOESBUILD=on) \
|
||||
&& (cd /opt/build; make configuration npm email typescript bundle-css inline swagger copy INTERNAL=off GOESBUILD=on) \
|
||||
&& sed -i 's#id="password_resets-watch_directory" placeholder="/config/jellyfin"#id="password_resets-watch_directory" value="/jf" disabled#g' /opt/build/build/data/html/setup.html
|
||||
|
||||
|
||||
|
||||
3
LICENSE
@@ -1,3 +1,5 @@
|
||||
---jfa-go---
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2021 Harvey Tindall
|
||||
@@ -19,3 +21,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
|
||||
47
Makefile
@@ -18,26 +18,55 @@ else ifneq ($(UPDATER), off)
|
||||
LDFLAGS := $(LDFLAGS) -X main.updater=$(UPDATER)
|
||||
endif
|
||||
|
||||
|
||||
|
||||
INTERNAL ?= on
|
||||
TRAY ?= off
|
||||
E2EE ?= off
|
||||
TAGS := -tags "
|
||||
|
||||
ifeq ($(INTERNAL), on)
|
||||
TAGS :=
|
||||
DATA := data
|
||||
else
|
||||
DATA := build/data
|
||||
TAGS := -tags external
|
||||
TAGS := $(TAGS) external
|
||||
endif
|
||||
|
||||
ifeq ($(TRAY), on)
|
||||
TAGS := $(TAGS) tray
|
||||
endif
|
||||
|
||||
ifeq ($(E2EE), on)
|
||||
TAGS := $(TAGS) e2ee
|
||||
endif
|
||||
|
||||
TAGS := $(TAGS)"
|
||||
|
||||
OS := $(shell go env GOOS)
|
||||
ifeq ($(TRAY)$(OS), onwindows)
|
||||
LDFLAGS := $(LDFLAGS) -H=windowsgui
|
||||
endif
|
||||
|
||||
DEBUG ?= off
|
||||
ifeq ($(DEBUG), on)
|
||||
LDFLAGS := -s -w $(LDFLAGS)
|
||||
SOURCEMAP := --sourcemap
|
||||
TYPECHECK := tsc -noEmit --project ts/tsconfig.json
|
||||
# jank
|
||||
COPYTS := rm -r $(DATA)/web/js/ts; cp -r ts $(DATA)/web/js
|
||||
UNCSS := cp $(DATA)/web/css/bundle.css $(DATA)/bundle.css
|
||||
else
|
||||
LDFLAGS := -s -w $(LDFLAGS)
|
||||
SOURCEMAP :=
|
||||
COPYTS :=
|
||||
TYPECHECK :=
|
||||
UNCSS := npx uncss $(DATA)/crash.html --csspath web/css --output $(DATA)/bundle.css
|
||||
endif
|
||||
|
||||
RACE ?= off
|
||||
ifeq ($(RACE), on)
|
||||
RACEDETECTOR := -race
|
||||
else
|
||||
RACEDETECTOR :=
|
||||
endif
|
||||
|
||||
npm:
|
||||
@@ -68,6 +97,7 @@ typescript:
|
||||
-$(ESBUILD) --bundle ts/pwr.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/pwr.js --minify
|
||||
-$(ESBUILD) --bundle ts/form.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/form.js --minify
|
||||
-$(ESBUILD) --bundle ts/setup.ts $(SOURCEMAP) --outfile=./$(DATA)/web/js/setup.js --minify
|
||||
-$(ESBUILD) --bundle ts/crash.ts --outfile=./$(DATA)/crash.js --minify
|
||||
$(COPYTS)
|
||||
|
||||
swagger:
|
||||
@@ -79,7 +109,7 @@ compile:
|
||||
$(GOBINARY) mod download
|
||||
$(info Building)
|
||||
mkdir -p build
|
||||
CGO_ENABLED=0 $(GOBINARY) build -ldflags="-s -w $(LDFLAGS)" $(TAGS) -o build/jfa-go
|
||||
$(GOBINARY) build $(RACEDETECTOR) -ldflags="$(LDFLAGS)" $(TAGS) -o build/jfa-go
|
||||
|
||||
compress:
|
||||
upx --lzma build/jfa-go
|
||||
@@ -89,11 +119,18 @@ bundle-css:
|
||||
$(info bundling css)
|
||||
$(ESBUILD) --bundle css/base.css --outfile=$(DATA)/web/css/bundle.css --external:remixicon.css --minify
|
||||
|
||||
inline:
|
||||
cp html/crash.html $(DATA)/crash.html
|
||||
$(UNCSS)
|
||||
npx inline-source --root $(DATA) $(DATA)/crash.html $(DATA)/crash.html
|
||||
rm $(DATA)/bundle.css
|
||||
|
||||
copy:
|
||||
$(info copying fonts)
|
||||
cp -r node_modules/remixicon/fonts/remixicon.css node_modules/remixicon/fonts/remixicon.woff2 $(DATA)/web/css/
|
||||
$(info copying html)
|
||||
cp -r html $(DATA)/
|
||||
mv $(DATA)/crash.html $(DATA)/html/
|
||||
$(info copying static data)
|
||||
-mkdir -p $(DATA)/web
|
||||
cp -r static/* $(DATA)/web/
|
||||
@@ -122,4 +159,4 @@ clean:
|
||||
-rm docs/docs.go docs/swagger.json docs/swagger.yaml
|
||||
go clean
|
||||
|
||||
all: configuration npm email typescript bundle-css swagger copy compile
|
||||
all: configuration npm email typescript bundle-css inline swagger copy compile
|
||||
|
||||
83
README.md
@@ -1,15 +1,19 @@
|
||||

|
||||
[](https://drone.hrfee.dev/hrfee/jfa-go)
|
||||
[](https://hub.docker.com/r/hrfee/jfa-go)
|
||||
[](https://weblate.hrfee.pw/engage/jfa-go/)
|
||||
[](https://weblate.jfa-go.com/engage/jfa-go/)
|
||||
[](https://wiki.jfa-go.com)
|
||||
|
||||
##### Downloads:
|
||||
##### [dockerhub](https://hub.docker.com/r/hrfee/jfa-go) | [stable](https://github.com/hrfee/jfa-go/releases) | [nightly](https://builds.hrfee.pw/view/hrfee/jfa-go) | [aur stable](https://aur.archlinux.org/packages/jfa-go) | [aur binary](https://aur.archlinux.org/packages/jfa-go-bin) | [aur nightly](https://aur.archlinux.org/packages/jfa-go-git)
|
||||
##### [docker](#docker) | [debian/ubuntu](#debian) | [arch (aur)](#aur) | [other platforms](#other-platforms)
|
||||
---
|
||||
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.
|
||||
|
||||
a rewrite of [jellyfin-accounts](https://github.com/hrfee/jellyfin-accounts) (original naming for both, ik
|
||||
😂).
|
||||
|
||||
#### Features
|
||||
* 🧑 Invite based account creation: Sends invites to your friends or family, and let them choose their own username and password without relying on you.
|
||||
* 🧑 Invite based account creation: Send invites to your friends or family, and let them choose their own username and password without relying on you.
|
||||
* Send invites via a link and/or email
|
||||
* 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.
|
||||
@@ -17,7 +21,7 @@ jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jelly
|
||||
* ⌛ 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 Integration: Verify users via telegram, and send Password Resets, Announcements, etc. through it.
|
||||
* 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.
|
||||
@@ -43,7 +47,9 @@ jfa-go is a user management app for [Jellyfin](https://github.com/jellyfin/jelly
|
||||
|
||||
#### Install
|
||||
|
||||
The [Docker](https://hub.docker.com/r/hrfee/jfa-go) image is your best bet.
|
||||
**Note**: `TrayIcon` builds include a tray icon to start/stop/restart, and an option to automatically start when you log-in to your computer. For Linux users, these builds depend on the `libappindicator3-1`/`libappindicator-gtk3`/`libappindicator` package for Debian/Ubuntu, Fedora, and Alpine respectively.
|
||||
|
||||
##### [Docker](https://hub.docker.com/r/hrfee/jfa-go)
|
||||
```sh
|
||||
docker create \
|
||||
--name "jfa-go" \ # Whatever you want to name it
|
||||
@@ -54,9 +60,41 @@ docker create \
|
||||
-v /etc/localtime:/etc/localtime:ro \ # Makes sure time is correct
|
||||
hrfee/jfa-go # hrfee/jfa-go:unstable for latest build from git
|
||||
```
|
||||
Available on the AUR as [jfa-go](https://aur.archlinux.org/packages/jfa-go/), [jfa-go-bin](https://aur.archlinux.org/packages/jfa-go) or [jfa-go-git](https://aur.archlinux.org/packages/jfa-go-git/).
|
||||
|
||||
For other platforms, grab an archive from the release section for your platform (or nightly builds [here](https://builds.hrfee.dev/view/hrfee/jfa-go)), and extract the `jfa-go` executable to somewhere useful.
|
||||
##### [Debian/Ubuntu](https://apt.hrfee.dev)
|
||||
```sh
|
||||
sudo apt-get update && sudo apt-get install curl apt-transport-https gnupg
|
||||
curl https://apt.hrfee.dev/hrfee.pubkey.gpg | sudo apt-key add -
|
||||
|
||||
# For stable releases
|
||||
echo "deb https://apt.hrfee.dev trusty main" | sudo tee /etc/apt/sources.list.d/hrfee.list
|
||||
# ------
|
||||
# For unstable releases
|
||||
echo "deb https://apt.hrfee.dev trusty-unstable main" | sudo tee /etc/apt/sources.list.d/hrfee.list
|
||||
# ------
|
||||
|
||||
sudo apt-get update
|
||||
|
||||
# For servers
|
||||
sudo apt-get install jfa-go
|
||||
# ------
|
||||
# For desktops/servers with GUI (has dependencies)
|
||||
sudo apt-get install jfa-go-tray
|
||||
# ------
|
||||
```
|
||||
|
||||
##### Arch
|
||||
Available on the AUR as:
|
||||
* [jfa-go](https://aur.archlinux.org/packages/jfa-go/) (stable)
|
||||
* [jfa-go-bin](https://aur.archlinux.org/packages/jfa-go) (pre-compiled, stable)
|
||||
* [jfa-go-git](https://aur.archlinux.org/packages/jfa-go-git/) (nightly)
|
||||
|
||||
##### Other platforms
|
||||
Download precompiled binaries from:
|
||||
* [The releases section](https://github.com/hrfee/jfa-go/releases) (stable)
|
||||
* [Buildrone](https://builds.hrfee.dev/view/hrfee/jfa-go) (nightly)
|
||||
|
||||
unzip the `jfa-go`/`jfa-go.exe` executable to somewhere useful.
|
||||
* For \*nix/macOS users, `chmod +x jfa-go` then place it somewhere in your PATH like `/usr/bin`.
|
||||
|
||||
Run the executable to start.
|
||||
@@ -65,23 +103,34 @@ Run the executable to start.
|
||||
#### Build from source
|
||||
If you're using docker, a Dockerfile is provided that builds from source.
|
||||
|
||||
Otherwise, full build instructions can be found [here](https://github.com/hrfee/jfa-go/wiki/Build).
|
||||
Otherwise, full build instructions can be found [here](https://wiki.jfa-go.com/docs/build/).
|
||||
|
||||
#### Usage
|
||||
Simply run `jfa-go` to start the application. A setup wizard will start on `localhost:8056` (or your own specified address). Upon completion, refresh the page.
|
||||
|
||||
```
|
||||
Usage of ./jfa-go:
|
||||
-config string
|
||||
alternate path to config file. (default "~/.config/jfa-go/config.ini")
|
||||
-data string
|
||||
alternate path to data directory. (default "~/.config/jfa-go")
|
||||
Usage of jfa-go:
|
||||
start
|
||||
start jfa-go as a daemon and run in the background.
|
||||
stop
|
||||
stop a daemonized instance of jfa-go.
|
||||
systemd
|
||||
generate a systemd .service file.
|
||||
|
||||
-config, -c string
|
||||
alternate path to config file. (default "/home/hrfee/.config/jfa-go/config.ini")
|
||||
-data, -d string
|
||||
alternate path to data directory. (default "/home/hrfee/.config/jfa-go")
|
||||
-debug
|
||||
Enables debug logging and exposes pprof.
|
||||
Enables debug logging.
|
||||
-help, -h
|
||||
prints this message.
|
||||
-host string
|
||||
alternate address to host web ui on.
|
||||
-port int
|
||||
-port, -p int
|
||||
alternate port to host web ui on.
|
||||
-pprof
|
||||
Exposes pprof profiler on /debug/pprof.
|
||||
-swagger
|
||||
Enable swagger at /swagger/index.html
|
||||
```
|
||||
@@ -102,6 +151,6 @@ If you're switching from jellyfin-accounts, copy your existing `~/.jf-accounts`
|
||||
#### Contributing
|
||||
See [CONTRIBUTING.md](https://github.com/hrfee/jfa-go/blob/main/CONTRIBUTING.md).
|
||||
##### Translation
|
||||
[](https://weblate.hrfee.pw/engage/jfa-go/)
|
||||
[](https://weblate.jfa-go.com/engage/jfa-go/)
|
||||
|
||||
For translations, use the weblate instance [here](https://weblate.hrfee.pw/engage/jfa-go/). You can login with github.
|
||||
For translations, use the weblate instance [here](https://weblate.jfa-go.com/engage/jfa-go/). You can login with github.
|
||||
|
||||
12
auth.go
@@ -4,12 +4,11 @@ import (
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/golang-jwt/jwt"
|
||||
"github.com/lithammer/shortuuid/v3"
|
||||
)
|
||||
|
||||
@@ -23,17 +22,16 @@ func CreateToken(userId, jfId string) (string, string, error) {
|
||||
claims := jwt.MapClaims{
|
||||
"valid": true,
|
||||
"id": userId,
|
||||
"exp": strconv.FormatInt(time.Now().Add(time.Minute*20).Unix(), 10),
|
||||
"exp": time.Now().Add(time.Minute * 20).Unix(),
|
||||
"jfid": jfId,
|
||||
"type": "bearer",
|
||||
}
|
||||
|
||||
tk := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
token, err := tk.SignedString([]byte(os.Getenv("JFA_SECRET")))
|
||||
if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
claims["exp"] = strconv.FormatInt(time.Now().Add(time.Hour*24).Unix(), 10)
|
||||
claims["exp"] = time.Now().Add(time.Hour * 24).Unix()
|
||||
claims["type"] = "refresh"
|
||||
tk = jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
refresh, err = tk.SignedString([]byte(os.Getenv("JFA_SECRET")))
|
||||
@@ -58,7 +56,7 @@ func (app *appContext) authenticate(gc *gin.Context) {
|
||||
return
|
||||
}
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
expiryUnix, err := strconv.ParseInt(claims["exp"].(string), 10, 64)
|
||||
expiryUnix := int64(claims["exp"].(float64))
|
||||
if err != nil {
|
||||
app.debug.Printf("Auth denied: %s", err)
|
||||
respond(401, "Unauthorized", gc)
|
||||
@@ -200,7 +198,7 @@ func (app *appContext) getTokenRefresh(gc *gin.Context) {
|
||||
return
|
||||
}
|
||||
claims, ok := token.Claims.(jwt.MapClaims)
|
||||
expiryUnix, err := strconv.ParseInt(claims["exp"].(string), 10, 64)
|
||||
expiryUnix := int64(claims["exp"].(float64))
|
||||
if err != nil {
|
||||
app.debug.Printf("getTokenRefresh: Invalid token expiry: %s", err)
|
||||
respond(401, "Invalid token", gc)
|
||||
|
||||
69
autostart.go
Normal file
@@ -0,0 +1,69 @@
|
||||
// +build tray
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/emersion/go-autostart"
|
||||
"github.com/getlantern/systray"
|
||||
)
|
||||
|
||||
type Autostart struct {
|
||||
as *autostart.App
|
||||
enabled bool
|
||||
menuitem *systray.MenuItem
|
||||
clicked chan bool
|
||||
}
|
||||
|
||||
func NewAutostart(name, displayname, trayName, trayTooltip string) *Autostart {
|
||||
a := &Autostart{
|
||||
as: &autostart.App{
|
||||
Name: name,
|
||||
DisplayName: displayname,
|
||||
},
|
||||
enabled: true,
|
||||
clicked: make(chan bool),
|
||||
}
|
||||
a.menuitem = systray.AddMenuItemCheckbox(trayName, trayTooltip, a.as.IsEnabled())
|
||||
command := os.Args
|
||||
command[0], _ = filepath.Abs(command[0])
|
||||
// Make sure to replace any relative paths with absolute ones
|
||||
pathArgs := []string{"-d", "-data", "-c", "-config"}
|
||||
for i := 1; i < len(command); i++ {
|
||||
isPath := false
|
||||
for _, p := range pathArgs {
|
||||
if command[i-1] == p {
|
||||
isPath = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if isPath {
|
||||
command[i], _ = filepath.Abs(command[i])
|
||||
}
|
||||
}
|
||||
a.as.Exec = command
|
||||
return a
|
||||
}
|
||||
|
||||
func (a *Autostart) HandleCheck() {
|
||||
for range a.menuitem.ClickedCh {
|
||||
if !a.menuitem.Checked() {
|
||||
if err := a.as.Enable(); err != nil {
|
||||
log.Printf("Failed to enable autostart on login: %v", err)
|
||||
} else {
|
||||
a.menuitem.Check()
|
||||
log.Printf("Enabled autostart")
|
||||
}
|
||||
} else {
|
||||
if err := a.as.Disable(); err != nil {
|
||||
log.Printf("Failed to disable autostart on login: %v", err)
|
||||
} else {
|
||||
a.menuitem.Uncheck()
|
||||
log.Printf("Disabled autostart")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -12,7 +12,7 @@ type TimeoutHandler func()
|
||||
func NewTimeoutHandler(name, addr string, noFail bool) TimeoutHandler {
|
||||
return func() {
|
||||
if r := recover(); r != nil {
|
||||
out := fmt.Sprintf("Failed to authenticate with %s @ %s: Timed out", name, addr)
|
||||
out := fmt.Sprintf("Failed to authenticate with %s @ \"%s\": Timed out", name, addr)
|
||||
if noFail {
|
||||
log.Print(out)
|
||||
} else {
|
||||
|
||||
52
config.go
@@ -14,6 +14,8 @@ import (
|
||||
var emailEnabled = false
|
||||
var messagesEnabled = false
|
||||
var telegramEnabled = false
|
||||
var discordEnabled = false
|
||||
var matrixEnabled = false
|
||||
|
||||
func (app *appContext) GetPath(sect, key string) (fs.FS, string) {
|
||||
val := app.config.Section(sect).Key(key).MustString("")
|
||||
@@ -42,9 +44,12 @@ func (app *appContext) loadConfig() error {
|
||||
key.SetValue(key.MustString(filepath.Join(app.dataPath, (key.Name() + ".json"))))
|
||||
}
|
||||
}
|
||||
for _, key := range []string{"user_configuration", "user_displayprefs", "user_profiles", "ombi_template", "invites", "emails", "user_template", "custom_emails", "users", "telegram_users"} {
|
||||
for _, key := range []string{"user_configuration", "user_displayprefs", "user_profiles", "ombi_template", "invites", "emails", "user_template", "custom_emails", "users", "telegram_users", "discord_users", "matrix_users", "announcements"} {
|
||||
app.config.Section("files").Key(key).SetValue(app.config.Section("files").Key(key).MustString(filepath.Join(app.dataPath, (key + ".json"))))
|
||||
}
|
||||
for _, key := range []string{"matrix_sql"} {
|
||||
app.config.Section("files").Key(key).SetValue(app.config.Section("files").Key(key).MustString(filepath.Join(app.dataPath, (key + ".db"))))
|
||||
}
|
||||
app.URLBase = strings.TrimSuffix(app.config.Section("ui").Key("url_base").MustString(""), "/")
|
||||
app.config.Section("email").Key("no_username").SetValue(strconv.FormatBool(app.config.Section("email").Key("no_username").MustBool(false)))
|
||||
|
||||
@@ -66,6 +71,11 @@ func (app *appContext) loadConfig() error {
|
||||
app.MustSetValue("deletion", "email_html", "jfa-go:"+"deleted.html")
|
||||
app.MustSetValue("deletion", "email_text", "jfa-go:"+"deleted.txt")
|
||||
|
||||
jfUrl := app.config.Section("jellyfin").Key("server").String()
|
||||
if !(strings.HasPrefix(jfUrl, "http://") || strings.HasPrefix(jfUrl, "https://")) {
|
||||
app.config.Section("jellyfin").Key("server").SetValue("http://" + jfUrl)
|
||||
}
|
||||
|
||||
// Deletion template is good enough for these as well.
|
||||
app.MustSetValue("disable_enable", "disabled_html", "jfa-go:"+"deleted.html")
|
||||
app.MustSetValue("disable_enable", "disabled_text", "jfa-go:"+"deleted.txt")
|
||||
@@ -82,20 +92,33 @@ func (app *appContext) loadConfig() error {
|
||||
app.MustSetValue("user_expiry", "email_html", "jfa-go:"+"user-expired.html")
|
||||
app.MustSetValue("user_expiry", "email_text", "jfa-go:"+"user-expired.txt")
|
||||
|
||||
app.MustSetValue("matrix", "topic", "Jellyfin notifications")
|
||||
|
||||
app.config.Section("jellyfin").Key("version").SetValue(version)
|
||||
app.config.Section("jellyfin").Key("device").SetValue("jfa-go")
|
||||
app.config.Section("jellyfin").Key("device_id").SetValue(fmt.Sprintf("jfa-go-%s-%s", version, commit))
|
||||
|
||||
// These two settings are pretty much the same
|
||||
url1 := app.config.Section("invite_emails").Key("url_base").String()
|
||||
url2 := app.config.Section("password_resets").Key("url_base").String()
|
||||
app.MustSetValue("password_resets", "url_base", strings.TrimSuffix(url1, "/invite"))
|
||||
app.MustSetValue("invite_emails", "url_base", url2)
|
||||
|
||||
messagesEnabled = app.config.Section("messages").Key("enabled").MustBool(false)
|
||||
telegramEnabled = app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
discordEnabled = app.config.Section("discord").Key("enabled").MustBool(false)
|
||||
matrixEnabled = app.config.Section("matrix").Key("enabled").MustBool(false)
|
||||
if !messagesEnabled {
|
||||
emailEnabled = false
|
||||
telegramEnabled = false
|
||||
discordEnabled = false
|
||||
matrixEnabled = false
|
||||
} else if app.config.Section("email").Key("method").MustString("") == "" {
|
||||
emailEnabled = false
|
||||
} else {
|
||||
emailEnabled = true
|
||||
}
|
||||
if !emailEnabled && !telegramEnabled {
|
||||
if !emailEnabled && !telegramEnabled && !discordEnabled && !matrixEnabled {
|
||||
messagesEnabled = false
|
||||
}
|
||||
|
||||
@@ -143,28 +166,3 @@ func (app *appContext) loadConfig() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (app *appContext) migrateEmailConfig() {
|
||||
tempConfig, _ := ini.Load(app.configPath)
|
||||
fmt.Println(warning("Part of your email configuration will be migrated to the new \"messages\" section.\nA backup will be made."))
|
||||
err := tempConfig.SaveTo(app.configPath + "_" + commit + ".bak")
|
||||
if err != nil {
|
||||
app.err.Fatalf("Failed to backup config: %v", err)
|
||||
return
|
||||
}
|
||||
for _, setting := range []string{"use_24h", "date_format", "message"} {
|
||||
if val := app.config.Section("email").Key(setting).Value(); val != "" {
|
||||
tempConfig.Section("email").Key(setting).SetValue("")
|
||||
tempConfig.Section("messages").Key(setting).SetValue(val)
|
||||
}
|
||||
}
|
||||
if app.config.Section("messages").Key("enabled").MustBool(false) || app.config.Section("telegram").Key("enabled").MustBool(false) {
|
||||
tempConfig.Section("messages").Key("enabled").SetValue("true")
|
||||
}
|
||||
err = tempConfig.SaveTo(app.configPath)
|
||||
if err != nil {
|
||||
app.err.Fatalf("Failed to save config: %v", err)
|
||||
return
|
||||
}
|
||||
app.loadConfig()
|
||||
}
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
["en-us", "English (US)"]
|
||||
],
|
||||
"value": "en-us",
|
||||
"description": "Default Account Form Language. Visit weblate.hrfee.dev if you'd like to translate."
|
||||
"description": "Default Account Form Language. Visit weblate.jfa-go.com if you'd like to translate."
|
||||
},
|
||||
"language-admin": {
|
||||
"name": "Default Admin Language",
|
||||
@@ -135,7 +135,7 @@
|
||||
["en-us", "English (US)"]
|
||||
],
|
||||
"value": "en-us",
|
||||
"description": "Default Admin page Language. Settings has not been translated. Visit weblate.hrfee.dev if you'd like to translate."
|
||||
"description": "Default Admin page Language. Settings has not been translated. Visit weblate.jfa-go.com if you'd like to translate."
|
||||
},
|
||||
"theme": {
|
||||
"name": "Default Look",
|
||||
@@ -246,7 +246,7 @@
|
||||
"requires_restart": true,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "URL base for when running jfa-go with a reverse proxy in a subfolder."
|
||||
"description": "URL base for when running jfa-go with a reverse proxy in a subfolder. include preceding /, e.g \"/accounts\"."
|
||||
}
|
||||
}
|
||||
},
|
||||
@@ -546,11 +546,94 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"discord": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
"name": "Discord",
|
||||
"description": "Settings for Discord invites/signup/notifications"
|
||||
},
|
||||
"settings": {
|
||||
"enabled": {
|
||||
"name": "Enabled",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Enable signup verification through Discord and the sending of notifications through it.\nSee the jfa-go wiki for setting up a bot."
|
||||
},
|
||||
"required": {
|
||||
"name": "Require on sign-up",
|
||||
"required": false,
|
||||
"required_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Require Discord connection on sign-up. See the jfa-go wiki for info on setting this up."
|
||||
},
|
||||
"token": {
|
||||
"name": "API Token",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Discord Bot API Token."
|
||||
},
|
||||
"start_command": {
|
||||
"name": "Start command",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "!start",
|
||||
"description": "Command to start the user verification process."
|
||||
},
|
||||
"channel": {
|
||||
"name": "Channel to monitor",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Only listen to commands in specified channel. Leave blank to monitor all."
|
||||
},
|
||||
"provide_invite": {
|
||||
"name": "Provide server invite",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Generate a one-time discord server invite for the account creation form. Required Bot permission \"Create instant invite\", you may need to re-add the bot to your server after."
|
||||
},
|
||||
"invite_channel": {
|
||||
"name": "Invite channel",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "provide_invite",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Channel to invite new users to."
|
||||
},
|
||||
"language": {
|
||||
"name": "Language",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"depends_true": "enabled",
|
||||
"type": "select",
|
||||
"options": [
|
||||
["en-us", "English (US)"]
|
||||
],
|
||||
"value": "en-us",
|
||||
"description": "Default Discord message language. Visit weblate if you'd like to translate."
|
||||
}
|
||||
}
|
||||
},
|
||||
"telegram": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
"name": "Telegram",
|
||||
"description": "Settings for Telegram signup/notifications"
|
||||
"description": "Settings for Telegram signup/notifications. See the jfa-go wiki for info on setting this up."
|
||||
},
|
||||
"settings": {
|
||||
"enabled": {
|
||||
@@ -565,6 +648,7 @@
|
||||
"name": "Require on sign-up",
|
||||
"required": false,
|
||||
"required_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Require telegram connection on sign-up."
|
||||
@@ -592,6 +676,90 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"matrix": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
"name": "Matrix",
|
||||
"description": "Settings for Matrix invites/signup/notifications. See the jfa-go wiki for info on setting this up."
|
||||
},
|
||||
"settings": {
|
||||
"enabled": {
|
||||
"name": "Enabled",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Enable signup verification through Matrix and the sending of notifications through it.\nSee the jfa-go wiki for setting up a bot."
|
||||
},
|
||||
"required": {
|
||||
"name": "Require on sign-up",
|
||||
"required": false,
|
||||
"required_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Require Matrix connection on sign-up."
|
||||
},
|
||||
"homeserver": {
|
||||
"name": "Home Server URL",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Matrix Home server URL."
|
||||
},
|
||||
"token": {
|
||||
"name": "Access Token",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Matrix Bot API Token."
|
||||
},
|
||||
"user_id": {
|
||||
"name": "Bot User ID",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "User ID of bot account (Example: @jfa-bot:riot.im)"
|
||||
},
|
||||
"topic": {
|
||||
"name": "Chat topic",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "Jellyfin notifications",
|
||||
"description": "Topic of Matrix private chats."
|
||||
},
|
||||
"language": {
|
||||
"name": "Language",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"depends_true": "enabled",
|
||||
"type": "select",
|
||||
"options": [
|
||||
["en-us", "English (US)"]
|
||||
],
|
||||
"value": "en-us",
|
||||
"description": "Default Matrix message language. Visit weblate if you'd like to translate."
|
||||
},
|
||||
"encryption": {
|
||||
"name": "End-to-end encryption (experimental)",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "enabled",
|
||||
"advanced": true,
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Enable end-to-end encryption for messages. Very experimental, currently does not support receiving commands (e.g !lang)."
|
||||
}
|
||||
}
|
||||
},
|
||||
"password_resets": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
@@ -626,6 +794,24 @@
|
||||
"value": false,
|
||||
"description": "Send users a link to reset their password instead of a PIN. Must be enabled to reset Ombi password at the same time as the Jellyfin password."
|
||||
},
|
||||
"set_password": {
|
||||
"name": "Set password through link",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"depends_true": "link_reset",
|
||||
"type": "bool",
|
||||
"value": false,
|
||||
"description": "Instead of automatically setting the user's password to the PIN, allow them to set a new password through the reset link."
|
||||
},
|
||||
"url_base": {
|
||||
"name": "URL Base",
|
||||
"required": true,
|
||||
"requires_restart": false,
|
||||
"depends_true": "link_reset",
|
||||
"type": "text",
|
||||
"value": "http://accounts.jellyf.in:8056",
|
||||
"description": "Base URL for jfa-go. You can leave this if you have one set in \"Invite Emails\". This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
|
||||
},
|
||||
"language": {
|
||||
"name": "Default reset link language",
|
||||
"required": false,
|
||||
@@ -719,11 +905,41 @@
|
||||
"requires_restart": false,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "http://accounts.jellyf.in:8056/invite",
|
||||
"value": "http://accounts.jellyf.in:8056",
|
||||
"description": "Base URL for jfa-go. This is necessary because using a reverse proxy means the program has no way of knowing the URL itself."
|
||||
}
|
||||
}
|
||||
},
|
||||
"template_email": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
"name": "Custom email template",
|
||||
"description": "Settings for the template used for announcements & custom messages. HTML should include {{ .text }}, Plaintext should include {{ .plaintext }}, and either can have {{ .message }} to include the contact message.",
|
||||
"advanced": true
|
||||
},
|
||||
"settings": {
|
||||
"email_html": {
|
||||
"name": "Custom template email (HTML)",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"advanced": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Path to custom email HTML template for announcements/custom messages."
|
||||
},
|
||||
"email_text": {
|
||||
"name": "Custom template email (plaintext)",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"advanced": true,
|
||||
"depends_true": "enabled",
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Path to custom email text template for announcements/custom messages."
|
||||
}
|
||||
}
|
||||
},
|
||||
"notifications": {
|
||||
"order": [],
|
||||
"meta": {
|
||||
@@ -1077,6 +1293,14 @@
|
||||
"value": "",
|
||||
"description": "Location of stored invites (json)."
|
||||
},
|
||||
"password_resets": {
|
||||
"name": "Password Resets",
|
||||
"required": false,
|
||||
"requires_restart": true,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Location of stored non-Jellyfin password resets (json)."
|
||||
},
|
||||
"emails": {
|
||||
"name": "Email Addresses",
|
||||
"required": false,
|
||||
@@ -1140,6 +1364,38 @@
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Stores telegram user IDs and language preferences."
|
||||
},
|
||||
"matrix_users": {
|
||||
"name": "Matrix users",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Stores matrix user IDs and language preferences."
|
||||
},
|
||||
"matrix_sql": {
|
||||
"name": "Matrix encryption DB",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Stores cryptographic material for Matrix end-to-end encryption."
|
||||
},
|
||||
"discord_users": {
|
||||
"name": "Discord users",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Stores discord user IDs and language preferences."
|
||||
},
|
||||
"announcements": {
|
||||
"name": "Announcement templates",
|
||||
"required": false,
|
||||
"requires_restart": false,
|
||||
"type": "text",
|
||||
"value": "",
|
||||
"description": "Stores custom announcement templates."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
60
css/base.css
@@ -30,12 +30,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
@media screen and (max-width: 1000px) {
|
||||
:root {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
.table-responsive table {
|
||||
min-width: 660px;
|
||||
min-width: 800px;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,6 +130,14 @@ div.card:contains(section.banner.footer) {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.w-100 {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.h-100 {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.inline-block {
|
||||
display: inline-block;
|
||||
}
|
||||
@@ -172,7 +180,7 @@ div.card:contains(section.banner.footer) {
|
||||
}
|
||||
|
||||
p.sm,
|
||||
span.sm {
|
||||
span.sm:not(.heading) {
|
||||
font-size: 0.75rem;
|
||||
}
|
||||
|
||||
@@ -424,6 +432,7 @@ p.top {
|
||||
|
||||
.table-responsive {
|
||||
overflow-x: auto;
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
|
||||
#notification-box {
|
||||
@@ -438,6 +447,10 @@ p.top {
|
||||
margin-bottom: -0.5rem;
|
||||
}
|
||||
|
||||
.dropdown-display.lg {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap; /* Mozilla, since 1999 */
|
||||
@@ -483,3 +496,44 @@ a:hover:not(.lang-link):not(.\~urge), a:active:not(.lang-link):not(.\~urge) {
|
||||
max-width: 15rem;
|
||||
min-width: 10rem;
|
||||
}
|
||||
|
||||
td.img-circle {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
}
|
||||
|
||||
span.img-circle.lg {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
}
|
||||
|
||||
span.shield.img-circle {
|
||||
padding: 0.2rem;
|
||||
}
|
||||
|
||||
img.img-circle {
|
||||
border-radius: 50%;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.table td.sm {
|
||||
padding-top: 0.1rem;
|
||||
padding-bottom: 0.1rem;
|
||||
}
|
||||
|
||||
.table-inline {
|
||||
display: flex !important;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
div.card:contains(section.banner.footer) {
|
||||
padding-bottom: 0px;
|
||||
}
|
||||
|
||||
.card.sectioned {
|
||||
padding: 0px;
|
||||
}
|
||||
|
||||
.card.sectioned .section {
|
||||
padding: var(--spacing-4, 1rem);
|
||||
}
|
||||
|
||||
410
discord.go
Normal file
@@ -0,0 +1,410 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
dg "github.com/bwmarrin/discordgo"
|
||||
)
|
||||
|
||||
type DiscordDaemon struct {
|
||||
Stopped bool
|
||||
ShutdownChannel chan string
|
||||
bot *dg.Session
|
||||
username string
|
||||
tokens []string
|
||||
verifiedTokens map[string]DiscordUser // Map of tokens to discord users.
|
||||
channelID, channelName, inviteChannelID, inviteChannelName string
|
||||
guildID string
|
||||
serverChannelName, serverName string
|
||||
users map[string]DiscordUser // Map of user IDs to users. Added to on first interaction, and loaded from app.storage.discord on start.
|
||||
app *appContext
|
||||
}
|
||||
|
||||
func newDiscordDaemon(app *appContext) (*DiscordDaemon, error) {
|
||||
token := app.config.Section("discord").Key("token").String()
|
||||
if token == "" {
|
||||
return nil, fmt.Errorf("token was blank")
|
||||
}
|
||||
bot, err := dg.New("Bot " + token)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
dd := &DiscordDaemon{
|
||||
Stopped: false,
|
||||
ShutdownChannel: make(chan string),
|
||||
bot: bot,
|
||||
tokens: []string{},
|
||||
verifiedTokens: map[string]DiscordUser{},
|
||||
users: map[string]DiscordUser{},
|
||||
app: app,
|
||||
}
|
||||
for _, user := range app.storage.discord {
|
||||
dd.users[user.ID] = user
|
||||
}
|
||||
|
||||
return dd, nil
|
||||
}
|
||||
|
||||
// NewAuthToken generates an 8-character pin in the form "A1-2B-CD".
|
||||
func (d *DiscordDaemon) NewAuthToken() string {
|
||||
pin := genAuthToken()
|
||||
d.tokens = append(d.tokens, pin)
|
||||
return pin
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) NewUnknownUser(channelID, userID, discrim, username string) DiscordUser {
|
||||
user := DiscordUser{
|
||||
ChannelID: channelID,
|
||||
ID: userID,
|
||||
Username: username,
|
||||
Discriminator: discrim,
|
||||
}
|
||||
return user
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) MustGetUser(channelID, userID, discrim, username string) DiscordUser {
|
||||
if user, ok := d.users[userID]; ok {
|
||||
return user
|
||||
}
|
||||
return d.NewUnknownUser(channelID, userID, discrim, username)
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) run() {
|
||||
d.bot.AddHandler(d.messageHandler)
|
||||
d.bot.Identify.Intents = dg.IntentsGuildMessages | dg.IntentsDirectMessages | dg.IntentsGuildMembers | dg.IntentsGuildInvites
|
||||
if err := d.bot.Open(); err != nil {
|
||||
d.app.err.Printf("Discord: Failed to start daemon: %v", err)
|
||||
return
|
||||
}
|
||||
// Wait for everything to populate, it's slow sometimes.
|
||||
for d.bot.State == nil {
|
||||
continue
|
||||
}
|
||||
for d.bot.State.User == nil {
|
||||
continue
|
||||
}
|
||||
d.username = d.bot.State.User.Username
|
||||
for d.bot.State.Guilds == nil {
|
||||
continue
|
||||
}
|
||||
// Choose the last guild (server), for now we don't really support multiple anyway
|
||||
d.guildID = d.bot.State.Guilds[len(d.bot.State.Guilds)-1].ID
|
||||
guild, err := d.bot.Guild(d.guildID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to get guild: %v", err)
|
||||
}
|
||||
d.serverChannelName = guild.Name
|
||||
d.serverName = guild.Name
|
||||
if channel := d.app.config.Section("discord").Key("channel").String(); channel != "" {
|
||||
d.channelName = channel
|
||||
d.serverChannelName += "/" + channel
|
||||
}
|
||||
if d.app.config.Section("discord").Key("provide_invite").MustBool(false) {
|
||||
if invChannel := d.app.config.Section("discord").Key("invite_channel").String(); invChannel != "" {
|
||||
d.inviteChannelName = invChannel
|
||||
}
|
||||
}
|
||||
defer d.bot.Close()
|
||||
<-d.ShutdownChannel
|
||||
d.ShutdownChannel <- "Down"
|
||||
return
|
||||
}
|
||||
|
||||
// NewTempInvite creates an invite link, and returns the invite URL, as well as the URL for the server icon.
|
||||
func (d *DiscordDaemon) NewTempInvite(ageSeconds, maxUses int) (inviteURL, iconURL string) {
|
||||
var inv *dg.Invite
|
||||
var err error
|
||||
if d.inviteChannelName == "" {
|
||||
d.app.err.Println("Discord: Cannot create invite without channel specified in settings.")
|
||||
return
|
||||
}
|
||||
if d.inviteChannelID == "" {
|
||||
channels, err := d.bot.GuildChannels(d.guildID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Couldn't get channel list: %v", err)
|
||||
return
|
||||
}
|
||||
found := false
|
||||
for _, channel := range channels {
|
||||
// channel, err := d.bot.Channel(ch.ID)
|
||||
// if err != nil {
|
||||
// d.app.err.Printf("Discord: Couldn't get channel: %v", err)
|
||||
// return
|
||||
// }
|
||||
if channel.Name == d.inviteChannelName {
|
||||
d.inviteChannelID = channel.ID
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
d.app.err.Printf("Discord: Couldn't find invite channel \"%s\"", d.inviteChannelName)
|
||||
return
|
||||
}
|
||||
}
|
||||
// channel, err := d.bot.Channel(d.inviteChannelID)
|
||||
// if err != nil {
|
||||
// d.app.err.Printf("Discord: Couldn't get invite channel: %v", err)
|
||||
// return
|
||||
// }
|
||||
inv, err = d.bot.ChannelInviteCreate(d.inviteChannelID, dg.Invite{
|
||||
// Guild: d.bot.State.Guilds[len(d.bot.State.Guilds)-1],
|
||||
// Channel: channel,
|
||||
// Inviter: d.bot.State.User,
|
||||
MaxAge: ageSeconds,
|
||||
MaxUses: maxUses,
|
||||
Temporary: false,
|
||||
})
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to create invite: %v", err)
|
||||
return
|
||||
}
|
||||
inviteURL = "https://discord.gg/" + inv.Code
|
||||
guild, err := d.bot.Guild(d.guildID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to get guild: %v", err)
|
||||
return
|
||||
}
|
||||
iconURL = guild.IconURL()
|
||||
return
|
||||
}
|
||||
|
||||
// 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 {
|
||||
members, err := d.bot.GuildMembers(
|
||||
d.guildID,
|
||||
"",
|
||||
1000,
|
||||
)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to get members: %v", err)
|
||||
return nil
|
||||
}
|
||||
hasDiscriminator := strings.Contains(username, "#")
|
||||
var users []*dg.Member
|
||||
for _, member := range members {
|
||||
if hasDiscriminator {
|
||||
if member.User.Username+"#"+member.User.Discriminator == username {
|
||||
return []*dg.Member{member}
|
||||
}
|
||||
}
|
||||
if strings.Contains(member.User.Username, username) {
|
||||
users = append(users, member)
|
||||
}
|
||||
}
|
||||
return users
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) NewUser(ID string) (user DiscordUser, ok bool) {
|
||||
u, err := d.bot.User(ID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to get user: %v", err)
|
||||
return
|
||||
}
|
||||
user.ID = ID
|
||||
user.Username = u.Username
|
||||
user.Contact = true
|
||||
user.Discriminator = u.Discriminator
|
||||
channel, err := d.bot.UserChannelCreate(ID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to create DM channel: %v", err)
|
||||
return
|
||||
}
|
||||
user.ChannelID = channel.ID
|
||||
ok = true
|
||||
return
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) Shutdown() {
|
||||
d.Stopped = true
|
||||
d.ShutdownChannel <- "Down"
|
||||
<-d.ShutdownChannel
|
||||
close(d.ShutdownChannel)
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) messageHandler(s *dg.Session, m *dg.MessageCreate) {
|
||||
if m.GuildID != "" && d.channelName != "" {
|
||||
if d.channelID == "" {
|
||||
channel, err := s.Channel(m.ChannelID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Couldn't get channel, will monitor all: %v", err)
|
||||
d.channelName = ""
|
||||
}
|
||||
if channel.Name == d.channelName {
|
||||
d.channelID = channel.ID
|
||||
}
|
||||
}
|
||||
if d.channelID != m.ChannelID {
|
||||
d.app.debug.Printf("Discord: Ignoring message as not in specified channel")
|
||||
return
|
||||
}
|
||||
}
|
||||
if m.Author.ID == s.State.User.ID {
|
||||
return
|
||||
}
|
||||
sects := strings.Split(m.Content, " ")
|
||||
if len(sects) == 0 {
|
||||
return
|
||||
}
|
||||
lang := d.app.storage.lang.chosenTelegramLang
|
||||
if user, ok := d.users[m.Author.ID]; ok {
|
||||
if _, ok := d.app.storage.lang.Telegram[user.Lang]; ok {
|
||||
lang = user.Lang
|
||||
}
|
||||
}
|
||||
switch msg := sects[0]; msg {
|
||||
case d.app.config.Section("discord").Key("start_command").MustString("!start"):
|
||||
d.commandStart(s, m, lang)
|
||||
case "!lang":
|
||||
d.commandLang(s, m, sects, lang)
|
||||
default:
|
||||
d.commandPIN(s, m, sects, lang)
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) commandStart(s *dg.Session, m *dg.MessageCreate, lang string) {
|
||||
channel, err := s.UserChannelCreate(m.Author.ID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to create private channel with \"%s\": %v", m.Author.Username, err)
|
||||
return
|
||||
}
|
||||
user := d.MustGetUser(channel.ID, m.Author.ID, m.Author.Discriminator, m.Author.Username)
|
||||
d.users[m.Author.ID] = user
|
||||
content := d.app.storage.lang.Telegram[lang].Strings.get("startMessage") + "\n"
|
||||
content += d.app.storage.lang.Telegram[lang].Strings.template("languageMessage", tmpl{"command": "!lang"})
|
||||
_, err = s.ChannelMessageSend(channel.ID, content)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) commandLang(s *dg.Session, m *dg.MessageCreate, sects []string, lang string) {
|
||||
if len(sects) == 1 {
|
||||
list := "!lang <lang>\n"
|
||||
for code := range d.app.storage.lang.Telegram {
|
||||
list += fmt.Sprintf("%s: %s\n", code, d.app.storage.lang.Telegram[code].Meta.Name)
|
||||
}
|
||||
_, err := s.ChannelMessageSendReply(
|
||||
m.ChannelID,
|
||||
list,
|
||||
m.Reference(),
|
||||
)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
if _, ok := d.app.storage.lang.Telegram[sects[1]]; ok {
|
||||
var user DiscordUser
|
||||
for jfID, user := range d.app.storage.discord {
|
||||
if user.ID == m.Author.ID {
|
||||
user.Lang = sects[1]
|
||||
d.app.storage.discord[jfID] = user
|
||||
if err := d.app.storage.storeDiscordUsers(); err != nil {
|
||||
d.app.err.Printf("Failed to store Discord users: %v", err)
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
d.users[m.Author.ID] = user
|
||||
}
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) commandPIN(s *dg.Session, m *dg.MessageCreate, sects []string, lang string) {
|
||||
if _, ok := d.users[m.Author.ID]; ok {
|
||||
channel, err := s.Channel(m.ChannelID)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to get channel: %v", err)
|
||||
return
|
||||
}
|
||||
if channel.Type != dg.ChannelTypeDM {
|
||||
d.app.debug.Println("Discord: Ignoring message as not a DM")
|
||||
return
|
||||
}
|
||||
} else {
|
||||
d.app.debug.Println("Discord: Ignoring message as user was not found")
|
||||
return
|
||||
}
|
||||
tokenIndex := -1
|
||||
for i, token := range d.tokens {
|
||||
if sects[0] == token {
|
||||
tokenIndex = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if tokenIndex == -1 {
|
||||
_, err := s.ChannelMessageSend(
|
||||
m.ChannelID,
|
||||
d.app.storage.lang.Telegram[lang].Strings.get("invalidPIN"),
|
||||
)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||
}
|
||||
return
|
||||
}
|
||||
_, err := s.ChannelMessageSend(
|
||||
m.ChannelID,
|
||||
d.app.storage.lang.Telegram[lang].Strings.get("pinSuccess"),
|
||||
)
|
||||
if err != nil {
|
||||
d.app.err.Printf("Discord: Failed to send message to \"%s\": %v", m.Author.Username, err)
|
||||
}
|
||||
d.verifiedTokens[sects[0]] = d.users[m.Author.ID]
|
||||
d.tokens[len(d.tokens)-1], d.tokens[tokenIndex] = d.tokens[tokenIndex], d.tokens[len(d.tokens)-1]
|
||||
d.tokens = d.tokens[:len(d.tokens)-1]
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) SendDM(message *Message, userID ...string) error {
|
||||
channels := make([]string, len(userID))
|
||||
for i, id := range userID {
|
||||
channel, err := d.bot.UserChannelCreate(id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
channels[i] = channel.ID
|
||||
}
|
||||
return d.Send(message, channels...)
|
||||
}
|
||||
|
||||
func (d *DiscordDaemon) Send(message *Message, channelID ...string) error {
|
||||
msg := ""
|
||||
var embeds []*dg.MessageEmbed
|
||||
if message.Markdown != "" {
|
||||
msg, embeds = StripAltText(message.Markdown, true)
|
||||
} else {
|
||||
msg = message.Text
|
||||
}
|
||||
for _, id := range channelID {
|
||||
var err error
|
||||
if len(embeds) != 0 {
|
||||
_, err = d.bot.ChannelMessageSendComplex(
|
||||
id,
|
||||
&dg.MessageSend{
|
||||
Content: msg,
|
||||
Embed: embeds[0],
|
||||
},
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
for i := 1; i < len(embeds); i++ {
|
||||
_, err := d.bot.ChannelMessageSendEmbed(id, embeds[i])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_, err := d.bot.ChannelMessageSend(
|
||||
id,
|
||||
msg,
|
||||
)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
102
email.go
@@ -25,7 +25,9 @@ import (
|
||||
"github.com/mailgun/mailgun-go/v4"
|
||||
)
|
||||
|
||||
// implements email sending, right now via smtp or mailgun.
|
||||
var renderer = html.NewRenderer(html.RendererOptions{Flags: html.Smartypants})
|
||||
|
||||
// EmailClient implements email sending, right now via smtp, mailgun or a dummy client.
|
||||
type EmailClient interface {
|
||||
Send(fromName, fromAddr string, message *Message, address ...string) error
|
||||
}
|
||||
@@ -37,7 +39,7 @@ func (dc *DummyClient) Send(fromName, fromAddr string, email *Message, address .
|
||||
return nil
|
||||
}
|
||||
|
||||
// Mailgun client implements emailClient.
|
||||
// Mailgun client implements EmailClient.
|
||||
type Mailgun struct {
|
||||
client *mailgun.MailgunImpl
|
||||
}
|
||||
@@ -59,7 +61,7 @@ func (mg *Mailgun) Send(fromName, fromAddr string, email *Message, address ...st
|
||||
return err
|
||||
}
|
||||
|
||||
// SMTP supports SSL/TLS and STARTTLS; implements emailClient.
|
||||
// SMTP supports SSL/TLS and STARTTLS; implements EmailClient.
|
||||
type SMTP struct {
|
||||
sslTLS bool
|
||||
server string
|
||||
@@ -139,9 +141,9 @@ func NewEmailer(app *appContext) *Emailer {
|
||||
}
|
||||
method := app.config.Section("email").Key("method").String()
|
||||
if method == "smtp" {
|
||||
sslTls := false
|
||||
sslTLS := false
|
||||
if app.config.Section("smtp").Key("encryption").String() == "ssl_tls" {
|
||||
sslTls = true
|
||||
sslTLS = true
|
||||
}
|
||||
username := ""
|
||||
if u := app.config.Section("smtp").Key("username").MustString(""); u != "" {
|
||||
@@ -149,7 +151,7 @@ func NewEmailer(app *appContext) *Emailer {
|
||||
} else {
|
||||
username = emailer.fromAddr
|
||||
}
|
||||
err := emailer.NewSMTP(app.config.Section("smtp").Key("server").String(), app.config.Section("smtp").Key("port").MustInt(465), username, app.config.Section("smtp").Key("password").String(), sslTls, app.config.Section("smtp").Key("ssl_cert").MustString(""))
|
||||
err := emailer.NewSMTP(app.config.Section("smtp").Key("server").String(), app.config.Section("smtp").Key("port").MustInt(465), username, app.config.Section("smtp").Key("password").String(), sslTLS, app.config.Section("smtp").Key("ssl_cert").MustString(""))
|
||||
if err != nil {
|
||||
app.err.Printf("Error while initiating SMTP mailer: %v", err)
|
||||
}
|
||||
@@ -177,6 +179,23 @@ func (emailer *Emailer) NewMailgun(url, key string) {
|
||||
|
||||
// NewSMTP returns an SMTP emailClient.
|
||||
func (emailer *Emailer) NewSMTP(server string, port int, username, password string, sslTLS bool, certPath string) (err error) {
|
||||
// x509.SystemCertPool is unavailable on windows
|
||||
if PLATFORM == "windows" {
|
||||
sender := &SMTP{
|
||||
server: server,
|
||||
port: port,
|
||||
sslTLS: sslTLS,
|
||||
tlsConfig: &tls.Config{
|
||||
InsecureSkipVerify: false,
|
||||
ServerName: server,
|
||||
},
|
||||
}
|
||||
if username != "" || password != "" {
|
||||
sender.auth = smtp.PlainAuth("", username, password, server)
|
||||
}
|
||||
emailer.sender = sender
|
||||
return
|
||||
}
|
||||
rootCAs, err := x509.SystemCertPool()
|
||||
if rootCAs == nil || err != nil {
|
||||
rootCAs = x509.NewCertPool()
|
||||
@@ -188,8 +207,7 @@ func (emailer *Emailer) NewSMTP(server string, port int, username, password stri
|
||||
err = errors.New("Failed to append cert to pool")
|
||||
}
|
||||
}
|
||||
emailer.sender = &SMTP{
|
||||
auth: smtp.PlainAuth("", username, password, server),
|
||||
sender := &SMTP{
|
||||
server: server,
|
||||
port: port,
|
||||
sslTLS: sslTLS,
|
||||
@@ -199,6 +217,10 @@ func (emailer *Emailer) NewSMTP(server string, port int, username, password stri
|
||||
RootCAs: rootCAs,
|
||||
},
|
||||
}
|
||||
if username != "" || password != "" {
|
||||
sender.auth = smtp.PlainAuth("", username, password, server)
|
||||
}
|
||||
emailer.sender = sender
|
||||
return
|
||||
}
|
||||
|
||||
@@ -215,9 +237,8 @@ func (emailer *Emailer) construct(app *appContext, section, keyFragment string,
|
||||
}
|
||||
var keys []string
|
||||
plaintext := app.config.Section("email").Key("plaintext").MustBool(false)
|
||||
telegram := app.config.Section("telegram").Key("enabled").MustBool(false)
|
||||
if plaintext {
|
||||
if telegram {
|
||||
if telegramEnabled || discordEnabled {
|
||||
keys = []string{"text"}
|
||||
text, markdown = "", ""
|
||||
} else {
|
||||
@@ -225,7 +246,7 @@ func (emailer *Emailer) construct(app *appContext, section, keyFragment string,
|
||||
text = ""
|
||||
}
|
||||
} else {
|
||||
if telegram {
|
||||
if telegramEnabled || discordEnabled {
|
||||
keys = []string{"html", "text", "markdown"}
|
||||
} else {
|
||||
keys = []string{"html", "text"}
|
||||
@@ -291,6 +312,9 @@ func (emailer *Emailer) confirmationValues(code, username, key string, app *appC
|
||||
} else {
|
||||
message := app.config.Section("messages").Key("message").String()
|
||||
inviteLink := app.config.Section("invite_emails").Key("url_base").String()
|
||||
if !strings.HasSuffix(inviteLink, "/invite") {
|
||||
inviteLink += "/invite"
|
||||
}
|
||||
inviteLink = fmt.Sprintf("%s/%s?key=%s", inviteLink, code, key)
|
||||
template["helloUser"] = emailer.lang.Strings.template("helloUser", tmpl{"username": username})
|
||||
template["confirmationURL"] = inviteLink
|
||||
@@ -322,19 +346,27 @@ func (emailer *Emailer) constructConfirmation(code, username, key string, app *a
|
||||
return email, nil
|
||||
}
|
||||
|
||||
func (emailer *Emailer) constructTemplate(subject, md string, app *appContext) (*Message, error) {
|
||||
// username is optional, but should only be passed once.
|
||||
func (emailer *Emailer) constructTemplate(subject, md string, app *appContext, username ...string) (*Message, error) {
|
||||
if len(username) != 0 {
|
||||
md = templateEmail(md, []string{"{username}"}, nil, map[string]interface{}{"username": username[0]})
|
||||
subject = templateEmail(subject, []string{"{username}"}, nil, map[string]interface{}{"username": username[0]})
|
||||
}
|
||||
email := &Message{Subject: subject}
|
||||
renderer := html.NewRenderer(html.RendererOptions{Flags: html.Smartypants})
|
||||
html := markdown.ToHTML([]byte(md), nil, renderer)
|
||||
text := stripMarkdown(md)
|
||||
message := app.config.Section("messages").Key("message").String()
|
||||
var err error
|
||||
email.HTML, email.Text, email.Markdown, err = emailer.construct(app, "template_email", "email_", map[string]interface{}{
|
||||
data := map[string]interface{}{
|
||||
"text": template.HTML(html),
|
||||
"plaintext": text,
|
||||
"message": message,
|
||||
"md": md,
|
||||
})
|
||||
}
|
||||
if len(username) != 0 {
|
||||
data["username"] = username[0]
|
||||
}
|
||||
email.HTML, email.Text, email.Markdown, err = emailer.construct(app, "template_email", "email_", data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -346,6 +378,9 @@ func (emailer *Emailer) inviteValues(code string, invite Invite, app *appContext
|
||||
d, t, expiresIn := emailer.formatExpiry(expiry, false, app.datePattern, app.timePattern)
|
||||
message := app.config.Section("messages").Key("message").String()
|
||||
inviteLink := app.config.Section("invite_emails").Key("url_base").String()
|
||||
if !strings.HasSuffix(inviteLink, "/invite") {
|
||||
inviteLink += "/invite"
|
||||
}
|
||||
inviteLink = fmt.Sprintf("%s/%s", inviteLink, code)
|
||||
template := map[string]interface{}{
|
||||
"hello": emailer.lang.InviteEmail.get("hello"),
|
||||
@@ -517,17 +552,17 @@ func (emailer *Emailer) resetValues(pwr PasswordReset, app *appContext, noSub bo
|
||||
} else {
|
||||
template["helloUser"] = emailer.lang.Strings.template("helloUser", tmpl{"username": pwr.Username})
|
||||
template["codeExpiry"] = emailer.lang.PasswordReset.template("codeExpiry", tmpl{"date": d, "time": t, "expiresInMinutes": expiresIn})
|
||||
inviteLink := app.config.Section("invite_emails").Key("url_base").String()
|
||||
url := app.config.Section("password_resets").Key("url_base").String()
|
||||
if linkResetEnabled {
|
||||
if inviteLink != "" {
|
||||
if url != "" {
|
||||
// Strip /invite form end of this URL, ik its ugly.
|
||||
template["link_reset"] = true
|
||||
pinLink := fmt.Sprintf("%s/reset?pin=%s", strings.Replace(inviteLink, "/invite", "", 1), pwr.Pin)
|
||||
pinLink := fmt.Sprintf("%s/reset?pin=%s", url, pwr.Pin)
|
||||
template["pin"] = pinLink
|
||||
// Only used in html email.
|
||||
template["pin_code"] = pwr.Pin
|
||||
} else {
|
||||
app.info.Println("Password Reset link disabled as no URL Base provided. Set in Settings > Invite Emails.")
|
||||
app.info.Println("Password Reset link disabled as no URL Base provided. Set in Settings > Password Resets.")
|
||||
template["pin"] = pwr.Pin
|
||||
}
|
||||
} else {
|
||||
@@ -576,6 +611,7 @@ func (emailer *Emailer) deletedValues(reason string, app *appContext, noSub bool
|
||||
template["reason"] = reason
|
||||
template["message"] = app.config.Section("messages").Key("message").String()
|
||||
}
|
||||
fmt.Println("TTTT", template)
|
||||
return template
|
||||
}
|
||||
|
||||
@@ -794,8 +830,27 @@ func (app *appContext) sendByID(email *Message, ID ...string) error {
|
||||
var err error
|
||||
if tgChat, ok := app.storage.telegram[id]; ok && tgChat.Contact && telegramEnabled {
|
||||
err = app.telegram.Send(email, tgChat.ChatID)
|
||||
} else if address, ok := app.storage.emails[id]; ok {
|
||||
err = app.email.send(email, address.(string))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if dcChat, ok := app.storage.discord[id]; ok && dcChat.Contact && discordEnabled {
|
||||
err = app.discord.Send(email, dcChat.ChannelID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if mxChat, ok := app.storage.matrix[id]; ok && mxChat.Contact && matrixEnabled {
|
||||
err = app.matrix.Send(email, mxChat)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if address, ok := app.storage.emails[id]; ok && address.Contact && emailEnabled {
|
||||
err = app.email.send(email, address.Addr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -805,11 +860,14 @@ 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
|
||||
}
|
||||
if tgChat, ok := app.storage.telegram[jfID]; ok && tgChat.Contact && telegramEnabled {
|
||||
return "@" + tgChat.Username
|
||||
}
|
||||
if addr, ok := app.storage.emails[jfID]; ok {
|
||||
return addr.(string)
|
||||
return addr.Addr
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
87
exit.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html/template"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"runtime/debug"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/pkg/browser"
|
||||
)
|
||||
|
||||
// https://gist.github.com/swdunlop/9629168
|
||||
func identifyPanic() string {
|
||||
var name, file string
|
||||
var line int
|
||||
var pc [16]uintptr
|
||||
|
||||
n := runtime.Callers(4, pc[:])
|
||||
for _, pc := range pc[:n] {
|
||||
fn := runtime.FuncForPC(pc)
|
||||
if fn == nil {
|
||||
continue
|
||||
}
|
||||
file, line = fn.FileLine(pc)
|
||||
name = fn.Name()
|
||||
if !strings.HasPrefix(name, "runtime.") {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
switch {
|
||||
case name != "":
|
||||
return fmt.Sprintf("%v:%v", name, line)
|
||||
case file != "":
|
||||
return fmt.Sprintf("%v:%v", file, line)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("pc:%x", pc)
|
||||
}
|
||||
|
||||
// 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")
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to load template: %v", err)
|
||||
}
|
||||
logCache := lineCache.String()
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
logCache += "\n" + fmt.Sprint(err)
|
||||
}
|
||||
logCache += "\n" + string(debug.Stack())
|
||||
sanitized := sanitizeLog(logCache)
|
||||
data := map[string]interface{}{
|
||||
"Log": logCache,
|
||||
"SanitizedLog": sanitized,
|
||||
}
|
||||
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"))
|
||||
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")
|
||||
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)
|
||||
}
|
||||
defer f.Close()
|
||||
err2 = tmpl.Execute(f, data)
|
||||
if err2 != nil {
|
||||
log.Fatalf("Failed to execute template: %v", err2)
|
||||
}
|
||||
browser.OpenFile(fpath + ".html")
|
||||
if TRAY {
|
||||
QuitTray()
|
||||
} else {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
22
external.go
@@ -12,8 +12,8 @@ import (
|
||||
|
||||
const binaryType = "external"
|
||||
|
||||
var localFS fs.FS
|
||||
var langFS fs.FS
|
||||
var localFS dirFS
|
||||
var langFS dirFS
|
||||
|
||||
// When using os.DirFS, even on Windows the separator seems to be '/'.
|
||||
// func FSJoin(elem ...string) string { return filepath.Join(elem...) }
|
||||
@@ -29,9 +29,23 @@ func FSJoin(elem ...string) string {
|
||||
return strings.TrimSuffix(path, sep)
|
||||
}
|
||||
|
||||
type dirFS string
|
||||
|
||||
func (dir dirFS) Open(name string) (fs.File, error) {
|
||||
return os.Open(string(dir) + "/" + name)
|
||||
}
|
||||
|
||||
func (dir dirFS) ReadFile(name string) ([]byte, error) {
|
||||
return os.ReadFile(string(dir) + "/" + name)
|
||||
}
|
||||
|
||||
func (dir dirFS) ReadDir(name string) ([]fs.DirEntry, error) {
|
||||
return os.ReadDir(string(dir) + "/" + name)
|
||||
}
|
||||
|
||||
func loadFilesystems() {
|
||||
log.Println("Using external storage")
|
||||
executable, _ := os.Executable()
|
||||
localFS = os.DirFS(filepath.Join(filepath.Dir(executable), "data"))
|
||||
langFS = os.DirFS(filepath.Join(filepath.Dir(executable), "data", "lang"))
|
||||
localFS = dirFS(filepath.Join(filepath.Dir(executable), "data"))
|
||||
langFS = dirFS(filepath.Join(filepath.Dir(executable), "data", "lang"))
|
||||
}
|
||||
|
||||
78
go.mod
@@ -10,41 +10,65 @@ replace github.com/hrfee/jfa-go/ombi => ./ombi
|
||||
|
||||
replace github.com/hrfee/jfa-go/logger => ./logger
|
||||
|
||||
replace github.com/hrfee/jfa-go/linecache => ./linecache
|
||||
|
||||
require (
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/fatih/color v1.10.0
|
||||
github.com/bwmarrin/discordgo v0.23.2
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 // indirect
|
||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a
|
||||
github.com/fatih/color v1.12.0
|
||||
github.com/fsnotify/fsnotify v1.4.9
|
||||
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/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-openapi/spec v0.20.3 // indirect
|
||||
github.com/gin-contrib/static v0.0.1
|
||||
github.com/gin-gonic/gin v1.7.4
|
||||
github.com/go-openapi/jsonreference v0.19.6 // indirect
|
||||
github.com/go-openapi/swag v0.19.15 // indirect
|
||||
github.com/go-playground/validator/v10 v10.4.1 // indirect
|
||||
github.com/go-telegram-bot-api/telegram-bot-api v4.6.4+incompatible // indirect
|
||||
github.com/golang/protobuf v1.4.3 // indirect
|
||||
github.com/gomarkdown/markdown v0.0.0-20210408062403-ad838ccf8cdd
|
||||
github.com/google/uuid v1.1.2 // indirect
|
||||
github.com/hrfee/jfa-go/common v0.0.0-20210105184019-fdc97b4e86cc
|
||||
github.com/hrfee/jfa-go/docs v0.0.0-20201112212552-b6f3cd7c1f71
|
||||
github.com/hrfee/jfa-go/logger v0.0.0-00010101000000-000000000000
|
||||
github.com/hrfee/jfa-go/ombi v0.0.0-20201112212552-b6f3cd7c1f71
|
||||
github.com/hrfee/mediabrowser v0.3.3
|
||||
github.com/itchyny/timefmt-go v0.1.2
|
||||
github.com/go-playground/validator/v10 v10.9.0 // indirect
|
||||
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-20210514010506-3b9f47219fe7
|
||||
github.com/google/uuid v1.3.0 // indirect
|
||||
github.com/hrfee/jfa-go/common v0.0.0-20210816220108-eb3489b34f9e
|
||||
github.com/hrfee/jfa-go/docs v0.0.0-20210816220108-eb3489b34f9e
|
||||
github.com/hrfee/jfa-go/linecache v0.0.0-20210816220108-eb3489b34f9e
|
||||
github.com/hrfee/jfa-go/logger v0.0.0-20210816220108-eb3489b34f9e
|
||||
github.com/hrfee/jfa-go/ombi v0.0.0-20210816220108-eb3489b34f9e
|
||||
github.com/hrfee/mediabrowser v0.3.5
|
||||
github.com/itchyny/timefmt-go v0.1.3
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible
|
||||
github.com/lithammer/shortuuid/v3 v3.0.4
|
||||
github.com/mailgun/mailgun-go/v4 v4.5.1
|
||||
github.com/json-iterator/go v1.1.11 // indirect
|
||||
github.com/lib/pq v1.10.2 // indirect
|
||||
github.com/lithammer/shortuuid/v3 v3.0.7
|
||||
github.com/mailgun/mailgun-go/v4 v4.5.2
|
||||
github.com/mailru/easyjson v0.7.7 // indirect
|
||||
github.com/mattn/go-isatty v0.0.13 // indirect
|
||||
github.com/mattn/go-sqlite3 v1.14.7 // indirect
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2
|
||||
github.com/pkg/errors v0.9.1 // indirect
|
||||
github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966
|
||||
github.com/smartystreets/goconvey v1.6.4 // indirect
|
||||
github.com/swaggo/files v0.0.0-20190704085106-630677cd5c14
|
||||
github.com/swaggo/gin-swagger v1.3.0
|
||||
github.com/swaggo/swag v1.7.0 // indirect
|
||||
github.com/swaggo/files v0.0.0-20210815190702-a29dd2bc99b2
|
||||
github.com/swaggo/gin-swagger v1.3.1
|
||||
github.com/swaggo/swag v1.7.1 // indirect
|
||||
github.com/technoweenie/multipartstreamer v1.0.1 // indirect
|
||||
github.com/ugorji/go v1.2.0 // indirect
|
||||
github.com/tidwall/gjson v1.8.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
github.com/tidwall/sjson v1.1.7 // indirect
|
||||
github.com/ugorji/go v1.2.6 // indirect
|
||||
github.com/writeas/go-strip-markdown v2.0.1+incompatible
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9 // indirect
|
||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c // indirect
|
||||
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 // indirect
|
||||
golang.org/x/tools v0.1.0 // indirect
|
||||
google.golang.org/protobuf v1.25.0 // indirect
|
||||
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e // indirect
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d // indirect
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912 // indirect
|
||||
golang.org/x/text v0.3.7 // indirect
|
||||
golang.org/x/tools v0.1.5 // indirect
|
||||
google.golang.org/protobuf v1.27.1 // indirect
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1 // indirect
|
||||
gopkg.in/ini.v1 v1.62.0
|
||||
maunium.net/go/maulogger/v2 v2.3.0 // indirect
|
||||
maunium.net/go/mautrix v0.9.19
|
||||
)
|
||||
|
||||
332
go.sum
@@ -1,6 +1,3 @@
|
||||
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
|
||||
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
|
||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
github.com/KyleBanks/depth v1.2.1/go.mod h1:jzSb9d0L43HxTQfT+oSA1EEp2q+ne2uh6XgeJcm8brE=
|
||||
@@ -9,27 +6,31 @@ github.com/PuerkitoBio/purell v1.1.1 h1:WEQqlqaGbrPkxLJWfBwQmfEAE1Z7ONdDLqrN38tN
|
||||
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/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM=
|
||||
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
|
||||
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
|
||||
github.com/client9/misspell v0.3.4 h1:ta993UF76GwbvJcIo3Y68y/M3WxlpEHPWIGDkJYwzJI=
|
||||
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
|
||||
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.2 h1:BzrtTktixGHIu9Tt7dEE6diysEF9HWnXeHuoJEt2fH4=
|
||||
github.com/bwmarrin/discordgo v0.23.2/go.mod h1:c1WtWUGN6nREDmzIpyTp/iD3VYt4Fpx+bVyfBG7JE+M=
|
||||
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d h1:U+s90UTSYgptZMwQh2aRr3LuazLJIa+Pg3Kc1ylSYVY=
|
||||
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 h1:uDmaGzcdjhF4i/plgjmEsriH11Y0o7RKapEf/LDaM3w=
|
||||
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=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0 h1:G/bYguwHIzWq9ZoyUQqrjTmJbbYn3j3CKKpKinvZLFk=
|
||||
github.com/elazarl/go-bindata-assetfs v1.0.0/go.mod h1:v+YaWX3bdea5J/mo8dSETolEo7R71Vk1u8bnjau5yw4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473 h1:4cmBvAEBNJaGARUEs3/suWRyfyBfhf7I60WBZq+bv2w=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0 h1:EQciDnbrYxy13PgWoY8AqoxGiPrpgBZ1R8UNe3ddc+A=
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a h1:M88ob4TyDnEqNuL3PgsE/p3bDujfspnulR+0dQWNYZs=
|
||||
github.com/emersion/go-autostart v0.0.0-20210130080809-00ed301c8e9a/go.mod h1:buzQsO8HHkZX2Q45fdfGH1xejPjuDQaXH8btcYMFzPM=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ=
|
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64=
|
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A=
|
||||
@@ -38,8 +39,33 @@ github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQD
|
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0=
|
||||
github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg=
|
||||
github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fatih/color v1.12.0 h1:mRhaKNwANqRgUBGKmnI5ZxEk7QXmjQeCcuYFMX2bfcc=
|
||||
github.com/fatih/color v1.12.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM=
|
||||
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
|
||||
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
|
||||
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520 h1:NRUJuo3v3WGC/g5YiyF790gut6oQr5f3FBI88Wv0dx4=
|
||||
github.com/getlantern/context v0.0.0-20190109183933-c447772a6520/go.mod h1:L+mq6/vvYHKjCX2oez0CgEAJmbq1fbb/oNJIWQkBybY=
|
||||
github.com/getlantern/errors v0.0.0-20190325191628-abdb3e3e36f7 h1:6uJ+sZ/e03gkbqZ0kUG6mfKoqDb4XMAzMIwlajq19So=
|
||||
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/golog v0.0.0-20190830074920-4ef2e798c2d7 h1:guBYzEaLz0Vfc/jv0czrr2z7qyzTOGC9hiQ0VC+hKjk=
|
||||
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/hex v0.0.0-20190417191902-c6586a6fe0b7/go.mod h1:dD3CgOrwlzca8ed61CsZouQS5h5jIzkK9ZWrTcf0s+o=
|
||||
github.com/getlantern/hidden v0.0.0-20190325191715-f02dbb02be55 h1:XYzSdCbkzOC0FDNrgJqGRo8PCMFOBFL9py72DRs7bmc=
|
||||
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/ops v0.0.0-20190325191751-d70cb0d6f85f h1:wrYrQttPS8FHIRSlsrcuKazukx/xqO/PpLZzZXsF+EA=
|
||||
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/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
|
||||
github.com/gin-contrib/gzip v0.0.1 h1:ezvKOL6jH+jlzdHNE4h9h8q8uMpDQjyl0NN0Jd7jozc=
|
||||
@@ -52,12 +78,18 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE
|
||||
github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI=
|
||||
github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e h1:8bZpGwoPxkaivQPrAbWl+7zjjUcbFUnYp7yQcx2r2N0=
|
||||
github.com/gin-contrib/static v0.0.0-20200916080430-d45d9a37d28e/go.mod h1:VhW/Ch/3FhimwZb8Oj+qJmdMmoB8r7lmJ5auRjm50oQ=
|
||||
github.com/gin-contrib/static v0.0.1 h1:JVxuvHPuUfkoul12N7dtQw7KRn/pSMq7Ue1Va9Swm1U=
|
||||
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.5.0/go.mod h1:Nd6IXA8m5kNZdNEHMBd93KT+mdY3+bewLgRvmCsR2Do=
|
||||
github.com/gin-gonic/gin v1.6.2/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.6.3 h1:ahKqKTFpO5KTPHxWZjEdPScmYaGtLo8Y4DMHoEsnp14=
|
||||
github.com/gin-gonic/gin v1.6.3/go.mod h1:75u5sXoLsGZoRN5Sgbi1eraJ4GU3++wFwWzhwvtwp4M=
|
||||
github.com/gin-gonic/gin v1.7.0/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.2 h1:Tg03T9yM2xa8j6I3Z3oqLaQRSmKvxPd6g/2HJ6zICFA=
|
||||
github.com/gin-gonic/gin v1.7.2/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/gin-gonic/gin v1.7.4 h1:QmUZXrvJ9qZ3GfWvQ+2wnW/1ePrTEJqPKMYEU3lD/DM=
|
||||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
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=
|
||||
@@ -67,18 +99,16 @@ github.com/go-openapi/jsonreference v0.17.0/go.mod h1:g4xxGn04lDIRh0GJb5QlpE3Hfo
|
||||
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.4/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg=
|
||||
github.com/go-openapi/jsonreference v0.19.5 h1:1WJP/wi4OjB4iV8KVbH73rQaoialJrqv8gitZLxGLtM=
|
||||
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/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.19.14/go.mod h1:gwrgJS15eCUgjLpMjBJmbZezCsw88LmgeEip0M63doA=
|
||||
github.com/go-openapi/spec v0.20.3 h1:uH9RQ6vdyPSs2pSy9fL8QPspDF2AMIMPtmK5coSSjtQ=
|
||||
github.com/go-openapi/spec v0.20.3/go.mod h1:gG4F8wdEDN+YPBMVnzE85Rbhf+Th2DTvA9nFPQ5AYEg=
|
||||
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.11/go.mod h1:Uc0gKkdR+ojzsEpjh39QChyu92vPgIr72POcgHMAgSY=
|
||||
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=
|
||||
@@ -87,78 +117,101 @@ github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvSc
|
||||
github.com/go-playground/locales v0.12.1/go.mod h1:IUMDtCfWo/w/mtMfIE/IG2K+Ey3ygWanZIBtBW0W2TM=
|
||||
github.com/go-playground/locales v0.13.0 h1:HyWk6mgj5qFqCT5fjGBuRArbVDfE4hi8+e8ceBS/t7Q=
|
||||
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/universal-translator v0.16.0/go.mod h1:1AnU7NaIRDWWzGEKwgtJRd2xk99HeFyHw3yid4rvQIY=
|
||||
github.com/go-playground/universal-translator v0.17.0 h1:icxd5fm+REJzpZx7ZfpaD876Lmtgy7VtROAbHHXk8no=
|
||||
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/validator/v10 v10.2.0/go.mod h1:uOYAAleCW8F/7oMFd6aG0GOhaH6EGOAJShg8Id5JGkI=
|
||||
github.com/go-playground/validator/v10 v10.4.1 h1:pH2c5ADXtd66mxoE0Zm9SUhxE20r7aM3F26W0hOn+GE=
|
||||
github.com/go-playground/validator/v10 v10.4.1/go.mod h1:nlOn6nFhuKACm19sB/8EGNn9GlaMV7XkbRSipzJ0Ii4=
|
||||
github.com/go-playground/validator/v10 v10.8.0 h1:1kAa0fCrnpv+QYdkdcRzrRM7AyYs5o8+jZdJCz9xj6k=
|
||||
github.com/go-playground/validator/v10 v10.8.0/go.mod h1:9JhgTzTaE31GZDpH/HSvHiRJrJ3iKAgqqH0Bl/Ocjdk=
|
||||
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-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
|
||||
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
|
||||
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/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
|
||||
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
|
||||
github.com/golang/mock v1.1.1 h1:G5FRp8JnTd7RQH5kemVNlMeyXQAztQ3mOWV95KxsXH8=
|
||||
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c=
|
||||
github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I=
|
||||
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/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
|
||||
github.com/golang/protobuf v1.3.2/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.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8=
|
||||
github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA=
|
||||
github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs=
|
||||
github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w=
|
||||
github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0=
|
||||
github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8=
|
||||
github.com/golang/protobuf v1.4.3 h1:JjCZWpVbqXDqFVmTfYWEVTMIYrL/NPdPSCHPJ0T/raM=
|
||||
github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI=
|
||||
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-20210408062403-ad838ccf8cdd h1:0b8AqsWQb6A0jjx80UXLG/uMTXQkGD0IGuXWqsrNz1M=
|
||||
github.com/gomarkdown/markdown v0.0.0-20210408062403-ad838ccf8cdd/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
|
||||
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0 h1:A8PeW59pxE9IoFRqBp37U+mSNaQoZ46F1f0f863XSXw=
|
||||
github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7 h1:oKYOfNR7Hp6XpZ4JqolL5u642Js5Z0n7psPVl+S5heo=
|
||||
github.com/gomarkdown/markdown v0.0.0-20210514010506-3b9f47219fe7/go.mod h1:aii0r/K0ZnHv7G0KF7xy1v0A7s2Ljrb5byB7MO5p6TU=
|
||||
github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU=
|
||||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
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 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
|
||||
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/hrfee/mediabrowser v0.3.3 h1:7E05uiol8hh2ytKn3WVLrUIvHAyifYEIy3Y5qtuNh8I=
|
||||
github.com/hrfee/mediabrowser v0.3.3/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
|
||||
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/hrfee/mediabrowser v0.3.5 h1:bOJlI2HLvw7v0c7mcRw5XDRMUHReQzk5z0EJYRyYjpo=
|
||||
github.com/hrfee/mediabrowser v0.3.5/go.mod h1:PnHZbdxmbv1wCVdAQyM7nwPwpVj9fdKx2EcET7sAk+U=
|
||||
github.com/itchyny/timefmt-go v0.1.2 h1:q0Xa4P5it6K6D7ISsbLAMwx1PnWlixDcJL6/sFs93Hs=
|
||||
github.com/itchyny/timefmt-go v0.1.2/go.mod h1:0osSSCQSASBJMsIZnhAaF1C2fCBTJZXrnj37mG8/c+A=
|
||||
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/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible h1:jdpOPRN1zP63Td1hDQbZW73xKmzDvZHzVdNYxhnTMDA=
|
||||
github.com/jordan-wright/email v4.0.1-0.20210109023952-943e75fe5223+incompatible/go.mod h1:1c7szIrayyPPB/987hsnvNzLushdWf4o/79s3P08L8A=
|
||||
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.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.10 h1:Kz6Cvnvv2wGdaG/V8yMvfkmNiXq9Ya2KUv4rouJJr68=
|
||||
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
|
||||
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
|
||||
github.com/jtolds/gls v4.20.0+incompatible h1:xdiiI2gbIgH/gLH7ADydsJ1uDOEzR8yvV7C0MuV77Wo=
|
||||
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/kkdai/bstream v0.0.0-20161212061736-f391b8402d23/go.mod h1:J+Gs4SYgM6CZQHDETBtE9HaSEkGmuNXF86RwHhHUvq4=
|
||||
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/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4=
|
||||
github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
|
||||
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.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
|
||||
github.com/leodido/go-urn v1.2.0 h1:hpXL4XnriNwQ/ABnpepYM/1vCLWNDfUNts8dX3xTG6Y=
|
||||
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/lib/pq v1.9.0 h1:L8nSXQQzAYByakOFMTwpjRoHsMJklur4Gi59b6VivR8=
|
||||
github.com/lib/pq v1.9.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lib/pq v1.10.2 h1:AqzbZs4ZoCBp+GtejcpCpcxM3zlSMx29dXbUSeVtJb8=
|
||||
github.com/lib/pq v1.10.2/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.4 h1:uj4xhotfY92Y1Oa6n6HUiFn87CdoEHYUlTy0+IgbLrs=
|
||||
github.com/lithammer/shortuuid/v3 v3.0.4/go.mod h1:RviRjexKqIzx/7r1peoAITm6m7gnif/h+0zmolKJjzw=
|
||||
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.5.1 h1:XrQQ/ZgqFvINRKy+eBqowLl7k3pQO6OCLpKphliMOFs=
|
||||
github.com/mailgun/mailgun-go/v4 v4.5.1/go.mod h1:FJlF9rI5cQT+mrwujtJjPMbIVy3Ebor9bKTVsJ0QU40=
|
||||
github.com/mailgun/mailgun-go/v4 v4.5.2 h1:6289rnnSn8pKFR8TS5pwWOqFcY/HdWpqhvnQ+J7IVQc=
|
||||
github.com/mailgun/mailgun-go/v4 v4.5.2/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=
|
||||
@@ -171,8 +224,12 @@ github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx
|
||||
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.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ=
|
||||
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
|
||||
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-isatty v0.0.13 h1:qdl+GuBjcsKKDco5BsxPJlId98mSWNKqYA+Co0SC1yA=
|
||||
github.com/mattn/go-isatty v0.0.13/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
|
||||
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA=
|
||||
github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
|
||||
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=
|
||||
@@ -181,53 +238,86 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
|
||||
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
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/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-20210606212950-a7b7a6107d32 h1:K3WnH8Ka32vWygzmjKEhz1zAVqckNoWDqX3azMxuiSA=
|
||||
github.com/pkg/browser v0.0.0-20210606212950-a7b7a6107d32/go.mod h1:yvwcBfzEX4m+eTgxPBbNYytaWFv4PSQzBaeYjxp8Iik=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2 h1:acNfDZXmm28D2Yg/c3ALnZStzNaZMSagpbr96vY6Zjc=
|
||||
github.com/pkg/browser v0.0.0-20210706143420-7d21f8c997e2/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
|
||||
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
|
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I=
|
||||
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/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4 h1:gQz4mCbXsO+nc9n1hCxHcGA3Zx3Eo+UHZoInFGUIXNM=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/russross/blackfriday/v2 v2.0.1 h1:lPqVAte+HuHNfhJ/0LC98ESWRz8afy9tM/0RK8m9o+Q=
|
||||
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
|
||||
github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE=
|
||||
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
|
||||
github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww=
|
||||
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/shurcooL/sanitized_anchor_name v1.0.0 h1:PdmoCO6wvbs+7yrJyMORt4/BmY5IYyJwS/kOiWx8mHo=
|
||||
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 h1:zE9ykElWQ6/NYmHa3jpm/yHnI4xSofP+UP6SpjHcSeM=
|
||||
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
|
||||
github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s=
|
||||
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
|
||||
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
|
||||
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 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
|
||||
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/swaggo/files v0.0.0-20190704085106-630677cd5c14 h1:PyYN9JH5jY9j6av01SpfRMb+1DWg/i3MbGOKPxJ2wjM=
|
||||
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/gin-swagger v1.2.0/go.mod h1:qlH2+W7zXGZkczuL+r2nEBR2JTT+/lX05Nn6vPhc7OI=
|
||||
github.com/swaggo/gin-swagger v1.3.0 h1:eOmp7r57oUgZPw2dJOjcGNMse9cvXcI4tTqBcnZtPsI=
|
||||
github.com/swaggo/gin-swagger v1.3.0/go.mod h1:oy1BRA6WvgtCp848lhxce7BnWH4C8Bxa0m5SkWx+cS0=
|
||||
github.com/swaggo/gin-swagger v1.3.1 h1:mO9MU8O99WX+RM3jekzOV54g9Fo+Nbkk7rgrN1u9irM=
|
||||
github.com/swaggo/gin-swagger v1.3.1/go.mod h1:Z6NtRBK2PRig0EUmy1Xu75CnCEs6vGYu9QZd/QWRYKU=
|
||||
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.0 h1:5bCA/MTLQoIqDXXyHfOpMeDvL9j68OY/udlK4pQoo4E=
|
||||
github.com/swaggo/swag v1.7.0/go.mod h1:BdPIL73gvS9NBsdi7M1JOxLvlbfvNRaBP8m6WT6Aajo=
|
||||
github.com/swaggo/swag v1.7.1 h1:gY9ZakXlNWg/i/v5bQBic7VMZ4teq4m89lpiao74p/s=
|
||||
github.com/swaggo/swag v1.7.1/go.mod h1:gAiHxNTb9cIpNmA/VEGUP+CyZMCP/EW7mdtc8Bny+p8=
|
||||
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.6.8 h1:CTmXMClGYPAmln7652e69B7OLXfTi5ABcPPwjIWUv7w=
|
||||
github.com/tidwall/gjson v1.6.8/go.mod h1:zeFuBCIqD4sN/gmqBzZ4j7Jd6UcA2Fc56x7QFsv+8fI=
|
||||
github.com/tidwall/gjson v1.8.0/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/gjson v1.8.1 h1:8j5EE9Hrh3l9Od1OIEDAb7IpezNA20UdRngNAj5N0WU=
|
||||
github.com/tidwall/gjson v1.8.1/go.mod h1:5/xDoumyyDNerp2U36lyolv46b3uF/9Bu6OfyQ9GImk=
|
||||
github.com/tidwall/match v1.0.3 h1:FQUVvBImDutD8wJLN6c5eMzWtjgONK9MwIBCOrUJKeE=
|
||||
github.com/tidwall/match v1.0.3/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
github.com/tidwall/pretty v1.0.2 h1:Z7S3cePv9Jwm1KwS0513MRaoUe3S01WPbLNV40pwWZU=
|
||||
github.com/tidwall/pretty v1.0.2/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
github.com/tidwall/pretty v1.1.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
|
||||
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.1.5 h1:wsUceI/XDyZk3J1FUvuuYlK62zJv2HO2Pzb8A5EWdUE=
|
||||
github.com/tidwall/sjson v1.1.5/go.mod h1:VuJzsZnTowhSxWdOgsAnb886i4AjEyTkk7tNtsL7EYE=
|
||||
github.com/tidwall/sjson v1.1.7 h1:sgVPwu/yygHJ2m1pJDLgGM/h+1F5odx5Q9ljG3imRm8=
|
||||
github.com/tidwall/sjson v1.1.7/go.mod h1:w/yG+ezBeTdUxiKs5NcPicO9diP38nk96QBAbIIGeFs=
|
||||
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.1.13/go.mod h1:jxau1n+/wyTGLQoCkjok9r5zFa/FxT6eI5HiHKQszjc=
|
||||
github.com/ugorji/go v1.2.0 h1:6eXlzYLLwZwXroJx9NyqbYcbv/d93twiOzQLDewE6qM=
|
||||
github.com/ugorji/go v1.2.0/go.mod h1:1ny++pKMXhLWrwWV5Nf+CbOuZJhMoaFD+0GMFfd8fEc=
|
||||
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/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.1.13/go.mod h1:oNVt3Dq+FO91WNQ/9JnHKQP2QJxTzoN7wCBFCq1OeuU=
|
||||
github.com/ugorji/go/codec v1.2.0 h1:As6RccOIlbm9wHuWYMlB30dErcI+4WiKWsYsmPkyrUw=
|
||||
github.com/ugorji/go/codec v1.2.0/go.mod h1:dXvG35r7zTX6QImXOSFhGMmKtX+wJ7VTWzGvYQGIjBs=
|
||||
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/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
|
||||
github.com/urfave/cli/v2 v2.1.1/go.mod h1:SE9GqnLQmjVa0iPEY0f1w3ygNIYcIJ0OKPMoW2caLfQ=
|
||||
@@ -235,29 +325,27 @@ 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/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
|
||||
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead h1:jeP6FgaSLNTMP+Yri3qjlACywQLye+huGLmNGhBzm6k=
|
||||
github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
|
||||
golang.org/dl v0.0.0-20190829154251-82a15e2f2ead/go.mod h1:IUMfjQLJQd4UTqG1Z90tenwKoCX93Gn3MAQJMOSBsDQ=
|
||||
golang.org/x/crypto v0.0.0-20170930174604-9419663f5a44/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
|
||||
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-20201112155050-0c6587e931a9 h1:umElSU9WZirRdgu2yFHY0ayQkEnKiOC1TtM3fWXFnoU=
|
||||
golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4 h1:c2HOrn5iMezYjSlGPncknSEr/8x5LELb/ilJbXi9DEA=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
|
||||
golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3 h1:XQyxROzUlZH+WIQwySDgnISgOivlhjIEwaQaJEJrrN0=
|
||||
golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
|
||||
golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
|
||||
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI=
|
||||
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e h1:VvfwVmMH40bpMeizC9/K7ipM5Qjucuu16RWfneFPyhQ=
|
||||
golang.org/x/crypto v0.0.0-20210813211128-0a44fdfbc16e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/mod v0.4.2 h1:Gz96sIWK3OalVv/I/qNygP42zyoKp3xptRVCWRFEBvo=
|
||||
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
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-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
@@ -266,19 +354,22 @@ golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLL
|
||||
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-20201110031124-69a78807bb2b/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-20210331212208-0fccb6fa2b5c h1:KHUzaHIpjWVlVVNh65G3hhuj3KB1HnjY6Cq5cTvRQT8=
|
||||
golang.org/x/net v0.0.0-20210331212208-0fccb6fa2b5c/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be h1:vEDujvNQGv4jgYKudGeI/+DAX4Jffq6hpD55MmoEvKs=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/net v0.0.0-20210220033124-5f55cee0dc0d/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
|
||||
golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff h1:j2EK/QoxYNBsXI4R7fQkkRUk8y6wnOBI+6hgPdP/6Ds=
|
||||
golang.org/x/net v0.0.0-20210716203947-853a461950ff/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d h1:LO7XpTYMwTqxjLcGWPijK3vRXg1aWdlNOVOHRq45d7c=
|
||||
golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
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 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
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/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=
|
||||
@@ -287,73 +378,68 @@ 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-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/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-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-20210319071255-635bc2c9138d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54 h1:rF3Ohx8DRyl8h2zw9qojyLHLhrJpEMgyPOImREEryf0=
|
||||
golang.org/x/sys v0.0.0-20210331175145-43e1dd70ce54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
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-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 h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I=
|
||||
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-20210816183151-1e6c022a8912 h1:uCLL3g5wH2xjxVREVuAbP9JM5PPKjRbXKRa6IBjkzmU=
|
||||
golang.org/x/sys v0.0.0-20210816183151-1e6c022a8912/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
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.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6 h1:aRYxNxv6iGQlyVaZmk6ZgYEDa+Jg18DxebPSrd6bg1M=
|
||||
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/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
|
||||
golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
|
||||
golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q=
|
||||
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.0.0-20201120155355-20be4ac4bd6e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
|
||||
golang.org/x/tools v0.1.0 h1:po9/4sTYwZU9lPhi1tOrb4hCv3qrhiQ77LZfGa2OjwY=
|
||||
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
|
||||
golang.org/x/tools v0.1.3 h1:L69ShwSZEyCsLKoAxDKeMvLDZkumEe8gXUZAjab0tX8=
|
||||
golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
golang.org/x/tools v0.1.5 h1:ouewzE6p+/VEB31YYnTbEJdi8pFqKp4P4n85vwo3DHA=
|
||||
golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
|
||||
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/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
|
||||
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
|
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
|
||||
google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY=
|
||||
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo=
|
||||
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
|
||||
google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg=
|
||||
google.golang.org/grpc v1.27.0 h1:rRYRFMVgRv6E0D70Skyfsr28tDXIuuPZyWGMPdMcnXg=
|
||||
google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk=
|
||||
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
|
||||
google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0=
|
||||
google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=
|
||||
google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE=
|
||||
google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo=
|
||||
google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
|
||||
google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
|
||||
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
|
||||
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=
|
||||
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 h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/go-playground/assert.v1 v1.2.1 h1:xoYuJVE7KT85PYWrN730RguIQO0ePzVRfFMXadIrXTM=
|
||||
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 h1:lFB4DoMU6B626w8ny76MV7VX6W2VHct2GVOI3xgiMrQ=
|
||||
gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1 h1:SvGtYmN60a5CVKTOzMSyfzWDeZRxRuGvRQyEAKbw1xc=
|
||||
gopkg.in/go-playground/validator.v9 v9.29.1/go.mod h1:+c9/zcJMFNgbLvly1L1V+PpxWdVbfP1avr/N00E2vyQ=
|
||||
gopkg.in/ini.v1 v1.62.0 h1:duBzk771uxoUuOlyRLkHsygud9+5lrlGjdFBb4mSKDU=
|
||||
gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
|
||||
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=
|
||||
@@ -364,6 +450,12 @@ 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 h1:tQIYjPdBoyREyB9XMu+nnTclpTYkz2zFM+lzLJFO4gQ=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc h1:/hemPrYIhOhy8zYrNj+069zDB68us2sMGsfkFJO0iZs=
|
||||
honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
maunium.net/go/maulogger/v2 v2.2.4 h1:oV2GDeM4fx1uRysdpDC0FcrPg+thFicSd9XzPcYMbVY=
|
||||
maunium.net/go/maulogger/v2 v2.2.4/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/maulogger/v2 v2.3.0 h1:TMCcO65fLk6+pJXo7sl38tzjzW0KBFgc6JWJMBJp4GE=
|
||||
maunium.net/go/maulogger/v2 v2.3.0/go.mod h1:TYWy7wKwz/tIXTpsx8G3mZseIRiC5DoMxSZazOHy68A=
|
||||
maunium.net/go/mautrix v0.9.15 h1:9EJMALSxvy5LkQh5zjaMhbhm/grzVHv3xoA/2pfxpek=
|
||||
maunium.net/go/mautrix v0.9.15/go.mod h1:7IzKfWvpQtN+W2Lzxc0rLvIxFM3ryKX6Ys3S/ZoWbg8=
|
||||
maunium.net/go/mautrix v0.9.19 h1:8ZoDuijJOKxgEOMDoBN2B6at0Ba7EJpsqWA/5jV7ELw=
|
||||
maunium.net/go/mautrix v0.9.19/go.mod h1:7IzKfWvpQtN+W2Lzxc0rLvIxFM3ryKX6Ys3S/ZoWbg8=
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
<script>
|
||||
window.URLBase = "{{ .urlBase }}";
|
||||
window.notificationsEnabled = {{ .notifications }};
|
||||
window.emailEnabled = {{ .email_enabled }};
|
||||
window.telegramEnabled = {{ .telegram_enabled }};
|
||||
window.emailEnabled = {{ .emailEnabled }};
|
||||
window.telegramEnabled = {{ .telegramEnabled }};
|
||||
window.discordEnabled = {{ .discordEnabled }};
|
||||
window.matrixEnabled = {{ .matrixEnabled }};
|
||||
window.ombiEnabled = {{ .ombiEnabled }};
|
||||
window.usernameEnabled = {{ .username }};
|
||||
window.langFile = JSON.parse({{ .language }});
|
||||
@@ -161,15 +163,28 @@
|
||||
<span class="heading"><span id="header-announce"></span> <span class="modal-close">×</span></span>
|
||||
<div class="row">
|
||||
<div class="col flex-col content mt-half">
|
||||
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
||||
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
||||
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
<div id="announce-details">
|
||||
<span class="label supra" for="editor-variables" id="label-editor-variables">{{ .strings.variables }}</span>
|
||||
<div id="announce-variables">
|
||||
<span class="button ~urge !normal mb-1 mt-half" id="announce-variables-username" style="margin-left: 0.25rem; margin-right: 0.25rem;"><span class="monospace">{username}</span></span>
|
||||
</div>
|
||||
<label class="label supra" for="announce-subject"> {{ .strings.subject }}</label>
|
||||
<input type="text" id="announce-subject" class="input ~neutral !normal mb-1 mt-half">
|
||||
<label class="label supra" for="textarea-announce">{{ .strings.message }}</label>
|
||||
<textarea id="textarea-announce" class="textarea full-width ~neutral !normal mt-half monospace"></textarea>
|
||||
<p class="support mt-half mb-1">{{ .strings.markdownSupported }}</p>
|
||||
</div>
|
||||
<label class="label unfocused" id="announce-name"><p class="supra">{{ .strings.name }}</p>
|
||||
<input type="text" class="input ~neutral !normal mb-1 mt-half">
|
||||
<p class="support">{{ .strings.templateEnterName }}</p>
|
||||
</label>
|
||||
<div class="row flex-expand">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal center supra submit">{{ .strings.send }}</span>
|
||||
</label>
|
||||
<span class="button ~info !normal center supra" id="save-announce">{{ .strings.saveAsTemplate }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col card ~neutral !low">
|
||||
<span class="subheading supra">{{ .strings.preview }}</span>
|
||||
@@ -309,7 +324,7 @@
|
||||
<span class="button ~urge !normal full-width center" id="update-update">{{ .strings.update }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ if .telegram_enabled }}
|
||||
{{ if .telegramEnabled }}
|
||||
<div id="modal-telegram" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkTelegram }}</span>
|
||||
@@ -327,6 +342,31 @@
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1"><span id="discord-header"></span><span class="modal-close">×</span></span>
|
||||
<p class="content mb-1" id="discord-description"></p>
|
||||
<div class="row">
|
||||
<input type="search" class="col sm field ~neutral !normal input" id="discord-search" placeholder="user#1234">
|
||||
</div>
|
||||
<table class="table"><tbody id="discord-list"></tbody></table>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<div id="modal-matrix" class="modal">
|
||||
<form class="modal-content card" id="form-matrix" href="">
|
||||
<span class="heading">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content">{{ .strings.linkMatrixDescription }}</p>
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.matrixHomeServer }}" id="matrix-homeserver">
|
||||
<input type="text" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="matrix-user">
|
||||
<input type="password" class="field input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="matrix-password">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.submit }}</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
<div id="notification-box"></div>
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
@@ -488,7 +528,14 @@
|
||||
<div id="create-send-to-container">
|
||||
<label class="label supra">{{ .strings.inviteSendToEmail }}</label>
|
||||
<div class="flex-expand mb-1 mt-half">
|
||||
{{ if .discordEnabled }}
|
||||
<input type="text" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com | user#1234">
|
||||
<span id="create-send-to-search" class="button ~neutral !normal mr-1">
|
||||
<i class="icon ri-search-2-line" title="{{ .strings.search }}"></i>
|
||||
</span>
|
||||
{{ else }}
|
||||
<input type="email" id="create-send-to" class="input ~neutral !normal mr-1" placeholder="example@example.com">
|
||||
{{ end }}
|
||||
<label for="create-send-to-enabled" class="button ~neutral !normal">
|
||||
<input type="checkbox" id="create-send-to-enabled" aria-label="Send to address enabled">
|
||||
</label>
|
||||
@@ -508,7 +555,15 @@
|
||||
</div>
|
||||
<div class="row">
|
||||
<span class="col sm button ~neutral !normal center mb-half" id="accounts-add-user">{{ .quantityStrings.addUser.Singular }}</span>
|
||||
<span class="col sm button ~info !normal center mb-half" id="accounts-announce">{{ .strings.announce }}</span>
|
||||
<div id="accounts-announce-dropdown" class="col sm dropdown" tabindex="0">
|
||||
<span class="h-100 sm button ~info !normal center mb-half" 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 sm button ~urge !normal center mb-half" id="accounts-modify-user">{{ .strings.modifySettings }}</span>
|
||||
<span class="col sm button ~warning !normal center mb-half" id="accounts-extend-expiry">{{ .strings.extendExpiry }}</span>
|
||||
<span class="col sm button ~positive !normal center mb-half" id="accounts-disable-enable">{{ .strings.disable }}</span>
|
||||
@@ -522,9 +577,15 @@
|
||||
<th><input type="checkbox" value="" id="accounts-select-all"></th>
|
||||
<th>{{ .strings.username }}</th>
|
||||
<th>{{ .strings.emailAddress }}</th>
|
||||
{{ if .telegram_enabled }}
|
||||
{{ if .telegramEnabled }}
|
||||
<th>Telegram</th>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<th>Matrix</th>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<th>Discord</th>
|
||||
{{ end }}
|
||||
<th>{{ .strings.expiry }}</th>
|
||||
<th>{{ .strings.lastActiveTime }}</th>
|
||||
</tr>
|
||||
|
||||
49
html/crash.html
Normal file
@@ -0,0 +1,49 @@
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<link inline rel="stylesheet" type="text/css" href="bundle.css">
|
||||
{{ template "header.html" . }}
|
||||
<title>Crash report</title>
|
||||
</head>
|
||||
<body>
|
||||
<div class="page-container">
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<div class="card ~critical sectioned">
|
||||
<section class="section ~critical">
|
||||
<span class="heading">Crash report for jfa-go</span>
|
||||
{{ if .Err }}
|
||||
<div class="monospace pre-line mt-1 mb-1">
|
||||
Error: {{ .Err }}
|
||||
</div>
|
||||
{{ end }}
|
||||
<a class="button ~critical mb-1" target="_blank" href="https://github.com/hrfee/jfa-go/issues/new/choose">Create an Issue</a>
|
||||
</section>
|
||||
<section class="section ~neutral !low">
|
||||
<div class="flex-expand">
|
||||
<span class="subheading">Full Log</span>
|
||||
<span class="button ~urge ml-half" id="copy-log">Copy</span>
|
||||
</div>
|
||||
<div class="row mb-1">
|
||||
<label class="col mr-1">
|
||||
<span class="button ~neutral !high supra full-width center" id="button-log-normal">Normal</span>
|
||||
</label>
|
||||
<label class="col mr-1">
|
||||
<span class="button ~neutral !normal supra full-width center" id="button-log-sanitized">Sanitized</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="log-normal">
|
||||
<pre class="monospace pre-line">{{ .Log }}</pre>
|
||||
</div>
|
||||
<div id="log-sanitized" class="unfocused">
|
||||
<p class="subheading">An attempt has been made to remove sensitive info, but make sure to check yourself.</p>
|
||||
<pre class="monospace pre-line">{{ .SanitizedLog }}</pre>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script inline src="crash.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
@@ -17,6 +17,18 @@
|
||||
window.telegramEnabled = {{ .telegramEnabled }};
|
||||
window.telegramRequired = {{ .telegramRequired }};
|
||||
window.telegramPIN = "{{ .telegramPIN }}";
|
||||
window.discordEnabled = {{ .discordEnabled }};
|
||||
window.discordRequired = {{ .discordRequired }};
|
||||
window.discordPIN = "{{ .discordPIN }}";
|
||||
window.discordInviteLink = {{ .discordInviteLink }};
|
||||
window.discordServerName = "{{ .discordServerName }}";
|
||||
window.matrixEnabled = {{ .matrixEnabled }};
|
||||
window.matrixRequired = {{ .matrixRequired }};
|
||||
window.matrixUserID = "{{ .matrixUser }}";
|
||||
</script>
|
||||
{{ if .passwordReset }}
|
||||
<script src="js/pwr.js" type="module"></script>
|
||||
{{ else }}
|
||||
<script src="js/form.js" type="module"></script>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
@@ -3,7 +3,13 @@
|
||||
<head>
|
||||
<link rel="stylesheet" type="text/css" href="css/bundle.css">
|
||||
{{ template "header.html" . }}
|
||||
<title>{{ .strings.pageTitle }}</title>
|
||||
<title>
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.passwordReset }}
|
||||
{{ else }}
|
||||
{{ .strings.pageTitle }}
|
||||
{{ end }}
|
||||
</title>
|
||||
</head>
|
||||
<body class="max-w-full overflow-x-hidden section">
|
||||
<div id="modal-success" class="modal">
|
||||
@@ -37,6 +43,35 @@
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<div id="modal-discord" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkDiscord }}</span>
|
||||
<p class="content mb-1"> {{ .discordSendPINMessage }}</p>
|
||||
<h1 class="ac">{{ .discordPIN }}</h1>
|
||||
<a id="discord-invite"></a>
|
||||
<span class="button ~info !normal full-width center mt-1" id="discord-waiting">{{ .strings.success }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<div id="modal-matrix" class="modal">
|
||||
<div class="modal-content card">
|
||||
<span class="heading mb-1">{{ .strings.linkMatrix }}</span>
|
||||
<p class="content mb-1"> {{ .strings.matrixEnterUser }}</p>
|
||||
<input type="text" class="input ~neutral !high" placeholder="@user:riot.im" id="matrix-userid">
|
||||
<div class="subheading link-center mt-1">
|
||||
<span class="shield ~info mr-1">
|
||||
<span class="icon">
|
||||
<i class="ri-chat-3-line"></i>
|
||||
</span>
|
||||
</span>
|
||||
{{ .matrixUser }}
|
||||
</div>
|
||||
<span class="button ~info !normal full-width center mt-1" id="matrix-send">{{ .strings.submit }}</span>
|
||||
</div>
|
||||
</div>
|
||||
{{ end }}
|
||||
<span class="dropdown" tabindex="0" id="lang-dropdown">
|
||||
<span class="button ~urge dropdown-button">
|
||||
<i class="ri-global-line"></i>
|
||||
@@ -51,8 +86,20 @@
|
||||
<div class="page-container">
|
||||
<div class="card ~neutral !low">
|
||||
<div class="row baseline">
|
||||
<span class="col heading">{{ .strings.createAccountHeader }}</span>
|
||||
<span class="col subheading"> {{ .helpMessage }}</span>
|
||||
<span class="col heading">
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.passwordReset }}
|
||||
{{ else }}
|
||||
{{ .strings.createAccountHeader }}
|
||||
{{ end }}
|
||||
</span>
|
||||
<span class="col subheading">
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.enterYourPassword }}
|
||||
{{ else }}
|
||||
{{ .helpMessage }}
|
||||
{{ end }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@@ -60,6 +107,7 @@
|
||||
<aside class="col aside sm ~warning" id="user-expiry-message"></aside>
|
||||
{{ end }}
|
||||
<form class="card ~neutral !normal" id="form-create" href="">
|
||||
{{ if not .passwordReset }}
|
||||
<label class="label supra">
|
||||
{{ .strings.username }}
|
||||
<input type="text" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.username }}" id="create-username" aria-label="{{ .strings.username }}">
|
||||
@@ -69,15 +117,36 @@
|
||||
<input type="email" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.emailAddress }}" id="create-email" aria-label="{{ .strings.emailAddress }}" value="{{ .email }}">
|
||||
{{ if .telegramEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-telegram">{{ .strings.linkTelegram }}</span>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-discord">{{ .strings.linkDiscord }}</span>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<span class="button ~info !normal full-width center mb-1" id="link-matrix">{{ .strings.linkMatrix }}</span>
|
||||
{{ end }}
|
||||
{{ if or (.telegramEnabled) (or .discordEnabled .matrixEnabled) }}
|
||||
<div id="contact-via" class="unfocused">
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="contact-via" value="email"><span>Contact through Email</span>
|
||||
</label>
|
||||
{{ if .telegramEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="contact-via" value="telegram" id="contact-via-telegram"><span>Contact through Telegram</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .discordEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="contact-via" value="discord" id="contact-via-discord"><span>Contact through Discord</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
{{ if .matrixEnabled }}
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="contact-via" value="matrix" id="contact-via-matrix"><span>Contact through Matrix</span>
|
||||
</label>
|
||||
{{ end }}
|
||||
</div>
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
<label class="label supra" for="create-password">{{ .strings.password }}</label>
|
||||
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-password" aria-label="{{ .strings.password }}">
|
||||
|
||||
@@ -85,7 +154,13 @@
|
||||
<input type="password" class="input ~neutral !high mt-half mb-1" placeholder="{{ .strings.password }}" id="create-reenter-password" aria-label="{{ .strings.reEnterPassword }}">
|
||||
<label>
|
||||
<input type="submit" class="unfocused">
|
||||
<span class="button ~urge !normal full-width center supra submit">{{ .strings.createAccountButton }}</span>
|
||||
<span class="button ~urge !normal full-width center supra submit">
|
||||
{{ if .passwordReset }}
|
||||
{{ .strings.reset }}
|
||||
{{ else }}
|
||||
{{ .strings.createAccountButton }}
|
||||
{{ end }}
|
||||
</span>
|
||||
</label>
|
||||
</form>
|
||||
</div>
|
||||
@@ -110,4 +185,3 @@
|
||||
{{ template "form-base" . }}
|
||||
</body>
|
||||
</html>
|
||||
|
||||
|
||||
@@ -40,6 +40,6 @@
|
||||
</div>
|
||||
<i class="content">{{ .contactMessage }}</i>
|
||||
</div>
|
||||
<script src="{{ .urlBase }}/js/pwr.js" type="module"></script>
|
||||
<script src="{{ .urlBase }}/js/pwr-pin.js" type="module"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
149
html/setup.html
@@ -233,85 +233,92 @@
|
||||
</section>
|
||||
</div>
|
||||
<div class="card ~neutral !low mb-1 unfocused">
|
||||
<span class="heading">{{ .lang.Email.title }}</span>
|
||||
<p class="content" id="email-description"></p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span>{{ .lang.Email.method }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="email-method">
|
||||
<option value="">{{ .lang.Strings.disabled }}</option>
|
||||
<option value="smtp">SMTP</option>
|
||||
<option value="mailgun">Mailgun</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="row switch">
|
||||
<input type="checkbox" id="email-no_username"><span>{{ .lang.Email.useEmailAsUsername }}</span>
|
||||
<p class="support mb-1">{{ .lang.Email.useEmailAsUsernameNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.fromAddress }}</span>
|
||||
<input type="email" class="input ~neutral !normal mt-half mb-1" id="email-address" placeholder="mail@jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.senderName }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="email-from" value="Jellyfin">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.dateFormat }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="email-date_format" value="%d/%m/%y">
|
||||
<p class="support mb-1" id="email-dateformat-notice"></p>
|
||||
</label>
|
||||
<div>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span>
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col">
|
||||
<div id="email-smtp">
|
||||
<p class="subheading">SMTP</p>
|
||||
<span class="heading">{{ .lang.Messages.title }}</span>
|
||||
<p class="content" id="messages-description"></p>
|
||||
<label class="row switch pb-1">
|
||||
<input type="checkbox" id="messages-enabled" checked><span>{{ .lang.Strings.enabled }}</span>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.dateFormat }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half" id="email-date_format" value="%d/%m/%y">
|
||||
<p class="support mb-1" id="email-dateformat-notice"></p>
|
||||
</label>
|
||||
<div>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="true" checked><span>{{ .lang.Strings.time24h }}</span>
|
||||
</label>
|
||||
<label class="row switch pb-1">
|
||||
<input type="radio" name="email-24h" value="false"><span>{{ .lang.Strings.time12h }}</span>
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-sect">
|
||||
<span class="heading">{{ .lang.Email.title }}</span>
|
||||
<p class="content" id="email-description"></p>
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
<label class="label">
|
||||
<span>{{ .lang.Email.encryption }}</span>
|
||||
<span>{{ .lang.Email.method }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="smtp-encryption">
|
||||
<option value="starttls">STARTTLS ({{ .lang.Strings.port }} 587)</option>
|
||||
<option value="ssl_tls">SSL/TLS ({{ .lang.Strings.port }} 465)</option>
|
||||
<select id="email-method">
|
||||
<option value="">{{ .lang.Strings.disabled }}</option>
|
||||
<option value="smtp">SMTP</option>
|
||||
<option value="mailgun">Mailgun</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="smtp-server" placeholder="smtp.jellyf.in">
|
||||
<label class="row switch">
|
||||
<input type="checkbox" id="email-no_username"><span>{{ .lang.Email.useEmailAsUsername }}</span>
|
||||
<p class="support mb-1">{{ .lang.Email.useEmailAsUsernameNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="smtp-port" placeholder="587">
|
||||
<span class="mt-half">{{ .lang.Email.fromAddress }}</span>
|
||||
<input type="email" class="input ~neutral !normal mt-half mb-1" id="email-address" placeholder="mail@jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="smtp-username">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.password }}</span>
|
||||
<input type="password" class="input ~neutral !normal mt-half mb-1" id="smtp-password">
|
||||
<span class="mt-half">{{ .lang.Email.senderName }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="email-from" value="Jellyfin">
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-mailgun">
|
||||
<p class="subheading">Mailgun</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.mailgunApiURL }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_key">
|
||||
</label>
|
||||
<div class="col">
|
||||
<div id="email-smtp">
|
||||
<p class="subheading">SMTP</p>
|
||||
<label class="label">
|
||||
<span>{{ .lang.Email.encryption }}</span>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="smtp-encryption">
|
||||
<option value="starttls">STARTTLS ({{ .lang.Strings.port }} 587)</option>
|
||||
<option value="ssl_tls">SSL/TLS ({{ .lang.Strings.port }} 465)</option>
|
||||
</select>
|
||||
</div>
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.serverAddress }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="smtp-server" placeholder="smtp.jellyf.in">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.port }}</span>
|
||||
<input type="number" class="input ~neutral !normal mt-half mb-1" id="smtp-port" placeholder="587">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.username }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="smtp-username">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.password }}</span>
|
||||
<input type="password" class="input ~neutral !normal mt-half mb-1" id="smtp-password">
|
||||
</label>
|
||||
</div>
|
||||
<div id="email-mailgun">
|
||||
<p class="subheading">Mailgun</p>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Email.mailgunApiURL }}</span>
|
||||
<input type="url" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_url" placeholder="https://api.eu.mailgun.net/v3/mail.jellyf.in/messages">
|
||||
</label>
|
||||
<label class="label">
|
||||
<span class="mt-half">{{ .lang.Strings.apiKey }}</span>
|
||||
<input type="text" class="input ~neutral !normal mt-half mb-1" id="mailgun-api_key">
|
||||
</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -380,7 +387,11 @@
|
||||
<input type="checkbox" id="password_resets-link_reset"><span>{{ .lang.PasswordResets.resetLinks }}</span>
|
||||
<p class="support mb-1">{{ .lang.PasswordResets.resetLinksNotice }}</p>
|
||||
</label>
|
||||
<label class="row label">
|
||||
<label class="switch">
|
||||
<input type="checkbox" id="password_resets-set_password"><span>{{ .lang.PasswordResets.setPassword }}</span>
|
||||
<p class="support mb-1">{{ .lang.PasswordResets.setPasswordNotice }}</p>
|
||||
</label>
|
||||
<label class="label">
|
||||
<p class="mt-half">{{ .lang.PasswordResets.resetLinksLanguage }}</p>
|
||||
<div class="select ~neutral !normal mt-half mb-1">
|
||||
<select id="password_resets-language">
|
||||
|
||||
BIN
images/discord/1.jpg
Normal file
|
After Width: | Height: | Size: 37 KiB |
BIN
images/discord/2.jpg
Normal file
|
After Width: | Height: | Size: 41 KiB |
BIN
images/discord/3.jpg
Normal file
|
After Width: | Height: | Size: 33 KiB |
BIN
images/discord/4.jpg
Normal file
|
After Width: | Height: | Size: 85 KiB |
BIN
images/discord/5.jpg
Normal file
|
After Width: | Height: | Size: 46 KiB |
BIN
images/discord/6.jpg
Normal file
|
After Width: | Height: | Size: 109 KiB |
BIN
images/discord/7.jpg
Normal file
|
After Width: | Height: | Size: 59 KiB |
BIN
images/discord/8.jpg
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
images/matrix/1.png
Normal file
|
After Width: | Height: | Size: 179 KiB |
BIN
images/matrix/2.png
Normal file
|
After Width: | Height: | Size: 190 KiB |
BIN
images/matrix/3.png
Normal file
|
After Width: | Height: | Size: 4.8 KiB |
BIN
images/matrix/4.png
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
images/tg-settings.png
Normal file
|
After Width: | Height: | Size: 21 KiB |
BIN
images/tg.png
Normal file
|
After Width: | Height: | Size: 71 KiB |
@@ -42,7 +42,7 @@ func (rt *inviteDaemon) run() {
|
||||
}
|
||||
}
|
||||
|
||||
func (rt *inviteDaemon) shutdown() {
|
||||
func (rt *inviteDaemon) Shutdown() {
|
||||
rt.Stopped = true
|
||||
rt.ShutdownChannel <- "Down"
|
||||
<-rt.ShutdownChannel
|
||||
1
lang.go
@@ -117,6 +117,7 @@ type setupLang struct {
|
||||
JellyfinEmby langSection `json:"jellyfinEmby"`
|
||||
Ombi langSection `json:"ombi"`
|
||||
Email langSection `json:"email"`
|
||||
Messages langSection `json:"messages"`
|
||||
Notifications langSection `json:"notifications"`
|
||||
WelcomeEmails langSection `json:"welcomeEmails"`
|
||||
PasswordResets langSection `json:"passwordResets"`
|
||||
|
||||
204
lang/admin/da-dk.json
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"invites": "Invitationer",
|
||||
"accounts": "Konti",
|
||||
"settings": "Indstillinger",
|
||||
"inviteMonths": "Måneder",
|
||||
"inviteDays": "Dage",
|
||||
"inviteHours": "Timer",
|
||||
"inviteMinutes": "Minutter",
|
||||
"inviteNumberOfUses": "Antal anvendelser",
|
||||
"inviteDuration": "Invitations varighed",
|
||||
"warning": "Advarsel",
|
||||
"inviteInfiniteUsesWarning": "invitationer med uendelig brug kan blive misbrugt",
|
||||
"inviteSendToEmail": "Send til",
|
||||
"login": "Log på",
|
||||
"logout": "Log ud",
|
||||
"create": "Opret",
|
||||
"apply": "Anvend",
|
||||
"delete": "Slet",
|
||||
"add": "Tilføj",
|
||||
"select": "Vælg",
|
||||
"name": "Navn",
|
||||
"date": "Dato",
|
||||
"enabled": "Aktiveret",
|
||||
"disabled": "Deaktiveret",
|
||||
"reEnable": "Genaktiver",
|
||||
"disable": "Deaktiver",
|
||||
"admin": "Administrator",
|
||||
"updates": "Opdateringer",
|
||||
"update": "Opdatering",
|
||||
"download": "Hent",
|
||||
"search": "Søg",
|
||||
"advancedSettings": "Avanceret Indstillinger",
|
||||
"lastActiveTime": "Sidst Aktiv",
|
||||
"from": "Fra",
|
||||
"user": "Bruger",
|
||||
"expiry": "Udløb",
|
||||
"userExpiry": "Brugerens Udløb",
|
||||
"userExpiryDescription": "En specificeret tid efter hver tilmelding, sletter/deaktiverer jfa-go kontoen. Du kan ændre denne adfærd i indstillingerne.",
|
||||
"aboutProgram": "Om",
|
||||
"version": "Version",
|
||||
"commitNoun": "Commit",
|
||||
"newUser": "Ny Bruger",
|
||||
"profile": "Profil",
|
||||
"unknown": "Ukendt",
|
||||
"label": "Etiket",
|
||||
"announce": "Annoncere",
|
||||
"subject": "Emne",
|
||||
"message": "Meddelelse",
|
||||
"variables": "Variabler",
|
||||
"conditionals": "Betingelser",
|
||||
"preview": "Eksempel",
|
||||
"reset": "Nulstil",
|
||||
"edit": "Rediger",
|
||||
"donate": "Doner",
|
||||
"contactThrough": "Kontakt gennem:",
|
||||
"extendExpiry": "Forlæng udløb",
|
||||
"customizeMessages": "Tilpas Meddelelser",
|
||||
"customizeMessagesDescription": "Hvis du ikke vil bruge jfa-go's meddelelses skabeloner, kan du oprette din egen ved hjælp af Markdown.",
|
||||
"markdownSupported": "Markdown understøttes.",
|
||||
"modifySettings": "Rediger indstillinger",
|
||||
"modifySettingsDescription": "Anvend indstillinger fra en eksisterende profil, eller hent dem direkte fra en bruger.",
|
||||
"applyHomescreenLayout": "Anvend startskærmens layout",
|
||||
"sendDeleteNotificationEmail": "Send notifikations meddelelse",
|
||||
"sendDeleteNotifiationExample": "Din konto er blevet slettet.",
|
||||
"settingsRestart": "Genstart",
|
||||
"settingsRestarting": "Genstarter…",
|
||||
"settingsRestartRequired": "Genstart nødvendig",
|
||||
"settingsRestartRequiredDescription": "En genstart er nødvendig for at anvende nogle indstillinger du har ændret. Genstart nu eller senere?",
|
||||
"settingsApplyRestartLater": "Anvend, genstart senere",
|
||||
"settingsApplyRestartNow": "Anvend & genstart",
|
||||
"settingsApplied": "Indstillingerne anvendt.",
|
||||
"settingsRefreshPage": "Opdater siden om få sekunder.",
|
||||
"settingsRequiredOrRestartMessage": "Bemærk: {n} angiver et obligatorisk felt, {n} angiver at ændringer kræver genstart.",
|
||||
"settingsSave": "Gem",
|
||||
"ombiUserDefaults": "Ombi bruger standarder",
|
||||
"ombiUserDefaultsDescription": "Opret en Ombi bruger og konfigurer den, vælg den derefter nedenfor. Brugerens indstillinger/tilladelser gemmes og anvendes på nye Ombi brugere oprettet af jfa-go",
|
||||
"userProfiles": "Bruger Profiler",
|
||||
"userProfilesDescription": "Profiler anvendes på brugere når de opretter en konto. En profil inkluderer adgangsrettigheder til biblioteket og layout på startskærmen.",
|
||||
"userProfilesIsDefault": "Standard",
|
||||
"userProfilesLibraries": "Biblioteker",
|
||||
"addProfile": "Tilføj Profil",
|
||||
"addProfileDescription": "Opret en Jellyfin bruger og konfigurer den, vælg den derefter nedenfor. Når denne profil anvendes på en invitation, oprettes nye brugere med indstillingerne.",
|
||||
"addProfileNameOf": "Profil Navn",
|
||||
"addProfileStoreHomescreenLayout": "Gem startskærmens layout",
|
||||
"inviteNoUsersCreated": "Ingen endnu!",
|
||||
"inviteUsersCreated": "Oprettet brugere",
|
||||
"inviteNoProfile": "Ingen Profil",
|
||||
"inviteDateCreated": "Oprettet",
|
||||
"inviteRemainingUses": "Resterende anvendelser",
|
||||
"inviteNoInvites": "Ingen",
|
||||
"inviteExpiresInTime": "Udløber om {n}",
|
||||
"notifyEvent": "Meddel den:",
|
||||
"notifyInviteExpiry": "Ved udløb",
|
||||
"notifyUserCreation": "Ved oprettelse af brugere",
|
||||
"sendPIN": "Bed brugeren om at sende pinkoden nedenfor til botten.",
|
||||
"searchDiscordUser": "Begynd at skrive Discord brugernavnet for at finde brugeren.",
|
||||
"findDiscordUser": "Find Discord bruger",
|
||||
"linkMatrixDescription": "Indtast brugernavnet og adgangskoden til den bruger der skal bruges som en bot. Når indsendt, genstarter appen.",
|
||||
"matrixHomeServer": "Hjemme server adresse",
|
||||
"saveAsTemplate": "Gem som skabelon",
|
||||
"templates": "Skabeloner",
|
||||
"deleteTemplate": "Slet skabelon",
|
||||
"templateEnterName": "Indtast et navn for at gemme denne skabelon."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Ændret e-mail adresse på {n}.",
|
||||
"userCreated": "Bruger {n} oprettet.",
|
||||
"createProfile": "Oprettede profil {n}.",
|
||||
"saveSettings": "Indstillingerne blev gemt",
|
||||
"saveEmail": "E-mail gemt.",
|
||||
"sentAnnouncement": "Meddelelse sendt.",
|
||||
"setOmbiDefaults": "Ombi standarder gemt.",
|
||||
"updateApplied": "Opdatering anvendt, genstart.",
|
||||
"updateAppliedRefresh": "Opdatering anvendt, genindlæs venligst siden.",
|
||||
"telegramVerified": "Telegram konto verificeret.",
|
||||
"accountConnected": "Konto tilsluttet.",
|
||||
"errorConnection": "Kunne ikke oprette forbindelse til jfa-go.",
|
||||
"error401Unauthorized": "Adgang nægtet. Prøv at genindlæse siden.",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "Indstillingerne blev anvendt, men anvendelse af startskærmens layout mislykkedes muligvis.",
|
||||
"errorHomescreenAppliedNoSettings": "Startskærmens layout blev anvendt, men anvendelsen af indstillingerne mislykkedes muligvis.",
|
||||
"errorSettingsFailed": "Ansøgningen mislykkedes.",
|
||||
"errorLoginBlank": "Brugernavnet og/eller adgangskoden blev efterladt tomme.",
|
||||
"errorUnknown": "Ukendt fejl.",
|
||||
"errorSaveEmail": "Kunne ikke gemme e-mail.",
|
||||
"errorBlankFields": "Felter blev efterladt tomme",
|
||||
"errorDeleteProfile": "Kunne ikke slette profilen {n}",
|
||||
"errorLoadProfiles": "Profiler kunne ikke indlæses.",
|
||||
"errorCreateProfile": "Kunne ikke oprette profilen {n}",
|
||||
"errorSetDefaultProfile": "Standard profilen kunne ikke indstilles.",
|
||||
"errorLoadUsers": "Kunne ikke indlæse brugere.",
|
||||
"errorSaveSettings": "Kunne ikke gemme indstillingerne.",
|
||||
"errorLoadSettings": "Indstillingerne kunne ikke indlæses.",
|
||||
"errorSetOmbiDefaults": "Ombi standarderne kunne ikke gemmes.",
|
||||
"errorLoadOmbiUsers": "Kunne ikke indlæse ombi brugere.",
|
||||
"errorChangedEmailAddress": "Kunne ikke ændre e-mail adressen på {n}.",
|
||||
"errorFailureCheckLogs": "Mislykkedes (tjek konsol/logfiler)",
|
||||
"errorPartialFailureCheckLogs": "Delvis fejl (tjek konsol/logfiler)",
|
||||
"errorUserCreated": "Kunne ikke oprette bruger {n}.",
|
||||
"errorSendWelcomeEmail": "Kunne ikke sende velkomst meddelelse (tjek konsol/logfiler",
|
||||
"errorApplyUpdate": "Kunne ikke anvende opdateringen, prøv manuelt.",
|
||||
"errorCheckUpdate": "Kunne ikke kontrollere for opdatering.",
|
||||
"updateAvailable": "En ny opdatering er tilgængelig, tjek indstillingerne.",
|
||||
"noUpdatesAvailable": "Ingen nye opdateringer tilgængelige.",
|
||||
"savedAnnouncement": "Meddelelse gemt."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
"singular": "Rediger indstillinger for {n} bruger",
|
||||
"plural": "Rediger indstillinger for {n} brugere"
|
||||
},
|
||||
"deleteNUsers": {
|
||||
"singular": "Slet {n} bruger",
|
||||
"plural": "Slet {n} brugere"
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "Deaktiver {n} bruger",
|
||||
"plural": "Deaktiver {n} brugere"
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "Genaktiver {n} bruger",
|
||||
"plural": "Genaktiver {n} brugere"
|
||||
},
|
||||
"addUser": {
|
||||
"singular": "Tilføj bruger",
|
||||
"plural": "Tilføj brugere"
|
||||
},
|
||||
"deleteUser": {
|
||||
"singular": "Slet bruger",
|
||||
"plural": "Slet brugere"
|
||||
},
|
||||
"deletedUser": {
|
||||
"singular": "Slettede {n} bruger.",
|
||||
"plural": "Slettede {n} brugere."
|
||||
},
|
||||
"disabledUser": {
|
||||
"singular": "Deaktiveret {n} bruger.",
|
||||
"plural": "Deaktiverede {n} brugere."
|
||||
},
|
||||
"enabledUser": {
|
||||
"singular": "Aktiveret {n} bruger.",
|
||||
"plural": "Aktiveret {n} brugere."
|
||||
},
|
||||
"announceTo": {
|
||||
"singular": "Annoncer til {n} bruger",
|
||||
"plural": "Annoncer til {n} brugere"
|
||||
},
|
||||
"appliedSettings": {
|
||||
"singular": "Anvendte indstillinger til {n} bruger.",
|
||||
"plural": "Anvendte indstillinger til {n} brugere."
|
||||
},
|
||||
"extendExpiry": {
|
||||
"singular": "Forlæng udløbet for {n} bruger",
|
||||
"plural": "Forlæng udløbet for {n} brugere"
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"singular": "Forlængede udløb for {n} bruger.",
|
||||
"plural": "Forlængede udløb for {n} brugere."
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,7 +32,7 @@
|
||||
"modifySettings": "Einstellungen ändern",
|
||||
"modifySettingsDescription": "Wende Einstellungen von einem bestehenden Profil an, oder beziehe sie direkt von einem Benutzer.",
|
||||
"applyHomescreenLayout": "Startbildschirmlayout anwenden",
|
||||
"sendDeleteNotificationEmail": "Benachrichtigungs-E-Mail senden",
|
||||
"sendDeleteNotificationEmail": "Benachrichtigung senden",
|
||||
"sendDeleteNotifiationExample": "Dein Konto wurde gelöscht.",
|
||||
"settingsRestartRequired": "Neustart erforderlich",
|
||||
"settingsRestartRequiredDescription": "Ein Neustart ist notwendig, um einige Einstellungen anzuwenden, die du geändert hast. Jetzt oder später neu starten?",
|
||||
@@ -72,7 +72,7 @@
|
||||
"customizeMessages": "E-Mails 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": "E-Mail-Betreff",
|
||||
"subject": "Betreff",
|
||||
"message": "Nachricht",
|
||||
"markdownSupported": "Markdown wird unterstützt.",
|
||||
"advancedSettings": "Erweiterte Einstellungen",
|
||||
@@ -87,7 +87,20 @@
|
||||
"update": "Aktualisieren",
|
||||
"updates": "Aktualisierungen",
|
||||
"expiry": "Ablaufdatum",
|
||||
"extendExpiry": "Ablaufdatum verlängern"
|
||||
"extendExpiry": "Ablaufdatum verlängern",
|
||||
"reEnable": "Wieder aktivieren",
|
||||
"disable": "Deaktivieren",
|
||||
"donate": "Spenden",
|
||||
"conditionals": "Bedingungen",
|
||||
"contactThrough": "Kontakt über:",
|
||||
"sendPIN": "Bitte den Benutzer, die unten stehende PIN an den Bot zu senden.",
|
||||
"inviteMonths": "Monate",
|
||||
"add": "Hinzufügen",
|
||||
"select": "Auswählen",
|
||||
"searchDiscordUser": "Gib den Discord-Benutzername ein, um den Benutzer zu finden.",
|
||||
"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"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "E-Mail-Adresse von {n} geändert.",
|
||||
@@ -116,7 +129,7 @@
|
||||
"errorFailureCheckLogs": "Fehlgeschlagen (überprüfe die Konsole/Logs)",
|
||||
"errorPartialFailureCheckLogs": "Teilweiser Fehlschlag (überprüfe die Konsole/Logs)",
|
||||
"errorUserCreated": "Fehler beim Erstellen des Benutzers {n}.",
|
||||
"errorSendWelcomeEmail": "Fehler beim Senden der Willkommens-E-Mail (überprüfe die Konsole/Logs)",
|
||||
"errorSendWelcomeEmail": "Fehler beim Senden der Willkommensnachricht (überprüfe die Konsole/Logs)",
|
||||
"saveEmail": "E-Mail gespeichert.",
|
||||
"errorSaveEmail": "Fehler beim Speichern der E-Mail.",
|
||||
"sentAnnouncement": "Ankündigung gesendet.",
|
||||
@@ -124,7 +137,10 @@
|
||||
"errorApplyUpdate": "Fehler beim Anwenden der Aktualisierung, versuche es manuell.",
|
||||
"errorCheckUpdate": "Fehler beim Suchen nach Aktualisierungen.",
|
||||
"updateAvailable": "Eine neue Aktualisierung ist verfügbar, überprüfe die Einstellungen.",
|
||||
"noUpdatesAvailable": "Keinen neuen Aktualisierungen verfügbar."
|
||||
"noUpdatesAvailable": "Keinen neuen Aktualisierungen verfügbar.",
|
||||
"updateAppliedRefresh": "Update angewendet, bitte aktualisieren.",
|
||||
"telegramVerified": "Telegram-Konto verifiziert.",
|
||||
"accountConnected": "Konto verbunden."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@@ -162,6 +178,22 @@
|
||||
"extendedExpiry": {
|
||||
"singular": "Ablaufdatum für {n} Benutzer verlängern.",
|
||||
"plural": "Ablaufdatum für {n} Benutzer verlängern."
|
||||
},
|
||||
"disabledUser": {
|
||||
"plural": "Benutzer {n} Deaktiviert.",
|
||||
"singular": "Benutzer {n} Deaktiviert."
|
||||
},
|
||||
"enabledUser": {
|
||||
"singular": "Benutzer {n} Aktiviert.",
|
||||
"plural": "Benutzer {n} Aktiviert."
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "Benutzer {n} deaktivieren",
|
||||
"plural": "Deaktiviere {n} Benutzer"
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "Benutzer {n} wieder aktivieren",
|
||||
"plural": "Benutzer {n} wieder aktivieren"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
"create": "Create",
|
||||
"apply": "Apply",
|
||||
"delete": "Delete",
|
||||
"add": "Add",
|
||||
"select": "Select",
|
||||
"name": "Name",
|
||||
"date": "Date",
|
||||
"enabled": "Enabled",
|
||||
@@ -46,6 +48,7 @@
|
||||
"unknown": "Unknown",
|
||||
"label": "Label",
|
||||
"announce": "Announce",
|
||||
"templates": "Templates",
|
||||
"subject": "Subject",
|
||||
"message": "Message",
|
||||
"variables": "Variables",
|
||||
@@ -94,7 +97,14 @@
|
||||
"notifyEvent": "Notify on:",
|
||||
"notifyInviteExpiry": "On expiry",
|
||||
"notifyUserCreation": "On user creation",
|
||||
"sendPIN": "Ask the user to send the PIN below to the bot."
|
||||
"sendPIN": "Ask the user to send the PIN below to the bot.",
|
||||
"searchDiscordUser": "Start typing the Discord username to find the user.",
|
||||
"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",
|
||||
"templateEnterName": "Enter a name to save this template."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Changed email address of {n}.",
|
||||
@@ -103,10 +113,12 @@
|
||||
"saveSettings": "Settings were saved",
|
||||
"saveEmail": "Email saved.",
|
||||
"sentAnnouncement": "Announcement sent.",
|
||||
"savedAnnouncement": "Announcement saved.",
|
||||
"setOmbiDefaults": "Stored ombi defaults.",
|
||||
"updateApplied": "Update applied, please restart.",
|
||||
"updateAppliedRefresh": "Update applied, please refresh.",
|
||||
"telegramVerified": "Telegram account verified.",
|
||||
"accountConnected": "Account connected.",
|
||||
"errorConnection": "Couldn't connect to jfa-go.",
|
||||
"error401Unauthorized": "Unauthorized. Try refreshing the page.",
|
||||
"errorSettingsAppliedNoHomescreenLayout": "Settings were applied, but applying homescreen layout may have failed.",
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
"inviteSendToEmail": "Enviar a",
|
||||
"login": "Acceso",
|
||||
"logout": "Cerrar sesión",
|
||||
"create": "Cerrar sesión",
|
||||
"create": "Crear",
|
||||
"apply": "Aplicar",
|
||||
"delete": "Eliminar",
|
||||
"name": "Nombre",
|
||||
@@ -91,7 +91,20 @@
|
||||
"notifyEvent": "Notificar en:",
|
||||
"notifyInviteExpiry": "Al vencimiento",
|
||||
"notifyUserCreation": "Sobre la creación de usuarios",
|
||||
"conditionals": "Condicionales"
|
||||
"conditionals": "Condicionales",
|
||||
"donate": "Donar",
|
||||
"add": "Añadir",
|
||||
"templates": "Plantillas",
|
||||
"contactThrough": "Contactar a través de:",
|
||||
"select": "Seleccionar",
|
||||
"sendPIN": "Pídale al usuario que envíe el PIN a continuación al bot.",
|
||||
"searchDiscordUser": "Comienza a escribir el nombre de usuario de Discord para encontrar a la usuario.",
|
||||
"findDiscordUser": "Encontrar usuario de Discord",
|
||||
"linkMatrixDescription": "Ingrese el nombre de usuario y la contraseña para usar como bot. Una vez enviada, la aplicación se reiniciará",
|
||||
"matrixHomeServer": "Dirección del servidor de inicio",
|
||||
"saveAsTemplate": "Guardar plantilla",
|
||||
"deleteTemplate": "Eliminar plantilla",
|
||||
"templateEnterName": "Ingrese un nombre para guardar esta plantilla."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Se cambió la dirección de correo electrónico de {n}.",
|
||||
@@ -124,11 +137,15 @@
|
||||
"errorFailureCheckLogs": "Fallido (ver consola / registros)",
|
||||
"errorPartialFailureCheckLogs": "Fallo parcial (ver consola / registros)",
|
||||
"errorUserCreated": "No se pudo crear el usuario {n}.",
|
||||
"errorSendWelcomeEmail": "No se pudo enviar el correo electrónico de bienvenida (verifique la consola / registros)",
|
||||
"errorSendWelcomeEmail": "No se pudo enviar el mensaje de bienvenida (verifique la consola / registros)",
|
||||
"errorApplyUpdate": "No se pudo aplicar la actualización, intente manualmente.",
|
||||
"errorCheckUpdate": "No se pudo comprobar la actualización.",
|
||||
"updateAvailable": "Hay una nueva actualización disponible, verifique la configuración.",
|
||||
"noUpdatesAvailable": "No hay nuevas actualizaciones disponibles."
|
||||
"noUpdatesAvailable": "No hay nuevas actualizaciones disponibles.",
|
||||
"updateAppliedRefresh": "Actualización aplicada, actualice.",
|
||||
"accountConnected": "Cuenta conectada.",
|
||||
"savedAnnouncement": "Anuncio guardado.",
|
||||
"telegramVerified": "Cuenta de Telegram verificada."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
|
||||
@@ -34,7 +34,7 @@
|
||||
"modifySettings": "Modifier les paramètres",
|
||||
"modifySettingsDescription": "Appliquez les paramètres à partir d'un profil existant ou obtenez-les directement auprès d'un utilisateur.",
|
||||
"applyHomescreenLayout": "Appliquer la disposition de l'écran d'accueil",
|
||||
"sendDeleteNotificationEmail": "Envoyer un e-mail de notification",
|
||||
"sendDeleteNotificationEmail": "Envoyer un message de notification",
|
||||
"sendDeleteNotifiationExample": "Votre compte a été supprimé.",
|
||||
"settingsRestartRequired": "Redémarrage nécessaire",
|
||||
"settingsRestartRequiredDescription": "Un redémarrage est nécessaire pour appliquer certains paramètres que vous avez modifiés. Redémarrer maintenant ou plus tard ?",
|
||||
@@ -74,7 +74,7 @@
|
||||
"customizeMessagesDescription": "Si vous ne souhaitez pas utiliser les modèles d'e-mails de jfa-go, vous pouvez créer les vôtres à l'aide de Markdown.",
|
||||
"variables": "Variables",
|
||||
"preview": "Aperçu",
|
||||
"reset": "Réinitialiser",
|
||||
"reset": "Réinitialisation",
|
||||
"edit": "Éditer",
|
||||
"customizeMessages": "Personnaliser les e-mails",
|
||||
"inviteDuration": "Durée de l'invitation",
|
||||
@@ -90,7 +90,18 @@
|
||||
"update": "Mise à jour",
|
||||
"download": "Téléchargement",
|
||||
"search": "Recherche",
|
||||
"conditionals": "Conditions"
|
||||
"conditionals": "Conditions",
|
||||
"userExpiryDescription": "Un laps de temps spécifié après chaque inscription, jfa-go supprimera / désactivera le compte. Vous pouvez modifier ce comportement dans les paramètres.",
|
||||
"donate": "Faire un don",
|
||||
"extendExpiry": "Prolonger l'expiration",
|
||||
"contactThrough": "Contacté par :",
|
||||
"sendPIN": "Demandez à l'utilisateur d'envoyer le code PIN ci-dessous au bot.",
|
||||
"add": "Ajouter",
|
||||
"select": "Sélectionner",
|
||||
"findDiscordUser": "Trouver l'utilisateur Discord",
|
||||
"linkMatrixDescription": "Entrez le nom d'utilisateur et le mot de passe de l'utilisateur pour l’utilisateur comme bot. Une fois soumis, l'application va redémarrer.",
|
||||
"searchDiscordUser": "Commencez à taper le nom d'utilisateur Discord pour trouver l'utilisateur.",
|
||||
"matrixHomeServer": "Adresse du serveur"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Adresse e-mail modifiée de {n}.",
|
||||
@@ -119,11 +130,18 @@
|
||||
"errorFailureCheckLogs": "Échec (vérifier la console / les journaux)",
|
||||
"errorPartialFailureCheckLogs": "Panne partielle (vérifier la console / les journaux)",
|
||||
"errorUserCreated": "Echec lors de la création de l'utilisateur {n}.",
|
||||
"errorSendWelcomeEmail": "Echec lors de l'envoi du mail de bienvenue (vérifier la console/les journaux)",
|
||||
"errorSendWelcomeEmail": "Echec lors de l'envoi du message de bienvenue (vérifier la console/les journaux)",
|
||||
"sentAnnouncement": "Annonce envoyée.",
|
||||
"saveEmail": "Email enregistré.",
|
||||
"errorSaveEmail": "Échec de l'enregistrement de l'e-mail.",
|
||||
"updateApplied": "Mise à jour appliquée, veuillez redémarrer."
|
||||
"updateApplied": "Mise à jour appliquée, veuillez redémarrer.",
|
||||
"errorApplyUpdate": "Échec de l'application de la mise à jour, essayez manuellement.",
|
||||
"errorCheckUpdate": "Échec de la vérification de la mise à jour.",
|
||||
"updateAvailable": "Une nouvelle mise à jour est disponible, vérifiez les paramètres.",
|
||||
"noUpdatesAvailable": "Aucune nouvelle mise à jour disponible.",
|
||||
"telegramVerified": "Compte Telegram vérifié.",
|
||||
"updateAppliedRefresh": "Mise à jour appliquée, veuillez actualiser.",
|
||||
"accountConnected": "Compte connecté."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
@@ -153,6 +171,30 @@
|
||||
"announceTo": {
|
||||
"singular": "Annonce à {n} utilisateur",
|
||||
"plural": "Annonce à {n} utilisateurs"
|
||||
},
|
||||
"enabledUser": {
|
||||
"plural": "{n} utilisateurs activés.",
|
||||
"singular": "{n} utilisateur activé."
|
||||
},
|
||||
"extendExpiry": {
|
||||
"singular": "Prolonger l'expiration pour {n} utilisateur",
|
||||
"plural": "Prolonger l'expiration pour {n} utilisateurs"
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"singular": "Expiration prolongée pour {n} utilisateur.",
|
||||
"plural": "Expiration prolongée pour {n} utilisateurs."
|
||||
},
|
||||
"disableUsers": {
|
||||
"singular": "Désactiver {n} utilisateur",
|
||||
"plural": "Désactiver {n} utilisateurs"
|
||||
},
|
||||
"reEnableUsers": {
|
||||
"singular": "Ré-activer {n} utilisateur",
|
||||
"plural": "Ré-activer {n} utilisateurs"
|
||||
},
|
||||
"disabledUser": {
|
||||
"singular": "{n} utilisateur désactivé.",
|
||||
"plural": "{n} utilisateurs désactivés."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
"modifySettings": "Instellingen aanpassen",
|
||||
"modifySettingsDescription": "Pas instellingen van een bestaand profiel toe, of neem ze direct over van een gebruiker.",
|
||||
"applyHomescreenLayout": "Sla startpagina indeling op",
|
||||
"sendDeleteNotificationEmail": "Stuur meldingse-mail",
|
||||
"sendDeleteNotificationEmail": "Stuur melding",
|
||||
"sendDeleteNotifiationExample": "Je account is verwijderd.",
|
||||
"settingsRestartRequired": "Herstart nodig",
|
||||
"settingsRestartRequiredDescription": "Er is een herstart nodig om de wijzigingen door te voeren. Herstart nu of later?",
|
||||
@@ -67,12 +67,12 @@
|
||||
"settingsRestarting": "Aan het herstarten…",
|
||||
"announce": "Aankondiging",
|
||||
"markdownSupported": "Markdown wordt ondersteund.",
|
||||
"subject": "E-mailonderwerp",
|
||||
"subject": "Onderwerp",
|
||||
"message": "Bericht",
|
||||
"variables": "Variabelen",
|
||||
"customizeMessagesDescription": "Als je de e-mailsjablonen van jfa-go niet wilt gebruiken, kun je met gebruik van Markdown je eigen aanmaken.",
|
||||
"preview": "Voorbeeld",
|
||||
"reset": "Resetten",
|
||||
"reset": "Reset",
|
||||
"edit": "Bewerken",
|
||||
"customizeMessages": "E-mails aanpassen",
|
||||
"inviteDuration": "Geldigheidsduur uitnodiging",
|
||||
@@ -91,7 +91,20 @@
|
||||
"inviteMonths": "Maanden",
|
||||
"reEnable": "Opnieuw inschakelen",
|
||||
"disable": "Uitschakelen",
|
||||
"conditionals": "Voorwaarden"
|
||||
"conditionals": "Voorwaarden",
|
||||
"donate": "Doneer",
|
||||
"contactThrough": "Stuur bericht via:",
|
||||
"sendPIN": "Vraag de gebruiker om onderstaande pincode naar de bot te sturen.",
|
||||
"add": "Voeg toe",
|
||||
"searchDiscordUser": "Begin de Discord gebruikersnaam te typen om de gebruiker te vinden.",
|
||||
"linkMatrixDescription": "Vul de gebruikersnaam en wachtwoord in van de gebruiker om als bot te gebruiken. De app start zodra ze zijn verstuurd.",
|
||||
"select": "Selecteer",
|
||||
"findDiscordUser": "Zoek Discord gebruiker",
|
||||
"matrixHomeServer": "Adres home server",
|
||||
"templates": "Sjablonen",
|
||||
"templateEnterName": "Voer een naam in om dit sjabloon op te slaan.",
|
||||
"saveAsTemplate": "Sla op als sjabloon",
|
||||
"deleteTemplate": "Verwijder sjabloon"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "E-mailadres van {n} gewijzigd.",
|
||||
@@ -119,7 +132,7 @@
|
||||
"errorChangedEmailAddress": "Wijzigen van e-mailadres van {n} mislukt.",
|
||||
"errorFailureCheckLogs": "Mislukt (controleer console/logbestanden)",
|
||||
"errorPartialFailureCheckLogs": "Gedeeltelijke fout (controleer console/logbestanden)",
|
||||
"errorSendWelcomeEmail": "Versturen van welkomste-mail is mislukt (zie console/logs)",
|
||||
"errorSendWelcomeEmail": "Versturen van welkomstbericht is mislukt (zie console/logs)",
|
||||
"errorUserCreated": "Aanmaken van gebruiker {n} is mislukt.",
|
||||
"sentAnnouncement": "Aankondiging verzonden.",
|
||||
"saveEmail": "E-mail opgeslagen.",
|
||||
@@ -128,7 +141,11 @@
|
||||
"errorApplyUpdate": "Installatie van update mislukt, probeer handmatig.",
|
||||
"errorCheckUpdate": "Controleren op update mislukt.",
|
||||
"updateAvailable": "Er is een nieuwe update beschikbaar, kijk bij instellingen.",
|
||||
"noUpdatesAvailable": "Geen nieuwe updates beschikbaar."
|
||||
"noUpdatesAvailable": "Geen nieuwe updates beschikbaar.",
|
||||
"telegramVerified": "Telegram-account goedgekeurd.",
|
||||
"updateAppliedRefresh": "Update toegepast, ververs alsjeblieft.",
|
||||
"accountConnected": "Account gekoppeld.",
|
||||
"savedAnnouncement": "Aankondiging opgeslagen."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
"modifySettings": "Modificar configurações",
|
||||
"modifySettingsDescription": "Aplique as configurações de um perfil existente ou obtenha-as diretamente de um usuário.",
|
||||
"applyHomescreenLayout": "Aplicar layout na tela inicial",
|
||||
"sendDeleteNotificationEmail": "Enviar email de notificação",
|
||||
"sendDeleteNotificationEmail": "Enviar mensagem de notificação",
|
||||
"sendDeleteNotifiationExample": "Sua conta foi deletada.",
|
||||
"settingsRestartRequired": "Necessário reiniciar",
|
||||
"settingsRestartRequiredDescription": "É necessário reiniciar para aplicar algumas configurações alteradas. Deseja reiniciar agora ou mais tarde?",
|
||||
@@ -66,7 +66,7 @@
|
||||
"settingsRestart": "Reiniciar",
|
||||
"settingsRestarting": "Reiniciando…",
|
||||
"announce": "Anunciar",
|
||||
"subject": "Assunto do email",
|
||||
"subject": "Assunto",
|
||||
"message": "Mensagem",
|
||||
"markdownSupported": "Suporte a Markdown.",
|
||||
"customizeMessagesDescription": "Se não quiser usar os modelos de email do jfa-go, você pode criar o seu próprio usando o Markdown.",
|
||||
@@ -91,7 +91,20 @@
|
||||
"inviteMonths": "Meses",
|
||||
"reEnable": "Reativar",
|
||||
"disable": "Desativar",
|
||||
"conditionals": "Condicionais"
|
||||
"conditionals": "Condicionais",
|
||||
"donate": "Doar",
|
||||
"contactThrough": "Contato através:",
|
||||
"sendPIN": "Peça ao usuário para enviar o PIN abaixo para o bot.",
|
||||
"searchDiscordUser": "Digite o nome de usuário do Discord.",
|
||||
"findDiscordUser": "Encontrar usuário Discord",
|
||||
"add": "Adicionar",
|
||||
"linkMatrixDescription": "Digite o nome de usuário e a senha para usar como bot. Depois de enviado, o aplicativo será reiniciado.",
|
||||
"select": "Selecionar",
|
||||
"templates": "Modelos",
|
||||
"matrixHomeServer": "Endereço do servidor local",
|
||||
"saveAsTemplate": "Salvar o modelo",
|
||||
"deleteTemplate": "Deletar modelo",
|
||||
"templateEnterName": "Digite um nome para salvar este modelo."
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "Endereço de e-mail alterado de {n}.",
|
||||
@@ -120,7 +133,7 @@
|
||||
"errorFailureCheckLogs": "Falha (verificar console/logs)",
|
||||
"errorPartialFailureCheckLogs": "Falha parcial (verificar console/logs)",
|
||||
"errorUserCreated": "Falha ao criar o usuário {n}.",
|
||||
"errorSendWelcomeEmail": "Falha ao enviar e-mail de boas-vindas (verifique console/logs)",
|
||||
"errorSendWelcomeEmail": "Falha ao enviar mensagem de boas-vindas (verifique console/logs)",
|
||||
"sentAnnouncement": "Comunicado enviado.",
|
||||
"saveEmail": "Email salvo.",
|
||||
"errorSaveEmail": "Falha ao salvar o email.",
|
||||
@@ -128,7 +141,11 @@
|
||||
"errorApplyUpdate": "Falha ao aplicar a atualização, tente manualmente.",
|
||||
"updateAvailable": "Uma nova atualização está disponível, verifique as configurações.",
|
||||
"errorCheckUpdate": "Falha ao verificar atualizações.",
|
||||
"noUpdatesAvailable": "Nenhuma atualização disponível."
|
||||
"noUpdatesAvailable": "Nenhuma atualização disponível.",
|
||||
"telegramVerified": "Conta do Telegram verificada.",
|
||||
"updateAppliedRefresh": "Atualização instalada, atualize.",
|
||||
"accountConnected": "Conta conectada.",
|
||||
"savedAnnouncement": "Anúncio salvo."
|
||||
},
|
||||
"quantityStrings": {
|
||||
"modifySettingsFor": {
|
||||
|
||||
204
lang/admin/zh-hans.json
Normal file
@@ -0,0 +1,204 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"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": "重新启用",
|
||||
"disable": "禁用",
|
||||
"admin": "管理员",
|
||||
"updates": "更新",
|
||||
"update": "更新",
|
||||
"download": "下载",
|
||||
"search": "搜索",
|
||||
"advancedSettings": "高级设置",
|
||||
"lastActiveTime": "上次活动",
|
||||
"from": "从",
|
||||
"user": "用户",
|
||||
"expiry": "到期",
|
||||
"userExpiry": "用户到期",
|
||||
"userExpiryDescription": "每次注册后的指定时间,jfa-go 将删除/禁用该帐户。您可以在设置中更改此行为。",
|
||||
"aboutProgram": "关于",
|
||||
"version": "版本",
|
||||
"commitNoun": "提交",
|
||||
"newUser": "新用户",
|
||||
"profile": "个人资料",
|
||||
"unknown": "未知",
|
||||
"label": "标签",
|
||||
"announce": "宣布",
|
||||
"templates": "模板",
|
||||
"subject": "主题",
|
||||
"message": "信息",
|
||||
"variables": "变量",
|
||||
"conditionals": "条件性条款",
|
||||
"preview": "预览",
|
||||
"reset": "重设",
|
||||
"edit": "编辑",
|
||||
"donate": "捐助",
|
||||
"contactThrough": "联系方式:",
|
||||
"extendExpiry": "延长有效期",
|
||||
"customizeMessages": "自定义消息",
|
||||
"customizeMessagesDescription": "如果不想使用 jfa-go 的消息模板,可以使用 Markdown 创建自己的消息模板。",
|
||||
"markdownSupported": "已支持Markdown。",
|
||||
"modifySettings": "修改设置",
|
||||
"modifySettingsDescription": "应用现有配置文件中的设置,或直接从用户处获取设置。",
|
||||
"applyHomescreenLayout": "应用主屏幕布局",
|
||||
"sendDeleteNotificationEmail": "发送通知消息",
|
||||
"sendDeleteNotifiationExample": "您的帐户已被删除。",
|
||||
"settingsRestart": "重启",
|
||||
"settingsRestarting": "正在重启……",
|
||||
"settingsRestartRequired": "需要重启",
|
||||
"settingsRestartRequiredDescription": "需要重新启动才能应用您更改的某些设置。现在重启还是稍后重启?",
|
||||
"settingsApplyRestartLater": "应用,稍后重启",
|
||||
"settingsApplyRestartNow": "应用并重启",
|
||||
"settingsApplied": "已应用设置。",
|
||||
"settingsRefreshPage": "几秒钟后刷新页面。",
|
||||
"settingsRequiredOrRestartMessage": "注意:{n} 表示必填字段,{n} 表示更改需要重新启动。",
|
||||
"settingsSave": "保存",
|
||||
"ombiUserDefaults": "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": "输入名称以保存此模板。"
|
||||
},
|
||||
"notifications": {
|
||||
"changedEmailAddress": "更改了 {n} 的电子邮件地址。",
|
||||
"userCreated": "用户 {n} 已创建。",
|
||||
"createProfile": "创建了配置文件{n}。",
|
||||
"saveSettings": "设置已保存",
|
||||
"saveEmail": "电子邮件已保存。",
|
||||
"sentAnnouncement": "公告已发出。",
|
||||
"savedAnnouncement": "公告已保存。",
|
||||
"setOmbiDefaults": "存储的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": "加载配置列表失败。",
|
||||
"errorSetOmbiDefaults": "存储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} 个用户的有效期"
|
||||
},
|
||||
"extendedExpiry": {
|
||||
"singular": "延长了 {n} 个用户的有效期。",
|
||||
"plural": "延长了 {n} 个用户的有效期。"
|
||||
}
|
||||
}
|
||||
}
|
||||
26
lang/common/da-dk.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"username": "Brugernavn",
|
||||
"password": "Adgangskode",
|
||||
"emailAddress": "E-mail Adresse",
|
||||
"name": "Navn",
|
||||
"submit": "Indsend",
|
||||
"send": "Send",
|
||||
"success": "Succes",
|
||||
"error": "Fejl",
|
||||
"copy": "Kopiér",
|
||||
"copied": "Kopiret",
|
||||
"time24h": "24 timers tid",
|
||||
"time12h": "12 timers tid",
|
||||
"linkTelegram": "Link Telegram",
|
||||
"contactEmail": "Kontakt gennem E-mail",
|
||||
"contactTelegram": "Kontakt gennem Telegram",
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Kontakt gennem Discord",
|
||||
"theme": "Tema"
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,13 @@
|
||||
"theme": "Thema",
|
||||
"time24h": "24h-Format",
|
||||
"time12h": "12h-Format",
|
||||
"copied": "Kopiert"
|
||||
"copied": "Kopiert",
|
||||
"linkTelegram": "Link Telegram",
|
||||
"contactEmail": "Kontakt über E-Mail",
|
||||
"contactTelegram": "Kontakt über Telegram",
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"send": "Senden",
|
||||
"contactDiscord": "Kontakt über Discord"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
"emailAddress": "Email Address",
|
||||
"name": "Name",
|
||||
"submit": "Submit",
|
||||
"send": "Send",
|
||||
"success": "Success",
|
||||
"error": "Error",
|
||||
"copy": "Copy",
|
||||
@@ -17,6 +18,9 @@
|
||||
"linkTelegram": "Link Telegram",
|
||||
"contactEmail": "Contact through Email",
|
||||
"contactTelegram": "Contact through Telegram",
|
||||
"linkDiscord": "Link Discord",
|
||||
"linkMatrix": "Link Matrix",
|
||||
"contactDiscord": "Contact through Discord",
|
||||
"theme": "Theme"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,11 @@
|
||||
"copy": "Copiar",
|
||||
"copied": "Copiado",
|
||||
"time24h": "24 horas",
|
||||
"time12h": "24 horas",
|
||||
"theme": "Tema"
|
||||
"time12h": "12 horas",
|
||||
"theme": "Tema",
|
||||
"send": "Enviar",
|
||||
"contactDiscord": "Contacta a través de Discord",
|
||||
"contactEmail": "Contacta a través de email",
|
||||
"contactTelegram": "Contacta a través de Telegram"
|
||||
}
|
||||
}
|
||||
|
||||
26
lang/common/fa-ir.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "انگلیسی"
|
||||
},
|
||||
"strings": {
|
||||
"username": "نام کاربری",
|
||||
"password": "کلمه عبور",
|
||||
"emailAddress": "پست الکترونیک",
|
||||
"name": "نام",
|
||||
"submit": "تایید",
|
||||
"send": "ارسال",
|
||||
"success": "موفقیت",
|
||||
"error": "خطا",
|
||||
"copy": "کپی",
|
||||
"copied": "کپی شد",
|
||||
"time24h": "ساعت 24 ساعت",
|
||||
"time12h": "ساعت 12 ساعت",
|
||||
"linkTelegram": "لینک تلگرام",
|
||||
"contactEmail": "تماس از طریق ایمیل",
|
||||
"contactTelegram": "تماس از طریق تلگرام",
|
||||
"linkDiscord": "پیوند دیسکورد",
|
||||
"linkMatrix": "پیوند ماتریکس",
|
||||
"contactDiscord": "از طریق دیسکورد تماس بگیرید",
|
||||
"theme": "موضوع"
|
||||
}
|
||||
}
|
||||
@@ -14,6 +14,14 @@
|
||||
"copy": "Copier",
|
||||
"time24h": "Temps 24h",
|
||||
"time12h": "Temps 12h",
|
||||
"theme": "Thème"
|
||||
"theme": "Thème",
|
||||
"copied": "Copié",
|
||||
"linkTelegram": "Lien Telegram",
|
||||
"contactEmail": "Contact par e-mail",
|
||||
"contactTelegram": "Contact par Telegram",
|
||||
"linkDiscord": "Lier Discord",
|
||||
"linkMatrix": "Lier Matrix",
|
||||
"send": "Envoyer",
|
||||
"contactDiscord": "Contacter par Discord"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,19 @@
|
||||
"password": "Wachtwoord",
|
||||
"emailAddress": "E-mailadres",
|
||||
"submit": "Verstuur",
|
||||
"success": "Success",
|
||||
"success": "Succes",
|
||||
"error": "Fout",
|
||||
"copy": "Kopiëer",
|
||||
"theme": "Thema",
|
||||
"time24h": "24u-formaat",
|
||||
"time12h": "12u-formaat",
|
||||
"copied": "Gekopieerd"
|
||||
"copied": "Gekopieerd",
|
||||
"linkTelegram": "Koppel Telegram",
|
||||
"contactEmail": "Stuur e-mailbericht",
|
||||
"contactTelegram": "Stuur Telegram-bericht",
|
||||
"send": "Verstuur",
|
||||
"linkDiscord": "Koppel Discord",
|
||||
"linkMatrix": "Koppel Matrix",
|
||||
"contactDiscord": "Stuur Discord bericht"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@
|
||||
"theme": "Tema",
|
||||
"time24h": "Horário 24h",
|
||||
"time12h": "Horário 12h",
|
||||
"copied": "Copiado"
|
||||
"copied": "Copiado",
|
||||
"linkTelegram": "Link do Telegram",
|
||||
"contactEmail": "Contato por Email",
|
||||
"contactTelegram": "Contato pelo Telegram",
|
||||
"send": "Enviar",
|
||||
"linkDiscord": "Link do Discord",
|
||||
"linkMatrix": "Link do Matrix",
|
||||
"contactDiscord": "Contato através do Discord"
|
||||
}
|
||||
}
|
||||
|
||||
26
lang/common/zh-hans.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"strings": {
|
||||
"username": "用户名",
|
||||
"password": "密码",
|
||||
"emailAddress": "电子邮箱",
|
||||
"name": "名称",
|
||||
"submit": "提交",
|
||||
"send": "发送",
|
||||
"success": "成功",
|
||||
"error": "错误",
|
||||
"copy": "复制",
|
||||
"copied": "已复制",
|
||||
"time24h": "24小时制",
|
||||
"time12h": "12小时制",
|
||||
"linkTelegram": "关联Telegram",
|
||||
"contactEmail": "通过邮件联系",
|
||||
"contactTelegram": "通过Telegram联系",
|
||||
"linkDiscord": "关联Discord",
|
||||
"linkMatrix": "关联Matrix",
|
||||
"contactDiscord": "通过Discord联系",
|
||||
"theme": "主题"
|
||||
}
|
||||
}
|
||||
77
lang/email/da-dk.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Ignorer venligst hvis dette ikke var dig.",
|
||||
"helloUser": "Hej {username},",
|
||||
"reason": "Grund"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "Bruger oprettet",
|
||||
"title": "Meddelelse: Bruger oprettet",
|
||||
"aUserWasCreated": "En bruger blev oprettet med koden {code}.",
|
||||
"time": "Tid",
|
||||
"notificationNotice": "Meddelelse: Notifikations e-mails kan blive ændret på admin-siden."
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "Invitationens udløb",
|
||||
"title": "Meddelelse: Invitation udløbet",
|
||||
"inviteExpired": "Invitation udløbet.",
|
||||
"expiredAt": "Koden {code} udløber om {time}.",
|
||||
"notificationNotice": "Meddelelse: Notifikations e-mails kan blive ændret på admin-siden."
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "Nulstil Adgangskode",
|
||||
"title": "Nulstilling af adgangskode anmodet - Jellyfin",
|
||||
"someoneHasRequestedReset": "Nogen har for nylig anmodet om nulstilling af din adgangskode på Jellyfin.",
|
||||
"ifItWasYou": "Hvis dette var dig, så indtast venligst pinkoden nedenunder ind i prompten.",
|
||||
"ifItWasYouLink": "Hvis dette var dig, så tryk på linket nedenunder.",
|
||||
"codeExpiry": "Koden udløber den {date}, klokken {time} UTC, hvilket er om {expiresInMinutes}.",
|
||||
"pin": "PINKODE"
|
||||
},
|
||||
"userDeleted": {
|
||||
"name": "Sletning af bruger",
|
||||
"title": "Din konto blev slettet - Jellyfin",
|
||||
"yourAccountWasDeleted": "Din Jellyfin konto blev slettet."
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "Bruger deaktiveret",
|
||||
"title": "Din konto er blevet deaktiveret - Jellyfin",
|
||||
"yourAccountWasDisabled": "Din konto blev deaktiveret."
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "Bruger aktiveret",
|
||||
"title": "Din konto er blevet genaktiveret - Jellyfin",
|
||||
"yourAccountWasEnabled": "Din konto blev genaktiveret."
|
||||
},
|
||||
"inviteEmail": {
|
||||
"name": "Invitations e-mail",
|
||||
"title": "Invitation - Jellyfin",
|
||||
"hello": "Hej",
|
||||
"youHaveBeenInvited": "Du er blevet inviteret til Jellyfin.",
|
||||
"toJoin": "Tilmeld dig med linket nedenfor.",
|
||||
"inviteExpiry": "Invitationen vil udløbe den {date} kl. {time}, hvilket er om {expiresInMinutes}, så skynd dig.",
|
||||
"linkButton": "Opsæt din konto"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "Velkommen",
|
||||
"title": "Velkommen til Jellyfin",
|
||||
"welcome": "Velkommen til Jellyfin!",
|
||||
"youCanLoginWith": "Du kan logge ind med nedenstående oplysninger",
|
||||
"yourAccountWillExpire": "Din konto udløber den {date}.",
|
||||
"jellyfinURL": "URL"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"name": "Bekræftelses e-mail",
|
||||
"title": "Bekræft din e-mail - Jellyfin",
|
||||
"clickBelow": "Klik på linket nedenunder for at bekræfte din e-mail adresse og start med at bruge Jellyfin.",
|
||||
"confirmEmail": "Bekræft E-mail"
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "Brugerens udløb",
|
||||
"title": "Din konto er udløbet - Jellyfin",
|
||||
"yourAccountHasExpired": "Din konto er udløbet.",
|
||||
"contactTheAdmin": "Kontakt administratoren for mere information."
|
||||
}
|
||||
}
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Deutsch (DE)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Wenn du das nicht warst, ignoriere bitte diese E-Mail.",
|
||||
"ifItWasNotYou": "Wenn du das nicht warst, ignoriere bitte dies.",
|
||||
"reason": "Grund",
|
||||
"helloUser": "Hallo {username},"
|
||||
},
|
||||
@@ -27,7 +27,8 @@
|
||||
"ifItWasYou": "Wenn du das warst, gib die PIN unten in die Eingabeaufforderung ein.",
|
||||
"codeExpiry": "Der Code wird am {date}, um {time} UTC ablaufen, was in {expiresInMinutes} ist.",
|
||||
"pin": "PIN",
|
||||
"name": "Passwortzurücksetzung"
|
||||
"name": "Passwortzurücksetzung",
|
||||
"ifItWasYouLink": "Wenn du das warst, klick auf den Link unten."
|
||||
},
|
||||
"userDeleted": {
|
||||
"title": "Dein Konto wurde gelöscht - Jellyfin",
|
||||
@@ -48,7 +49,8 @@
|
||||
"welcome": "Willkommen bei Jellyfin!",
|
||||
"youCanLoginWith": "Du kannst dich mit den mit den untenstehenden Zugangsdaten anmelden",
|
||||
"jellyfinURL": "URL",
|
||||
"name": "Willkommens-E-Mail"
|
||||
"name": "Willkommen",
|
||||
"yourAccountWillExpire": "Dein Konto läuft am {date} ab."
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"title": "Bestätige deine E-Mail - Jellyfin",
|
||||
@@ -61,5 +63,15 @@
|
||||
"title": "Dein Konto ist abgelaufen - Jellyfin",
|
||||
"yourAccountHasExpired": "Dein Konto ist abgelaufen.",
|
||||
"contactTheAdmin": "Kontaktiere den Administrator für weitere Informationen."
|
||||
},
|
||||
"userDisabled": {
|
||||
"name": "Benutzer deaktiviert",
|
||||
"title": "Dein Konto wurde deaktiviert - Jellyfin",
|
||||
"yourAccountWasDisabled": "Dein Konto wurde deaktiviert."
|
||||
},
|
||||
"userEnabled": {
|
||||
"name": "Benutzer aktiviert",
|
||||
"title": "Dein Konto wurde wieder freigeschaltet - Jellyfin",
|
||||
"yourAccountWasEnabled": "Dein Konto wurde wieder aktiviert."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
"author": "https://github.com/Cornichon420"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Si ce n'était pas toi, tu peux ignorer ce mail.",
|
||||
"ifItWasNotYou": "Si ce n'était pas toi, tu peux ignorer ceci.",
|
||||
"reason": "Motif",
|
||||
"helloUser": "Salut {username},"
|
||||
},
|
||||
@@ -50,7 +50,7 @@
|
||||
"title": "Bienvenue sur Jellyfin",
|
||||
"welcome": "Bienvenue sur Jellyfin !",
|
||||
"jellyfinURL": "URL",
|
||||
"name": "Courriel de bienvenue",
|
||||
"name": "Bienvenue",
|
||||
"yourAccountWillExpire": "Ton compte expirera le {date}."
|
||||
},
|
||||
"emailConfirmation": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Nederlands (NL)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Als jij dit niet was, negeer dan alsjeblieft deze email.",
|
||||
"ifItWasNotYou": "Als jij dit niet was, negeer dit dan alsjeblieft.",
|
||||
"reason": "Reden",
|
||||
"helloUser": "Hoi {username},"
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
"welcome": "Welkom bij Jellyfin!",
|
||||
"youCanLoginWith": "Je kunt inloggen met onderstaande gegevens",
|
||||
"jellyfinURL": "URL",
|
||||
"name": "Welkomste-mail",
|
||||
"name": "Welkom",
|
||||
"yourAccountWillExpire": "Je account verloopt op {date}."
|
||||
},
|
||||
"emailConfirmation": {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"name": "Português (BR)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "Se não foi você, ignore este e-mail.",
|
||||
"ifItWasNotYou": "Se não foi você, ignore.",
|
||||
"reason": "Razão",
|
||||
"helloUser": "Ola {username},"
|
||||
},
|
||||
@@ -49,7 +49,7 @@
|
||||
"welcome": "Bem vindo ao Jellyfin!",
|
||||
"youCanLoginWith": "Abaixo está os detalhes para fazer o login",
|
||||
"jellyfinURL": "URL",
|
||||
"name": "Email de Boas vindas",
|
||||
"name": "Bem-vindo",
|
||||
"yourAccountWillExpire": "Sua conta irá expirar em {date}."
|
||||
},
|
||||
"emailConfirmation": {
|
||||
|
||||
77
lang/email/zh-hans.json
Normal file
@@ -0,0 +1,77 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"strings": {
|
||||
"ifItWasNotYou": "如果这不是您,请忽略本邮件。",
|
||||
"helloUser": "你好{username},",
|
||||
"reason": "原因"
|
||||
},
|
||||
"userCreated": {
|
||||
"name": "创建用户",
|
||||
"title": "注意:用户已创建",
|
||||
"aUserWasCreated": "使用代码{code}创建了一个用户。",
|
||||
"time": "时间",
|
||||
"notificationNotice": "注意:通知邮件可以在管理仪表板上进行切换。"
|
||||
},
|
||||
"inviteExpiry": {
|
||||
"name": "邀请到期",
|
||||
"title": "注意:邀请已过期",
|
||||
"inviteExpired": "邀请已过期。",
|
||||
"expiredAt": "代码 {code} 已于 {time} 过期。",
|
||||
"notificationNotice": "注意:通知邮件可以在管理仪表板上进行切换。"
|
||||
},
|
||||
"passwordReset": {
|
||||
"name": "重设密码",
|
||||
"title": "要求重设密码 - Jellyfin",
|
||||
"someoneHasRequestedReset": "最近在Jellyfin上有一个重设密码的请求。",
|
||||
"ifItWasYou": "如果这是您,请在提示中输入下面的PIN。",
|
||||
"ifItWasYouLink": "如果这是您,请单击下面的链接。",
|
||||
"codeExpiry": "该代码将在UTC时间{日期} {时间}到期,也就是{expires In Minutes}。",
|
||||
"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} 到期,即 {expires In Minutes},因此请迅速行动。",
|
||||
"linkButton": "设置您的帐户"
|
||||
},
|
||||
"welcomeEmail": {
|
||||
"name": "欢迎",
|
||||
"title": "欢迎使用Jellyfin",
|
||||
"welcome": "欢迎使用Jellyfin!",
|
||||
"youCanLoginWith": "您可以使用以下信息登录",
|
||||
"yourAccountWillExpire": "您的帐户将于 {date}到期。",
|
||||
"jellyfinURL": "链接"
|
||||
},
|
||||
"emailConfirmation": {
|
||||
"name": "确认邮件",
|
||||
"title": "确认您的电子邮件 - Jellyfin",
|
||||
"clickBelow": "单击下面的链接以确认您的电子邮件地址并开始使用 Jellyfin。",
|
||||
"confirmEmail": "确认电子邮件"
|
||||
},
|
||||
"userExpired": {
|
||||
"name": "用户到期",
|
||||
"title": "您的帐户已过期 - Jellyfin",
|
||||
"yourAccountHasExpired": "您的帐户已过期。",
|
||||
"contactTheAdmin": "请联系管理员了解更多信息。"
|
||||
}
|
||||
}
|
||||
57
lang/form/da-dk.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Opret Jellyfin Konto",
|
||||
"createAccountHeader": "Opret Konto",
|
||||
"accountDetails": "Detaljer",
|
||||
"emailAddress": "E-mail",
|
||||
"username": "Brugernavn",
|
||||
"password": "Adgangskode",
|
||||
"reEnterPassword": "Genindtast Adgangskode",
|
||||
"reEnterPasswordInvalid": "Adgangskoderne er ikke ens.",
|
||||
"createAccountButton": "Opret Konto",
|
||||
"passwordRequirementsHeader": "Adgangskodekrav",
|
||||
"successHeader": "Succes!",
|
||||
"successContinueButton": "Fortsæt",
|
||||
"confirmationRequired": "E-mail bekræftelse er påkrævet",
|
||||
"confirmationRequiredMessage": "Tjek venligst din e-mail indbakke for at verificere din adresse.",
|
||||
"yourAccountIsValidUntil": "Din konto er gyldig indtil {date}.",
|
||||
"sendPIN": "Send nedenstående pinkode til botten, og kom derefter tilbage her for at linke din konto.",
|
||||
"sendPINDiscord": "Skriv {command} i {server_channel} på Discord, og send PIN-koden nedenfor via. DM til boten.",
|
||||
"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": {
|
||||
"errorUserExists": "Brugeren eksistere allerede.",
|
||||
"errorInvalidCode": "Ugyldig invitations kode.",
|
||||
"errorTelegramVerification": "Telegram verifikation påkrævet.",
|
||||
"errorDiscordVerification": "Discord verifikation påkrævet.",
|
||||
"errorMatrixVerification": "Matrix verifikation påkrævet.",
|
||||
"errorInvalidPIN": "PIN-koden er ugyldig.",
|
||||
"errorUnknown": "Ukendt fejl.",
|
||||
"verified": "konto verificeret."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
"singular": "Skal mindst have {n} tegn",
|
||||
"plural": "Skal mindst have {n} tegn"
|
||||
},
|
||||
"uppercase": {
|
||||
"singular": "Skal mindst have {n} store bogstaver",
|
||||
"plural": "Skal mindst have {n} store bogstaver"
|
||||
},
|
||||
"lowercase": {
|
||||
"singular": "Skal mindst have {n} små bogstaver",
|
||||
"plural": "Skal mindst have {n} små bogstaver"
|
||||
},
|
||||
"number": {
|
||||
"singular": "Skal mindst have {n} tal",
|
||||
"plural": "Skal mindst have {n} tal"
|
||||
},
|
||||
"special": {
|
||||
"singular": "Skal mindst have {n} specialtegn",
|
||||
"plural": "Skal mindst have {n} specialtegn"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,7 +17,10 @@
|
||||
"successContinueButton": "Weiter",
|
||||
"confirmationRequired": "E-Mail-Bestätigung erforderlich",
|
||||
"confirmationRequiredMessage": "Bitte überprüfe dein Posteingang und bestätige deine E-Mail-Adresse.",
|
||||
"yourAccountIsValidUntil": "Dein Konto wird bis zum {date} gültig sein."
|
||||
"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.",
|
||||
"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": {
|
||||
"length": {
|
||||
@@ -43,6 +46,13 @@
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Benutzer existiert bereits.",
|
||||
"errorInvalidCode": "Ungültiger Invite-Code."
|
||||
"errorInvalidCode": "Ungültiger Invite-Code.",
|
||||
"telegramVerified": "Telegram-Konto verifiziert.",
|
||||
"errorTelegramVerification": "Verifizierung von Telegram erforderlich.",
|
||||
"errorInvalidPIN": "PIN ist ungültig.",
|
||||
"errorDiscordVerification": "Discord-Verifizierung erforderlich.",
|
||||
"errorMatrixVerification": "Matrix-Verifizierung erforderlich.",
|
||||
"errorUnknown": "Unbekannter Fehler.",
|
||||
"verified": "Konto verifiziert."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,14 +18,19 @@
|
||||
"confirmationRequired": "Email confirmation required",
|
||||
"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."
|
||||
"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 via DM to the bot.",
|
||||
"matrixEnterUser": "Enter your User ID, press submit, and a PIN will be sent to you. Enter it here to continue."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "User already exists.",
|
||||
"errorInvalidCode": "Invalid invite code.",
|
||||
"errorTelegramVerification": "Telegram verification required.",
|
||||
"errorInvalidPIN": "Telegram PIN is invalid.",
|
||||
"telegramVerified": "Telegram account verified."
|
||||
"errorDiscordVerification": "Discord verification required.",
|
||||
"errorMatrixVerification": "Matrix verification required.",
|
||||
"errorInvalidPIN": "PIN is invalid.",
|
||||
"errorUnknown": "Unknown error.",
|
||||
"verified": "Account verified."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
57
lang/form/fa-ir.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "انگلیسی"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "ساختن حساب کاربری",
|
||||
"createAccountHeader": "ساخت اکانت",
|
||||
"accountDetails": "جزئیات",
|
||||
"emailAddress": "پست الکترونیک",
|
||||
"username": "نام کاربری",
|
||||
"password": "کلمه عبور",
|
||||
"reEnterPassword": "کلمه عبور را دوباره وارد کنید",
|
||||
"reEnterPasswordInvalid": "کلمه های عبور یکسان نیستند.",
|
||||
"createAccountButton": "ساخت حساب کاربری",
|
||||
"passwordRequirementsHeader": "کلمه عبور لازم است",
|
||||
"successHeader": "موفقیت!",
|
||||
"successContinueButton": "ادامه دادن",
|
||||
"confirmationRequired": "تایید ایمیل لازم است",
|
||||
"confirmationRequiredMessage": "لطفاً برای تأیید آدرس خود ، صندوق پستی ایمیل خود را بررسی کنید.",
|
||||
"yourAccountIsValidUntil": "حساب شما تا {date} معتبر خواهد بود.",
|
||||
"sendPIN": "پین زیر را به ربات ارسال کنید ، سپس برای پیوند حساب خود به اینجا برگردید.",
|
||||
"sendPINDiscord": "در Discord {command} را در {server_channel} تایپ کنید ، سپس پین زیر را از طریق DM به ربات ارسال کنید.",
|
||||
"matrixEnterUser": "شناسه کاربری خود را وارد کرده ، submit را فشار دهید و یک پین برای شما ارسال می شود. برای ادامه آن را اینجا وارد کنید."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "کاربر قبلاً وجود دارد.",
|
||||
"errorInvalidCode": "کد دعوت نامعتبر است.",
|
||||
"errorTelegramVerification": "تایید تلگرام الزامی است.",
|
||||
"errorDiscordVerification": "تأیید دیسکورد مورد نیاز است.",
|
||||
"errorMatrixVerification": "تأیید ماتریکس مورد نیاز است.",
|
||||
"errorInvalidPIN": "پین نامعتبر است.",
|
||||
"errorUnknown": "خطای ناشناخته.",
|
||||
"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} نویسه خاص داشته باشد"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -14,10 +14,14 @@
|
||||
"reEnterPasswordInvalid": "Les mots de passe ne correspondent pas.",
|
||||
"createAccountButton": "Créer le compte",
|
||||
"passwordRequirementsHeader": "Mot de passe requis",
|
||||
"successHeader": "Succes!",
|
||||
"successHeader": "Succès !",
|
||||
"successContinueButton": "Continuer",
|
||||
"confirmationRequired": "Confirmation de l'adresse e-mail requise",
|
||||
"confirmationRequiredMessage": "Veuillez vérifier votre boite de réception pour confirmer votre adresse e-mail."
|
||||
"confirmationRequiredMessage": "Veuillez vérifier votre boite de réception pour confirmer votre adresse e-mail.",
|
||||
"yourAccountIsValidUntil": "Votre compte sera valide jusqu'au {date}.",
|
||||
"sendPIN": "Envoyez le code PIN ci-dessous au bot, puis revenez ici pour lier votre compte.",
|
||||
"sendPINDiscord": "Écrivez {command} dans le salon {server_channel} sur Discord puis envoyez le PIN en message privé au bot.",
|
||||
"matrixEnterUser": "Entrez votre nom d'utilisateur, appuyez sur soumettre et un code PIN vous sera envoyé. Cliquez ici pour continuez."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
@@ -43,6 +47,13 @@
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Utilisateur déjà existant.",
|
||||
"errorInvalidCode": "Code d’invitation non valide."
|
||||
"errorInvalidCode": "Code d’invitation non valide.",
|
||||
"errorTelegramVerification": "Vérification Telegram requise.",
|
||||
"errorInvalidPIN": "PIN Telegram invalide.",
|
||||
"telegramVerified": "Compte Telegram vérifié.",
|
||||
"errorDiscordVerification": "Vérification Discord requise.",
|
||||
"errorMatrixVerification": "Vérification Matrix requise.",
|
||||
"errorUnknown": "Erreur inconnue.",
|
||||
"verified": "Compte vérifié."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,10 @@
|
||||
"successContinueButton": "Doorgaan",
|
||||
"confirmationRequired": "Bevestiging van e-mailadres verplicht",
|
||||
"confirmationRequiredMessage": "Controleer je e-mail inbox om je adres te bevestigen.",
|
||||
"yourAccountIsValidUntil": "Je account zal geldig zijn tot {date}."
|
||||
"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."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
@@ -43,6 +46,13 @@
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Gebruiker bestaat al.",
|
||||
"errorInvalidCode": "Ongeldige uitnodigingscode."
|
||||
"errorInvalidCode": "Ongeldige uitnodigingscode.",
|
||||
"telegramVerified": "Telegram-account goedgekeurd.",
|
||||
"errorTelegramVerification": "Telegram-verificatie nodig.",
|
||||
"errorInvalidPIN": "Pincode is ongeldig.",
|
||||
"errorDiscordVerification": "Discord-verificatie vereist.",
|
||||
"errorUnknown": "Onbekende fout.",
|
||||
"errorMatrixVerification": "Matrix-verificatie vereist.",
|
||||
"verified": "Account geverifieerd."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,15 +13,25 @@
|
||||
"reEnterPasswordInvalid": "Senha não Coincidem. Tentar novamente.",
|
||||
"createAccountButton": "Criar Conta",
|
||||
"passwordRequirementsHeader": "Requisitos da Senha",
|
||||
"successHeader": "Sucesso!",
|
||||
"successHeader": "Concluído!",
|
||||
"successContinueButton": "Continuar",
|
||||
"confirmationRequired": "Necessária confirmação de e-mail",
|
||||
"confirmationRequired": "Confirmação por e-mail",
|
||||
"confirmationRequiredMessage": "Verifique sua caixa de email para finalizar o cadastro.",
|
||||
"yourAccountIsValidUntil": "Sua conta é válida até {date}."
|
||||
"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.",
|
||||
"matrixEnterUser": "Digite sua ID de usuário, pressione enviar e um PIN será enviado. E digite aqui para continuar."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Esse usuário já existe.",
|
||||
"errorInvalidCode": "Código do convite invalido."
|
||||
"errorInvalidCode": "Código do convite invalido.",
|
||||
"telegramVerified": "Conta do Telegram verificada.",
|
||||
"errorInvalidPIN": "PIN inválido.",
|
||||
"errorTelegramVerification": "Requer a verificação do telegram.",
|
||||
"errorDiscordVerification": "Necessária verificação pelo Discord.",
|
||||
"errorMatrixVerification": "Necessária verificação Matrix.",
|
||||
"errorUnknown": "Erro desconhecido.",
|
||||
"verified": "Conta verificada."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
@@ -17,11 +17,15 @@
|
||||
"successContinueButton": "Fortsätt",
|
||||
"confirmationRequired": "E-postbekräftelse krävs",
|
||||
"confirmationRequiredMessage": "Kontrollera din e-postkorg för att verifiera din adress.",
|
||||
"yourAccountIsValidUntil": "Ditt konto är giltigt fram tills {date}."
|
||||
"yourAccountIsValidUntil": "Ditt konto är giltigt fram tills {date}.",
|
||||
"sendPIN": "Skicka PIN-koden nedan till botten, återvänd sedan till den här sidan för att länka ditt konto."
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "Användare finns redan.",
|
||||
"errorInvalidCode": "Ogiltig inbjudningskod."
|
||||
"errorInvalidCode": "Ogiltig inbjudningskod.",
|
||||
"errorInvalidPIN": "Telegram-PIN är ogiltig.",
|
||||
"errorTelegramVerification": "Telegram-verifiering krävs.",
|
||||
"telegramVerified": "Telegram-konto verifierades."
|
||||
},
|
||||
"validationStrings": {
|
||||
"length": {
|
||||
|
||||
57
lang/form/zh-hans.json
Normal file
@@ -0,0 +1,57 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "创建Jellyfin账户",
|
||||
"createAccountHeader": "创建账户",
|
||||
"accountDetails": "账户详情",
|
||||
"emailAddress": "电子邮箱",
|
||||
"username": "用户名",
|
||||
"password": "密码",
|
||||
"reEnterPassword": "再次输入密码",
|
||||
"reEnterPasswordInvalid": "两次输入的密码不相同。",
|
||||
"createAccountButton": "创建账户",
|
||||
"passwordRequirementsHeader": "密码格式要求",
|
||||
"successHeader": "成功!",
|
||||
"successContinueButton": "继续",
|
||||
"confirmationRequired": "需要邮件确认",
|
||||
"confirmationRequiredMessage": "请登录您的邮箱收件箱来验证您的地址。",
|
||||
"yourAccountIsValidUntil": "您的账户将在 {date} 之前有效。",
|
||||
"sendPIN": "把PIN码发送给下面的bot,然后回到这里来关联您的账户。",
|
||||
"sendPINDiscord": "在 Discord 上,在 {server_channel} 中输入 {command} 并将下面的 PIN 码作为 DM 发送给机器人。",
|
||||
"matrixEnterUser": "输入您的用户ID并点击提交,将发送给您的PIN码输入到这里并继续。"
|
||||
},
|
||||
"notifications": {
|
||||
"errorUserExists": "用户已经存在。",
|
||||
"errorInvalidCode": "无效的邀请码",
|
||||
"errorTelegramVerification": "需要Telegram验证",
|
||||
"errorDiscordVerification": "需要Discord验证。",
|
||||
"errorMatrixVerification": "需要Matrix验证。",
|
||||
"errorInvalidPIN": "无效的PIN码",
|
||||
"errorUnknown": "未知错误。",
|
||||
"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
lang/pwreset/da-dk.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Nulstil adgangskode",
|
||||
"reset": "Nulstil",
|
||||
"resetFailed": "Nulstilling af adgangskode fejlede",
|
||||
"tryAgain": "Prøv venligst igen.",
|
||||
"youCanLogin": "Du kan nu logge ind med koden nedenfor som din adgangskode.",
|
||||
"youCanLoginOmbi": "Du kan nu logge ind på Jellyfin & Ombi med koden nedenfor som din adgangskode.",
|
||||
"changeYourPassword": "Sørg for at ændre din adgangskode, når du har logget ind.",
|
||||
"enterYourPassword": "Indtast din nye adgangskode nedenfor."
|
||||
}
|
||||
}
|
||||
13
lang/pwreset/de-de.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Deutsch (DE)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Passwort zurücksetzen",
|
||||
"resetFailed": "Zurücksetzen des Passworts fehlgeschlagen",
|
||||
"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."
|
||||
}
|
||||
}
|
||||
13
lang/pwreset/en-gb.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": ""
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "",
|
||||
"resetFailed": "",
|
||||
"tryAgain": "",
|
||||
"youCanLogin": "",
|
||||
"youCanLoginOmbi": "",
|
||||
"changeYourPassword": ""
|
||||
}
|
||||
}
|
||||
@@ -4,10 +4,12 @@
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Password reset",
|
||||
"reset": "Reset",
|
||||
"resetFailed": "Password reset failed",
|
||||
"tryAgain": "Please try again.",
|
||||
"youCanLogin": "You can now log in with the below code as your password.",
|
||||
"youCanLoginOmbi": "You can now log in to Jellyfin & Ombi with the below code as your password.",
|
||||
"changeYourPassword": "Make sure to change your password after you log in."
|
||||
"changeYourPassword": "Make sure to change your password after you log in.",
|
||||
"enterYourPassword": "Enter your new password below."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
"resetFailed": "Error al cambiar contraseña",
|
||||
"tryAgain": "Por favor intente nuevamente.",
|
||||
"youCanLogin": "Ahora puedes logearte con el codigo como contraseña.",
|
||||
"changeYourPassword": "Recuerda cambiar tu contraseña luego de iniciar sesión."
|
||||
"changeYourPassword": "Recuerda cambiar tu contraseña luego de iniciar sesión.",
|
||||
"youCanLoginOmbi": "Ahora puede iniciar sesión en Jellyfin & Ombi con el siguiente código como contraseña.",
|
||||
"reset": "Reiniciar"
|
||||
}
|
||||
}
|
||||
|
||||
15
lang/pwreset/fa-ir.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "انگلیسی"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "تنظیم مجدد رمز عبور",
|
||||
"reset": "بازنشانی",
|
||||
"resetFailed": "بازنشانی گذرواژه ناموفق بود",
|
||||
"tryAgain": "لطفا دوباره تلاش کنید.",
|
||||
"youCanLogin": "اکنون می توانید با کد زیر به عنوان رمز عبور خود وارد شوید.",
|
||||
"youCanLoginOmbi": "اکنون می توانید با کد زیر به عنوان رمز عبور وارد شوید.",
|
||||
"changeYourPassword": "اطمینان حاصل کنید که پس از ورود به سیستم رمز عبور خود را تغییر دهید.",
|
||||
"enterYourPassword": "رمز عبور جدید خود را در زیر وارد کنید."
|
||||
}
|
||||
}
|
||||
15
lang/pwreset/fr-fr.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Français (FR)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Réinitialisation du mot de passe",
|
||||
"reset": "Réinitialisation",
|
||||
"resetFailed": "Réinitialisation du mot de passe échouée",
|
||||
"tryAgain": "Veuillez réessayer.",
|
||||
"youCanLogin": "Vous pouvez maintenant vous connecter en utilisant ce code comme mot de passe.",
|
||||
"youCanLoginOmbi": "Vous pouvez maintenant vous connecter à Jellyfin et Ombi en utilisant ce mot de passe.",
|
||||
"changeYourPassword": "Assurez-vous de changer votre mot de passe après s'être connecté.",
|
||||
"enterYourPassword": "Entrez votre nouveau mot de passe ici."
|
||||
}
|
||||
}
|
||||
15
lang/pwreset/nl-nl.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Nederlands (NL)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Wachtwoordreset",
|
||||
"reset": "Reset",
|
||||
"resetFailed": "Wachtwoordreset mislukt",
|
||||
"tryAgain": "Probeer het alsjeblieft nog een keer.",
|
||||
"youCanLogin": "Je kunt nu inloggen met onderstaande code als wachtwoord.",
|
||||
"youCanLoginOmbi": "Je kunt nu inloggen bij Jellyfin & Ombi met onderstaande code als wachtwoord.",
|
||||
"changeYourPassword": "Denk eraan je wachtwoord te wijzigen nadat je bent ingelogd.",
|
||||
"enterYourPassword": "Voer hieronder je nieuwe wachtwoord in."
|
||||
}
|
||||
}
|
||||
13
lang/pwreset/pt-br.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Português (BR)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "Redefinir senha",
|
||||
"resetFailed": "Falha ao redefinir a senha",
|
||||
"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."
|
||||
}
|
||||
}
|
||||
15
lang/pwreset/zh-hans.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"strings": {
|
||||
"passwordReset": "重设密码",
|
||||
"reset": "重设",
|
||||
"resetFailed": "重设密码失败",
|
||||
"tryAgain": "请重试。",
|
||||
"youCanLogin": "您现在可以使用下面的代码作为您的密码进行登录。",
|
||||
"youCanLoginOmbi": "您现在可以使用下面的代码作为您的密码登录Jellyfin和Ombi。",
|
||||
"changeYourPassword": "确保在登录状态下修改您的密码。",
|
||||
"enterYourPassword": "在下面输入您的新密码。"
|
||||
}
|
||||
}
|
||||
147
lang/setup/da-dk.json
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "Opsæt - jfa-go",
|
||||
"next": "Næste",
|
||||
"back": "Tilbage",
|
||||
"optional": "Valgfri",
|
||||
"serverType": "Servertype",
|
||||
"disabled": "Deaktiveret",
|
||||
"enabled": "Aktiveret",
|
||||
"port": "Port",
|
||||
"message": "Meddelelse",
|
||||
"serverAddress": "Serveradresse",
|
||||
"emailSubject": "E-mail emne",
|
||||
"URL": "URL",
|
||||
"apiKey": "API Nøgle",
|
||||
"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."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Velkommen!",
|
||||
"pressStart": "Du bliver nødt til at gøre et par ting for at konfigurere jfa-go. Tryk på start for at fortsætte.",
|
||||
"httpsNotice": "Sørg for, at du tilgår denne side via HTTPS eller på et privat netværk.",
|
||||
"start": "Start"
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Færdig!",
|
||||
"restartMessage": "Du kan konfigurere Discord/Telegram/Matrix bots, tilpasse dine meddelelser og mere i Indstillinger. Klik herunder for at genstarte, og opdater siden.",
|
||||
"refreshPage": "Opdater"
|
||||
},
|
||||
"language": {
|
||||
"title": "Sprog",
|
||||
"description": "Fællesskabsoversættelser er tilgængelige for de fleste dele af jfa-go. Du kan vælge standardsprogene nedenfor, men brugere kan stadig ændre det, hvis de ønsker det. Hvis du vil hjælpe med at oversætte, skal du tilmelde dig til {n} for at begynde at bidrage!",
|
||||
"defaultAdminLang": "Standard administrator sprog",
|
||||
"defaultFormLang": "Standard kontooprettelses sprog",
|
||||
"defaultEmailLang": "Standard e-mail sprog"
|
||||
},
|
||||
"general": {
|
||||
"title": "Generel",
|
||||
"listenAddress": "Listen Adresse",
|
||||
"urlBase": "URL-base",
|
||||
"urlBaseNotice": "Kun nødvendigt hvis du bruger en omvendt proxy på et underdomæne (f.eks. 'Jellyf.in/accounts').",
|
||||
"lightTheme": "Lys",
|
||||
"darkTheme": "Mørk",
|
||||
"useHTTPS": "Brug HTTPS",
|
||||
"httpsPort": "HTTPS Port",
|
||||
"useHTTPSNotice": "Anbefales kun hvis du ikke bruger en omvendt proxy.",
|
||||
"pathToCertificate": "Sti til certifikat",
|
||||
"pathToKeyFile": "Sti til nøglefil"
|
||||
},
|
||||
"updates": {
|
||||
"title": "Opdateringer",
|
||||
"description": "Få besked når nye opdateringer er tilgængelige. jfa-go kontrollerer {n} hvert 30 minut. Ingen IP'er eller personlige identificerbare oplysninger indsamles.",
|
||||
"updateChannel": "Opdaterings Kanal",
|
||||
"stable": "Stabil",
|
||||
"unstable": "Ustabil"
|
||||
},
|
||||
"login": {
|
||||
"title": "Log på",
|
||||
"description": "For at få adgang til admin-siden skal du logge ind med nedenstående metode:",
|
||||
"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."
|
||||
},
|
||||
"jellyfinEmby": {
|
||||
"title": "Jellyfin/Emby",
|
||||
"description": "En administratorkonto er nødvendig fordi API'en ikke tillader oprettelse af brugere ved hjælp af en API-nøgle. Du skal oprette en separat konto og markere 'Tillad denne bruger at administrere serveren'. Du kan deaktivere alt andet. Når du er færdig, skal du indtaste loginoplysningerne her.",
|
||||
"embyNotice": "Emby support er begrænset og understøtter ikke nulstilling af adgangskode.",
|
||||
"internal": "Intern",
|
||||
"external": "Ekstern",
|
||||
"replaceJellyfin": "Server navn",
|
||||
"replaceJellyfinNotice": "Hvis angivet, vil dette erstatte enhver forekomst af 'Jellyfin' i appen.",
|
||||
"addressExternalNotice": "Lad det være tomt for at bruge den samme adresse.",
|
||||
"testConnection": "Test forbindelse"
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "Ved at oprette forbindelse til Ombi, oprettes både en Jellyfin og Ombi konto når en bruger tilmelder sig via jfa-go. Når installationen er afsluttet, skal du gå til Indstillinger for at indstille en standardprofil til nye Ombi brugere.",
|
||||
"apiKeyNotice": "Find dette i den første fane i Ombi indstillinger."
|
||||
},
|
||||
"email": {
|
||||
"title": "E-mail",
|
||||
"description": "jfa-go kan sende PIN-koder til nulstilling af adgangskoder og forskellige meddelelser via e-mail. Du kan oprette forbindelse til en SMTP-server eller bruge {n} API.",
|
||||
"method": "Afsendelsesmetode",
|
||||
"useEmailAsUsername": "Brug e-mail adresser som brugernavn",
|
||||
"useEmailAsUsernameNotice": "Hvis aktiveret, logger nye brugere på Jellyfin/Emby med deres e-mail adresse i stedet for et brugernavn.",
|
||||
"fromAddress": "Fra adresse",
|
||||
"senderName": "Afsender navn",
|
||||
"dateFormat": "Datoformat",
|
||||
"dateFormatNotice": "Dato følger strftime formatet. For flere oplysninger, besøg {n}.",
|
||||
"encryption": "Kryptering",
|
||||
"mailgunApiURL": "API-URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Admin Meddelelser",
|
||||
"description": "Hvis aktiveret, kan du vælge (pr. Invitation) at modtage besked når en invitation udløber, eller når en bruger oprettes. Hvis du ikke valgte Jellyfin login metoden, skal du sørge for at angive din e-mail adresse, eller tilføje en anden kontakt metode senere."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Velkomst beskeder",
|
||||
"description": "Hvis aktiveret, sendes en besked til nye brugere med Jellyfin/Emby URL'en og deres brugernavn."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Invitations Beskeder",
|
||||
"description": "Hvis aktiveret, kan du sende invitationer direkte til en brugers e-mail adresse, Discord eller Matrix bruger. Fordi du muligvis bruger en omvendt proxy, skal du angive en URL, invitationer tilgås fra. Skriv din URL-base, og tilføj '/invite'."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Nulstilling af Adgangskoder",
|
||||
"description": "Når en bruger forsøger at nulstille deres adgangskode, opretter Jellyfin en fil med navnet 'passwordreset - *. Json', som indeholder en PIN-kode. jfa-go læser filen og sender PIN-koden til brugeren.",
|
||||
"pathToJellyfin": "Sti til Jellyfin's konfigurations mappe",
|
||||
"pathToJellyfinNotice": "Hvis du ikke ved hvor dette er, kan du prøve at nulstille din adgangskode i Jellyfin. En popup med '<sti til jellyfin>/passwordreset - *. Json' vises.",
|
||||
"resetLinks": "Send et link i stedet for en PIN-kode",
|
||||
"resetLinksNotice": "Hvis Ombi integration er aktiveret, skal du bruge denne til at synkronisere nulstilling af Jellyfin's adgangskode med Ombi.",
|
||||
"resetLinksLanguage": "Standard sprog til nulstillings link",
|
||||
"setPassword": "Angiv adgangskode gennem link",
|
||||
"setPasswordNotice": "Aktivering af dette betyder at brugeren ikke behøver at ændre sin adgangskode væk fra pinkoden efter nulstillingen. Adgangskodevalidering håndhæves også."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Validering af adgangskode",
|
||||
"description": "Hvis aktiveret, vises et sæt adgangskrav på siden til oprettelse af konto, såsom minimumslængde, store/små bogstaver osv.",
|
||||
"length": "Længde",
|
||||
"uppercase": "Store bogstaver",
|
||||
"lowercase": "Små bogstaver",
|
||||
"numbers": "Tal",
|
||||
"special": "Specialtegn (%, * osv.)"
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "Hjælpe Meddelelser",
|
||||
"description": "Disse meddelelser vises på siden til oprettelse af konto og i nogle e-mails.",
|
||||
"contactMessage": "Kontakt Meddelelse",
|
||||
"contactMessageNotice": "Vises nederst på alle sider undtagen admin-siden.",
|
||||
"helpMessage": "Hjælpe Meddelelse",
|
||||
"helpMessageNotice": "Vises på siden til oprettelse af konto.",
|
||||
"successMessage": "Succes Meddelelse",
|
||||
"successMessageNotice": "Vises når en bruger opretter sin konto.",
|
||||
"emailMessage": "E-mail Meddelelse",
|
||||
"emailMessageNotice": "Vises i bunden af e-mails."
|
||||
},
|
||||
"messages": {
|
||||
"title": "Beskeder",
|
||||
"description": "jfa-go kan sende nulstilling af adgangskoder og forskellige meddelelser via E-mail, Discord, Telegram og/eller Matrix. Du kan konfigurere E-mail herunder, og de andre kan konfigureres i Indstillinger senere. Instruktioner kan findes på {n}. Hvis du ikke har brug for dette, kan du deaktivere disse funktioner her."
|
||||
}
|
||||
}
|
||||
@@ -101,7 +101,10 @@
|
||||
"title": "Passwortzurücksetzungen",
|
||||
"description": "Wenn ein Benutzer versucht sein Passwort zurückzusetzen, erstellt Jellyfin eine Datei namens 'passwordreset-*.json', welche eine PIN enthält. jfa-go liest die Datei und sendet die PIN an den Benutzer.",
|
||||
"pathToJellyfin": "Pfad zum Jellyfin-Konfigurationsverzeichnis",
|
||||
"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."
|
||||
"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"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Passwortüberprüfung",
|
||||
|
||||
@@ -15,7 +15,11 @@
|
||||
"serverAddress": "Server Address",
|
||||
"emailSubject": "Email Subject",
|
||||
"URL": "URL",
|
||||
"apiKey": "API Key"
|
||||
"apiKey": "API Key",
|
||||
"errorInvalidUserPass": "Invalid username/password.",
|
||||
"errorNotAdmin": "User is not allowed to manage server.",
|
||||
"errorUserDisabled": "User may be disabled.",
|
||||
"error404": "404, check the internal URL."
|
||||
},
|
||||
"startPage": {
|
||||
"welcome": "Welcome!",
|
||||
@@ -25,7 +29,7 @@
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Finished!",
|
||||
"restartMessage": "There are more settings you can configure on the admin page. Click below to restart, then refresh the page.",
|
||||
"restartMessage": "You can configure Discord/Telegram/Matrix bots, customize your messages and more in Settings. Click below to restart, then refresh the page.",
|
||||
"refreshPage": "Refresh"
|
||||
},
|
||||
"language": {
|
||||
@@ -79,6 +83,10 @@
|
||||
"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": {
|
||||
"title": "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."
|
||||
},
|
||||
"email": {
|
||||
"title": "Email",
|
||||
"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.",
|
||||
@@ -93,16 +101,16 @@
|
||||
"mailgunApiURL": "API URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notifications",
|
||||
"description": "If enabled, you can choose (per invite) to receive an email 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."
|
||||
"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."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Welcome emails",
|
||||
"description": "If enabled, an email will be sent to new users with the Jellyfin/Emby URL and their username."
|
||||
"title": "Welcome messages",
|
||||
"description": "If enabled, an message will be sent to new users with the Jellyfin/Emby URL and their username."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Invite Emails",
|
||||
"description": "If enabled, you can send invites directly to a user's email address. 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'."
|
||||
"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'."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Password Resets",
|
||||
@@ -111,7 +119,9 @@
|
||||
"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.",
|
||||
"resetLinks": "Send a link instead of a PIN",
|
||||
"resetLinksNotice": "If Ombi integration is enabled, use this to sync Jellyfin password resets with Ombi.",
|
||||
"resetLinksLanguage": "Default reset link language"
|
||||
"resetLinksLanguage": "Default reset link language",
|
||||
"setPassword": "Set password through link",
|
||||
"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."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Password Validation",
|
||||
|
||||
@@ -108,7 +108,10 @@
|
||||
"title": "Restablecimiento de contraseña",
|
||||
"description": "Cuando un usuario intenta restablecer su contraseña, Jellyfin crea un archivo llamado 'passwordreset - *. Json' que contiene un PIN. jfa-go lee el archivo y envía el PIN al usuario.",
|
||||
"pathToJellyfin": "Ruta al directorio de configuración de Jellyfin",
|
||||
"pathToJellyfinNotice": "Si no sabe dónde está, intente restablecer su contraseña en Jellyfin. Aparecerá una ventana emergente con '<ruta a jellyfin>/passwordreset-. Json'."
|
||||
"pathToJellyfinNotice": "Si no sabe dónde está, intente restablecer su contraseña en Jellyfin. Aparecerá una ventana emergente con '<ruta a jellyfin>/passwordreset-. Json'.",
|
||||
"resetLinks": "Envía un enlace en lugar de un PIN",
|
||||
"resetLinksNotice": "Si la integración de Ombi está habilitada, utilícela para sincronizar los restablecimientos de contraseña de Jellyfin con Ombi.",
|
||||
"resetLinksLanguage": "Enlace de restablecimiento predeterminado"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Validación de contraseña",
|
||||
|
||||
@@ -101,7 +101,10 @@
|
||||
"title": "Réinitialisation de mot de passe",
|
||||
"description": "Lorsqu'un utilisateur essaie de réinitialiser son mot de passe, Jellyfin créé un fichier nommé 'passwordreset-*.json' qui contient le code PIN. jfa-go lit le fichier et envoie le code PIN à l'utilisateur.",
|
||||
"pathToJellyfin": "Chemin du dossier de configuration de Jellyfin",
|
||||
"pathToJellyfinNotice": "Si vous ne savez pas où c'est, essayez de réinitialiser votre mot de passe dans Jellyfin. Une popup avec '<path to jellyfin>/passwordreset-*.json' apparaitra."
|
||||
"pathToJellyfinNotice": "Si vous ne savez pas où c'est, essayez de réinitialiser votre mot de passe dans Jellyfin. Une popup avec '<path to jellyfin>/passwordreset-*.json' apparaitra.",
|
||||
"resetLinks": "Envoyer un lien plutôt qu'un PIN",
|
||||
"resetLinksNotice": "Si l'intégration est activée, utilisez ceci pour synchroniser les réinitialisations de mots de passe Jellyfin avec Ombi.",
|
||||
"resetLinksLanguage": "Langue du lien de réinitialisation par défaut"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Validation du mot de passe",
|
||||
@@ -123,5 +126,12 @@
|
||||
"successMessageNotice": "S'affiche lorsqu'un utilisateur crée son compte.",
|
||||
"emailMessage": "Message de l'e-mail",
|
||||
"emailMessageNotice": "S'affiche au bas des e-mails."
|
||||
},
|
||||
"updates": {
|
||||
"title": "Mises à jour",
|
||||
"description": "Activez pour être averti lorsque de nouvelles mises à jour sont disponibles. jfa-go vérifiera {n} toutes les 30 minutes. Aucune adresse IP ou information personnellement identifiable n'est collectée.",
|
||||
"updateChannel": "Mettre à jour la chaîne",
|
||||
"stable": "Stable",
|
||||
"unstable": "Instable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Klaar!",
|
||||
"restartMessage": "Er staan meer instellingen op de beheerderspagina. Druk op de knop hieronder om opnieuw op te starten, en ververs daarna de pagina.",
|
||||
"restartMessage": "Je kunt Discord/Telegram/Matrix bots instellen, berichten aanpassen en meer bij Instellingen. Klik hieronder om te herstarten, en ververs de pagina.",
|
||||
"refreshPage": "Verversen"
|
||||
},
|
||||
"language": {
|
||||
@@ -69,12 +69,12 @@
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "Bij verbinding met Ombi, worden voor nieuwe gebruikers via jfa-go zowel een Jellyfin als een Ombi account aangemaakt. Ga nadat de setup voltooid is naar instellingen om een standaardprofiel voor nieuwe Ombi-gebruikers te kiezen.",
|
||||
"description": "Bij verbinding met Ombi, wordt voor nieuwe gebruikers via jfa-go zowel een Jellyfin als een Ombi account aangemaakt. Ga nadat de setup voltooid is naar instellingen om een standaardprofiel voor nieuwe Ombi-gebruikers te kiezen.",
|
||||
"apiKeyNotice": "Te vinden op het eerste tabblad van de Ombi-instellingen."
|
||||
},
|
||||
"email": {
|
||||
"title": "E-mail",
|
||||
"description": "jfa-go kan wachtwoord reset PINs en meldingen via e-mail versturen. Je kunt verbinding maken met een SMTP server, of de {n} API gebruiken.",
|
||||
"description": "jfa-go kan wachtwoord reset pincodes en meldingen via e-mail versturen. Je kunt verbinding maken met een SMTP server, of de {n} API gebruiken.",
|
||||
"method": "Verstuurmethode",
|
||||
"useEmailAsUsername": "Gebruik e-mailadres als gebruikersnaam",
|
||||
"useEmailAsUsernameNotice": "Indien ingeschakeld wordt voor nieuwe Jellyfin/Emby-gebruikers hun e-mailadres in plaats van gebruikersnaam gebruikt.",
|
||||
@@ -86,22 +86,27 @@
|
||||
"mailgunApiURL": "API-URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Meldingen",
|
||||
"description": "Indien ingeschakeld kun je er (per uitnodiging) voor kiezen om een e-mail te ontvangen wanneer een uitnodiging verloopt of er een gebruiker wordt aangemaakt. Als je niet inlogt via Jellyfin, controleer dan dat je je e-mailadres hebt ingevuld."
|
||||
"title": "Beheersmeldingen",
|
||||
"description": "Indien ingeschakeld kun je er (per uitnodiging) voor kiezen om een bericht te ontvangen wanneer een uitnodiging verloopt of er een gebruiker wordt aangemaakt. Als je niet inlogt via Jellyfin, controleer dan dat je je e-mailadres hebt ingevuld, of voeg later een andere contactmethode toe."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Welkomste-mails",
|
||||
"description": "Indien ingeschakeld wordt er een e-mail gestuurd aan nieuwe gebruikers met de Jellyfin/Emby-URL en hun gebruikersnaam."
|
||||
"title": "Welkomstberichten",
|
||||
"description": "Indien ingeschakeld wordt er een bericht gestuurd aan nieuwe gebruikers met de Jellyfin/Emby-URL en hun gebruikersnaam."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Uitnodigingse-mails",
|
||||
"description": "Indien ingeschakeld kun je uitnodigingen direct naar het e-mailadres van gebruikers sturen. Omdat je misschien een reverse proxy gebruikt moet je het URL opgeven waarlangs uitnodigingen geopend worden. Geef de URL-basis op, gevolgd door '/invite'."
|
||||
"title": "Uitnodigingsbericht",
|
||||
"description": "Indien ingeschakeld kun je uitnodigingen direct naar het e-mailadres, Discord- of Matrix-account van gebruikers sturen. Omdat je misschien een reverse proxy gebruikt moet je het URL opgeven waarlangs uitnodigingen geopend worden. Geef de URL-basis op, gevolgd door '/invite'."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Wachtwoordresets",
|
||||
"description": "Wanneer een gebruiker een wachtwoordreset aanvraagt, maakt Jellyfin een bestand aan dat 'passwordreset-*.json' heet en een PIN bevat. jfa-go leest dit bestand uit en stuurt de PIN naar de gebruiker.",
|
||||
"description": "Wanneer een gebruiker een wachtwoordreset aanvraagt, maakt Jellyfin een bestand aan dat 'passwordreset-*.json' heet en een pincode bevat. jfa-go leest dit bestand uit en stuurt de pincode naar de gebruiker.",
|
||||
"pathToJellyfin": "Pad naar Jellyfin configuratiemap",
|
||||
"pathToJellyfinNotice": "Als je niet weet waar dit is, probeer de je wachtwoord te resetten in Jellyfin. Er verschijnt dan een popup met '<path to jellyfin>/passwordreset-*.json'."
|
||||
"pathToJellyfinNotice": "Als je niet weet waar dit is, probeer de je wachtwoord te resetten in Jellyfin. Er verschijnt dan een popup met '<path to jellyfin>/passwordreset-*.json'.",
|
||||
"resetLinks": "Stuur een link in plaats van een pincode",
|
||||
"resetLinksNotice": "Als Ombi-integratie is ingeschakeld, gebruik dan dit om Jellyfin wachtwoordresets te synchroniseren met Ombi.",
|
||||
"resetLinksLanguage": "Standaard reset-link taal",
|
||||
"setPassword": "Stel wachtwoord in via link",
|
||||
"setPasswordNotice": "Als dit aanstaat hoeft de gebruiker het wachtwoord niet te wijzigen van de PINcode na de reset. Wachtwoordvalidatie wordt ook afgedwongen."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Wachtwoordvalidatie",
|
||||
@@ -130,5 +135,9 @@
|
||||
"stable": "Stabiel",
|
||||
"title": "Updates",
|
||||
"description": "Vink aan om een melding te krijgen wanneer nieuwe updates beschikbaar zijn. jfa-go controleert {n} elke 30 minuten. Er worden geen IPs of persoonsgegevens verzameld."
|
||||
},
|
||||
"messages": {
|
||||
"title": "Berichten",
|
||||
"description": "jfa-go kan wachtwoordresets en verschillende berichten sturen via E-mail, Discord, Telegram, en/of Matrix. Je kunt e-mail hieronder instellen, en de rest kan later bij Instellingen aangepast worden. Instructies staan op de {n}. Als je dit niet nodig hebt, kun je deze onderdelen hier uitschakelen."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"endPage": {
|
||||
"finished": "Finalizado!",
|
||||
"restartMessage": "Existem mais opções que você pode definir na página do administrador. Clique abaixo para reiniciar e atualize a página.",
|
||||
"restartMessage": "Você pode configurar os bots Discord/Telegram/Matrix, personalizar suas mensagens e muito mais em Configurações. Clique abaixo para reiniciar e, em seguida, atualize a página.",
|
||||
"refreshPage": "Atualizar"
|
||||
},
|
||||
"language": {
|
||||
@@ -86,22 +86,27 @@
|
||||
"mailgunApiURL": "API URL"
|
||||
},
|
||||
"notifications": {
|
||||
"title": "Notificações",
|
||||
"description": "Se ativado, você pode escolher (por convite) receber um email quando um convite expirar ou um usuário for criado. Se você não escolheu o método de login Jellyfin, certifique-se de fornecer seu endereço de e-mail."
|
||||
"title": "Notificações do Administrador",
|
||||
"description": "Se ativado, você pode escolher (por convite) receber uma mensagem quando um convite expirar ou um usuário for criado. Se você não escolheu o método de login Jellyfin, certifique-se de fornecer seu endereço de e-mail ou adicione outro método de contato posteriormente."
|
||||
},
|
||||
"welcomeEmails": {
|
||||
"title": "Email de boas-vindas",
|
||||
"description": "Se habilitado, um email será enviado para os novos usuários Jellyfin/Emby."
|
||||
"title": "Mensagens de boas vindas",
|
||||
"description": "Se habilitado, uma mensagem será enviada para novos usuários com a URL Jellyfin/Emby e seu nome de usuário."
|
||||
},
|
||||
"inviteEmails": {
|
||||
"title": "Convidar por Emails",
|
||||
"description": "Se ativado, você pode enviar convites diretamente para o endereço de email do usuário. Como você pode estar usando um proxy reverso, é necessário fornecer a URL de onde os convites são acessados. Escreva a sua URL Base e acrescente '/invite'."
|
||||
"title": "Convite por Mensagens",
|
||||
"description": "Se ativado, você pode enviar convites diretamente para o endereço de e-mail do usuário, Discord ou Matrix. Como você pode estar usando um proxy reverso, é necessário fornecer a URL de onde os convites são acessados. Escreva a sua base de URL e acrescente '/ invite'."
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "Redefinir Senha",
|
||||
"description": "Quando um usuário tenta redefinir sua senha, o Jellyfin cria um arquivo chamado 'passwordreset-*.json' que contém um PIN. jfa-go lê o arquivo e envia o PIN ao usuário.",
|
||||
"pathToJellyfin": "Local do diretório de configuração do Jellyfin",
|
||||
"pathToJellyfinNotice": "Se você não sabe o local onde fica, tente redefinir sua senha no Jellyfin. Um pop-up com '<path to jellyfin>/passwordreset-*.json' aparecerá."
|
||||
"pathToJellyfinNotice": "Se você não sabe o local onde fica, tente redefinir sua senha no Jellyfin. Um pop-up com '<path to jellyfin>/passwordreset-*.json' aparecerá.",
|
||||
"resetLinks": "Envie um link em vez de um PIN",
|
||||
"resetLinksNotice": "Se a integração do Ombi estiver habilitada, use para sincronizar as redefinições de senha do Jellyfin com o Ombi.",
|
||||
"resetLinksLanguage": "Idioma do link de redefinição padrão",
|
||||
"setPassword": "Definir a senha por meio de link",
|
||||
"setPasswordNotice": "Se habilitar significa que o usuário não precisa alterar a senha do PIN após a redefinição. A validação de senha também será aplicada."
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Validar Senha",
|
||||
@@ -130,5 +135,9 @@
|
||||
"updateChannel": "Canal de Atualização",
|
||||
"stable": "Estável",
|
||||
"unstable": "Instável"
|
||||
},
|
||||
"messages": {
|
||||
"title": "Mensagens",
|
||||
"description": "jfa-go pode enviar redefinições de senha e várias mensagens por e-mail, Discord, Telegram e/ou Matrix. Você pode configurar o e-mail abaixo e os outros podem ser configurados em Configurações posteriormente. As instruções podem ser encontradas em {n}. Se você não precisar, pode desativar esses recursos aqui."
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
},
|
||||
"ombi": {
|
||||
"title": "Ombi",
|
||||
"description": "Genom att ansluta till Ombi skapas både ett Jellyfin- och Ombi-konto när en användare går med genom jfa-go. Efter installationen, om du är klar, gå till Inställningar för att ställa in en standardprofil för nya ombi-användare.",
|
||||
"description": "Genom att ansluta till Ombi skapas både ett Jellyfin- och Ombi-konto när en användare går med genom jfa-go. Efter installationen är klar, gå till Inställningar för att ställa in en standardprofil för nya ombi-användare.",
|
||||
"apiKeyNotice": "Hitta detta i den första fliken i Ombi-inställningarna."
|
||||
},
|
||||
"email": {
|
||||
@@ -101,7 +101,10 @@
|
||||
"title": "Lösenordsåterställningar",
|
||||
"description": "När en användare försöker återställa sitt lösenord skapar Jellyfin en fil med namnet 'passwordreset-*.json' som innehåller en PIN-kod. jfa-go läser filen och skickar PIN-koden till användaren.",
|
||||
"pathToJellyfin": "Sökväg till Jellyfin-konfigurationskatalogen",
|
||||
"pathToJellyfinNotice": "Om du inte vet var det är, försök återställa lösenordet i Jellyfin. En popup med '<sökväg till jellyfin>/passwordreset-*.json' kommer då visas."
|
||||
"pathToJellyfinNotice": "Om du inte vet var det är, försök återställa lösenordet i Jellyfin. En popup med '<sökväg till jellyfin>/passwordreset-*.json' kommer då visas.",
|
||||
"resetLinks": "Skicka en länk istället för en PIN",
|
||||
"resetLinksNotice": "Om Ombi-integrationen är aktiverad, använd den för att synkronisera lösenordsåterställningar med Ombi.",
|
||||
"resetLinksLanguage": "Förvalt språk för återställningslänk"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "Validering av lösenord",
|
||||
@@ -123,5 +126,12 @@
|
||||
"successMessageNotice": "Visas när en användare skapar sitt konto.",
|
||||
"emailMessage": "E-postmeddelande",
|
||||
"emailMessageNotice": "Visas längst ner i e-postmeddelanden."
|
||||
},
|
||||
"updates": {
|
||||
"title": "Uppdateringar",
|
||||
"updateChannel": "Uppdateringskanal",
|
||||
"description": "Aktivera för att få notifikation när nya uppdateringar finns tillgängliga. jfa-go kollar {n} var 30:e minut. Inga IP-adresser eller personligt identifierande handlingar samlas in.",
|
||||
"stable": "Stabil",
|
||||
"unstable": "Ostabil"
|
||||
}
|
||||
}
|
||||
|
||||
147
lang/setup/zh-hans.json
Normal file
@@ -0,0 +1,147 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "简体中文(CN)"
|
||||
},
|
||||
"strings": {
|
||||
"pageTitle": "设置 - jfa-go",
|
||||
"next": "下一步",
|
||||
"back": "上一步",
|
||||
"optional": "可选的",
|
||||
"serverType": "服务类型",
|
||||
"disabled": "已禁用",
|
||||
"enabled": "已启用",
|
||||
"port": "端口",
|
||||
"message": "信息",
|
||||
"serverAddress": "服务地址",
|
||||
"emailSubject": "邮件主题",
|
||||
"URL": "链接",
|
||||
"apiKey": "API Key",
|
||||
"errorInvalidUserPass": "无效的用户名/密码。",
|
||||
"errorNotAdmin": "此用户不允许管理服务。",
|
||||
"errorUserDisabled": "此永固可能已被禁用。",
|
||||
"error404": "404,请检查内部URL。"
|
||||
},
|
||||
"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 Base",
|
||||
"urlBaseNotice": "仅在子域上使用反向代理时才需要(例如“jellyf.in/accounts”)。",
|
||||
"lightTheme": "明亮",
|
||||
"darkTheme": "暗黑",
|
||||
"useHTTPS": "使用HTTPS",
|
||||
"httpsPort": "HTTPS端口",
|
||||
"useHTTPSNotice": "仅在不使用反向代理时推荐使用。",
|
||||
"pathToCertificate": "证书文件路径",
|
||||
"pathToKeyFile": "密钥文件路径"
|
||||
},
|
||||
"updates": {
|
||||
"title": "更新",
|
||||
"description": "fa-go将每隔30分钟检查一次{n},以便在有新更新时得到通知。不会收集IP或个人身份信息。",
|
||||
"updateChannel": "更新通道",
|
||||
"stable": "稳定版",
|
||||
"unstable": "非稳定版"
|
||||
},
|
||||
"login": {
|
||||
"title": "登录",
|
||||
"description": "要访问管理页面,您需要使用以下方法登录:",
|
||||
"authorizeWithJellyfin": "从Jellyfin/Emby 授权:登录信息与 Jellyfin 同步,允许使用多个用户。",
|
||||
"authorizeManual": "用户名和密码:手动设置用户名和密码。",
|
||||
"adminOnly": "仅允许管理员账户(推荐)",
|
||||
"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 Base,并附加“/invite”。"
|
||||
},
|
||||
"passwordResets": {
|
||||
"title": "重置密码",
|
||||
"description": "当用户尝试重置密码时,Jellyfin 会创建一个名为“passwordreset-*.json”的文件,其中包含一个 PIN码。jfa-go 会读取该文件并将 PIN 码发送给用户。",
|
||||
"pathToJellyfin": "Jellyfin 配置目录的路径",
|
||||
"pathToJellyfinNotice": "如果您找不到它在哪,请尝试在 Jellyfin 中重置您的密码。将出现一个带有 '<path to jellyfin>/passwordreset-*.json' 的弹出窗口。",
|
||||
"resetLinks": "发送链接而不是PIN码",
|
||||
"resetLinksNotice": "如果启用了 Ombi 集成,请使用它与 Ombi 同步 Jellyfin 密码重置。",
|
||||
"resetLinksLanguage": "默认重置链接语言",
|
||||
"setPassword": "通过链接设置密码",
|
||||
"setPasswordNotice": "启用此功能意味着用户无需在重置后通过 PIN 更改其密码。并将强制执行密码验证。"
|
||||
},
|
||||
"passwordValidation": {
|
||||
"title": "密码验证",
|
||||
"description": "如果启用,则在创建帐户页面上会显示一组密码要求,例如最小长度、大写/小写字符等。",
|
||||
"length": "长度",
|
||||
"uppercase": "大写字母",
|
||||
"lowercase": "小写字母",
|
||||
"numbers": "数字",
|
||||
"special": "特殊字符 (%, *, etc.)"
|
||||
},
|
||||
"helpMessages": {
|
||||
"title": "帮助信息",
|
||||
"description": "这些消息将显示在帐户创建页面和某些电子邮件中。",
|
||||
"contactMessage": "联系方式",
|
||||
"contactMessageNotice": "显示在除 admin 之外的所有页面的底部。",
|
||||
"helpMessage": "帮助信息",
|
||||
"helpMessageNotice": "显示在帐户创建页面上。",
|
||||
"successMessage": "成功信息",
|
||||
"successMessageNotice": "在用户创建账户时显示。",
|
||||
"emailMessage": "电子邮件",
|
||||
"emailMessageNotice": "显示在电子邮件的底部。"
|
||||
}
|
||||
}
|
||||
12
lang/telegram/da-dk.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "Dansk"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "Hej!\nIndtast din Jellyfin PIN-kode her for at verificere din konto.",
|
||||
"matrixStartMessage": "Hej!\nIndtast PIN-koden under ind i Jellyfin tilmeldingssiden for at verificere din konto.",
|
||||
"invalidPIN": "Den PIN-kode var ugyldig, prøv igen.",
|
||||
"pinSuccess": "Sådan! Du kan nu gå tilbage til tilmeldingssiden.",
|
||||
"languageMessage": "Meddelelse: Se tilgængelige sprog med {command}, og vælg sprog med {command} <sprog kode>."
|
||||
}
|
||||
}
|
||||
12
lang/telegram/de-de.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"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.",
|
||||
"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."
|
||||
}
|
||||
}
|
||||
@@ -4,8 +4,9 @@
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "Hi!\nEnter your Jellyfin PIN code here to verify your account.",
|
||||
"matrixStartMessage": "Hi\nEnter the below PIN in the Jellyfin sign-up page to verify your account.",
|
||||
"invalidPIN": "That PIN was invalid, try again.",
|
||||
"pinSuccess": "Success! You can now return to the sign-up page.",
|
||||
"languageMessage": "Note: See available languages with /lang, and set language with /lang <language code>."
|
||||
"languageMessage": "Note: See available languages with {command}, and set language with {command} <language code>."
|
||||
}
|
||||
}
|
||||
|
||||
12
lang/telegram/es-es.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": ""
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "¡Hola!\nIntroduce tu código PIN de Jellyfin para verificar tu cuenta.",
|
||||
"matrixStartMessage": "Hola,\nIntroduce el PIN de abajo para logarte en la página de Jellyfin y verificar tu cuenta.",
|
||||
"invalidPIN": "El PIN es inváido, inténtalo de nuevo.",
|
||||
"pinSuccess": "Ok! Ya puedes volver a la página de login.",
|
||||
"languageMessage": "Nota: Ver los idiomas disponibles con {command}, y ajusta el idioma con {command} <language code>."
|
||||
}
|
||||
}
|
||||
12
lang/telegram/fa-ir.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"meta": {
|
||||
"name": "انگلیسی"
|
||||
},
|
||||
"strings": {
|
||||
"startMessage": "سلام!\nبرای تأیید حساب خود ، کد PIN خود را در اینجا وارد کنید.",
|
||||
"matrixStartMessage": "سلام\nبرای تأیید حساب خود ، پین زیر را در صفحه ثبت نام وارد کنید.",
|
||||
"invalidPIN": "آن پین نامعتبر بود ، دوباره امتحان کنید.",
|
||||
"pinSuccess": "موفقیت! اکنون می توانید به صفحه ثبت نام بازگردید.",
|
||||
"languageMessage": "توجه: زبانهای موجود با {command} را مشاهده کرده و زبان را با {command} <code code> تنظیم کنید."
|
||||
}
|
||||
}
|
||||