mirror of
https://github.com/filebrowser/filebrowser.git
synced 2026-01-23 10:45:24 +00:00
Compare commits
120 commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08c8ede587 | ||
|
|
1154b49974 | ||
|
|
785b7abb7b | ||
|
|
550a73b6ba | ||
|
|
e7ea1ad27d | ||
|
|
24781badd4 | ||
|
|
4094fb359b | ||
|
|
cfa6c5864e | ||
|
|
59ca0c340a | ||
|
|
037e29a708 | ||
|
|
fda8a99292 | ||
|
|
208535a8cc | ||
|
|
464b581953 | ||
|
|
20312ff18e | ||
|
|
219582c0b0 | ||
|
|
4fd18a382c | ||
|
|
94ec786d34 | ||
|
|
25e9b85259 | ||
|
|
ffa893e9ac | ||
|
|
b8151a038a | ||
|
|
943e5340d0 | ||
|
|
88aa56f53b | ||
|
|
a12a612970 | ||
|
|
a2d80c62c1 | ||
|
|
1faa21844f | ||
|
|
7a93b2a062 | ||
|
|
032d6c7520 | ||
|
|
9595f3939c | ||
|
|
60b1ee8bb9 | ||
|
|
79d1aa9229 | ||
|
|
20bfd131c6 | ||
|
|
f89975603e | ||
|
|
2d3b64ecf6 | ||
|
|
579756dbb5 | ||
|
|
c11c986b73 | ||
|
|
3fdca6dfd9 | ||
|
|
cf966578d8 | ||
|
|
6d4c867672 | ||
|
|
169e97e6f9 | ||
|
|
7fa3432f25 | ||
|
|
e9ce7fa5aa | ||
|
|
849f5ad443 | ||
|
|
c1715992bd | ||
|
|
e4f2503298 | ||
|
|
152f8302f7 | ||
|
|
4cbb4b73af | ||
|
|
58cc874828 | ||
|
|
124def5cd7 | ||
|
|
2d88c06761 | ||
|
|
204a3f0eea | ||
|
|
f029c3005e | ||
|
|
a6934e40ff | ||
|
|
98662ac5ec | ||
|
|
5cf8ce8db5 | ||
|
|
062dc414f8 | ||
|
|
63582b644c | ||
|
|
4302ece49b | ||
|
|
e1ee14d827 | ||
|
|
84ca722261 | ||
|
|
b9ac45d5da | ||
|
|
701522a060 | ||
|
|
78e0395960 | ||
|
|
f0680cf0f5 | ||
|
|
982405ec94 | ||
|
|
a78aaed214 | ||
|
|
df11a7dd0e | ||
|
|
79980bcf52 | ||
|
|
3be134f23d | ||
|
|
279a5ccd1e | ||
|
|
87f73ac982 | ||
|
|
85cde140ba | ||
|
|
119609c834 | ||
|
|
d48f5665d6 | ||
|
|
54306bdc87 | ||
|
|
33deedf559 | ||
|
|
88d1eecc4e | ||
|
|
43db19f8c8 | ||
|
|
a360f26979 | ||
|
|
ab367a2740 | ||
|
|
5df5508a85 | ||
|
|
6d5aa355e4 | ||
|
|
a3b5584505 | ||
|
|
8db2411cd4 | ||
|
|
c284de9d2c | ||
|
|
984ea7b569 | ||
|
|
fd7b70cf38 | ||
|
|
13e3b46718 | ||
|
|
d759ab0bd8 | ||
|
|
00323a8f37 | ||
|
|
420adea7e6 | ||
|
|
f576d38a7e | ||
|
|
9bdc67c207 | ||
|
|
f41585f039 | ||
|
|
89be0b1873 | ||
|
|
8c5dc7641e | ||
|
|
0a0cb8046f | ||
|
|
f89435c068 | ||
|
|
fb8d41eb9a | ||
|
|
0fadaccaa2 | ||
|
|
e24e1f1aba | ||
|
|
5de4099cba | ||
|
|
d01493106d | ||
|
|
2d9689dd6a | ||
|
|
c4c1cea230 | ||
|
|
ceb5e723f3 | ||
|
|
ebc7d2303d | ||
|
|
23c4e4565b | ||
|
|
17f1e08a58 | ||
|
|
ffc850454e | ||
|
|
13814e1119 | ||
|
|
4e9e312984 | ||
|
|
ce3b407c51 | ||
|
|
fb5d099f85 | ||
|
|
1ace579a55 | ||
|
|
ac7b49c148 | ||
|
|
9d44932dba | ||
|
|
0d973d3aad | ||
|
|
cacc0999e9 | ||
|
|
42d1b6f3ae | ||
|
|
bb10c3dfa9 |
192 changed files with 6311 additions and 2664 deletions
12
.github/workflows/ci.yaml
vendored
12
.github/workflows/ci.yaml
vendored
|
|
@ -13,7 +13,7 @@ jobs:
|
||||||
name: Lint Frontend
|
name: Lint Frontend
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
- uses: pnpm/action-setup@v4
|
- uses: pnpm/action-setup@v4
|
||||||
with:
|
with:
|
||||||
package_json_file: "frontend/package.json"
|
package_json_file: "frontend/package.json"
|
||||||
|
|
@ -31,7 +31,7 @@ jobs:
|
||||||
name: Lint Backend
|
name: Lint Backend
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-go@v6
|
- uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: "1.25.x"
|
go-version: "1.25.x"
|
||||||
|
|
@ -43,7 +43,7 @@ jobs:
|
||||||
name: Test
|
name: Test
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
- uses: actions/setup-go@v6
|
- uses: actions/setup-go@v6
|
||||||
with:
|
with:
|
||||||
go-version: "1.25.x"
|
go-version: "1.25.x"
|
||||||
|
|
@ -53,7 +53,7 @@ jobs:
|
||||||
name: Build
|
name: Build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-go@v6
|
- uses: actions/setup-go@v6
|
||||||
|
|
@ -77,7 +77,7 @@ jobs:
|
||||||
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v')
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v5
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
- uses: actions/setup-go@v6
|
- uses: actions/setup-go@v6
|
||||||
|
|
@ -97,7 +97,7 @@ jobs:
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
uses: go-task/setup-task@v1
|
uses: go-task/setup-task@v1
|
||||||
- run: task build-frontend
|
- run: task build:frontend
|
||||||
- name: Login to Docker Hub
|
- name: Login to Docker Hub
|
||||||
uses: docker/login-action@v3
|
uses: docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
|
|
|
||||||
24
.github/workflows/docs.yml
vendored
24
.github/workflows/docs.yml
vendored
|
|
@ -16,7 +16,7 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
|
|
@ -28,25 +28,25 @@ jobs:
|
||||||
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
|
||||||
name: Build and Release Docs
|
name: Build and Release Docs
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
pages: write
|
||||||
deployments: write
|
id-token: write
|
||||||
pull-requests: write
|
environment:
|
||||||
|
name: github-pages
|
||||||
|
url: ${{ steps.deployment.outputs.page_url }}
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 5
|
timeout-minutes: 5
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v5
|
uses: actions/checkout@v6
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
uses: docker/setup-buildx-action@v3
|
||||||
- name: Install Task
|
- name: Install Task
|
||||||
uses: go-task/setup-task@v1
|
uses: go-task/setup-task@v1
|
||||||
- name: Build site
|
- name: Build site
|
||||||
run: task docs
|
run: task docs
|
||||||
- name: Deploy to Cloudflare Pages
|
- name: Upload static files as artifact
|
||||||
uses: cloudflare/wrangler-action@v3
|
uses: actions/upload-pages-artifact@v4
|
||||||
with:
|
with:
|
||||||
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
|
path: www/public
|
||||||
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
|
- name: Deploy to GitHub Pages
|
||||||
command: pages deploy www/public --project-name=${{ secrets.CLOUDFLARE_PROJECT_NAME }}
|
uses: actions/deploy-pages@v4
|
||||||
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
|
|
||||||
|
|
|
||||||
122
.golangci.yml
122
.golangci.yml
|
|
@ -1,132 +1,14 @@
|
||||||
version: "2"
|
version: "2"
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
# inverted configuration with `default: all` and `disable` is not scalable during updates of golangci-lint
|
default: standard
|
||||||
default: none
|
|
||||||
enable:
|
enable:
|
||||||
- bodyclose
|
|
||||||
- dogsled
|
|
||||||
- dupl
|
|
||||||
- errcheck
|
|
||||||
- errorlint
|
|
||||||
- exhaustive
|
|
||||||
- funlen
|
|
||||||
- gocheckcompilerdirectives
|
|
||||||
- gochecknoinits
|
|
||||||
- gocritic
|
- gocritic
|
||||||
- gocyclo
|
|
||||||
- godox
|
|
||||||
- goprintffuncname
|
|
||||||
- gosec
|
|
||||||
- govet
|
- govet
|
||||||
- ineffassign
|
|
||||||
- lll
|
|
||||||
- misspell
|
|
||||||
- mnd
|
|
||||||
- nakedret
|
|
||||||
- nolintlint
|
|
||||||
- prealloc
|
|
||||||
- revive
|
- revive
|
||||||
- rowserrcheck
|
|
||||||
- staticcheck
|
|
||||||
- testifylint
|
|
||||||
- unconvert
|
|
||||||
- unparam
|
|
||||||
- unused
|
|
||||||
- whitespace
|
|
||||||
settings:
|
|
||||||
dupl:
|
|
||||||
threshold: 100
|
|
||||||
exhaustive:
|
|
||||||
default-signifies-exhaustive: false
|
|
||||||
funlen:
|
|
||||||
lines: 100
|
|
||||||
statements: 50
|
|
||||||
gocritic:
|
|
||||||
disabled-checks:
|
|
||||||
- dupImport # https://github.com/go-critic/go-critic/issues/845
|
|
||||||
- ifElseChain
|
|
||||||
- octalLiteral
|
|
||||||
- whyNoLint
|
|
||||||
- wrapperFunc
|
|
||||||
enabled-tags:
|
|
||||||
- diagnostic
|
|
||||||
- experimental
|
|
||||||
- opinionated
|
|
||||||
- performance
|
|
||||||
- style
|
|
||||||
gocyclo:
|
|
||||||
min-complexity: 15
|
|
||||||
govet:
|
|
||||||
enable:
|
|
||||||
- nilness
|
|
||||||
- shadow
|
|
||||||
lll:
|
|
||||||
line-length: 140
|
|
||||||
misspell:
|
|
||||||
locale: US
|
|
||||||
mnd:
|
|
||||||
# don't include the "operation" and "assign"
|
|
||||||
checks:
|
|
||||||
- argument
|
|
||||||
- case
|
|
||||||
- condition
|
|
||||||
- return
|
|
||||||
ignored-numbers:
|
|
||||||
- "0"
|
|
||||||
- "1"
|
|
||||||
- "2"
|
|
||||||
- "3"
|
|
||||||
- "0666"
|
|
||||||
- "0700"
|
|
||||||
- "0700"
|
|
||||||
ignored-functions:
|
|
||||||
- strings.SplitN
|
|
||||||
- make
|
|
||||||
nolintlint:
|
|
||||||
allow-unused: false # report any unused nolint directives
|
|
||||||
require-explanation: false # require an explanation for nolint directives
|
|
||||||
require-specific: true # require nolint directives to be specific about which linter is being skipped
|
|
||||||
staticcheck:
|
|
||||||
checks:
|
|
||||||
- "all"
|
|
||||||
- "-QF*"
|
|
||||||
exclusions:
|
exclusions:
|
||||||
generated: lax
|
|
||||||
presets:
|
presets:
|
||||||
- comments
|
|
||||||
- common-false-positives
|
|
||||||
- legacy
|
|
||||||
- std-error-handling
|
- std-error-handling
|
||||||
rules:
|
- comments
|
||||||
- linters:
|
|
||||||
- gochecknoinits
|
|
||||||
path: cmd/.*.go
|
|
||||||
- linters:
|
|
||||||
- dupl
|
|
||||||
- funlen
|
|
||||||
- gochecknoinits
|
|
||||||
- gocyclo
|
|
||||||
- lll
|
|
||||||
- scopelint
|
|
||||||
path: .*_test.go
|
|
||||||
- linters:
|
|
||||||
- misspell
|
|
||||||
text: "[aA]uther"
|
|
||||||
- linters:
|
|
||||||
- mnd
|
|
||||||
text: strconv.Parse
|
|
||||||
paths:
|
|
||||||
- frontend/
|
|
||||||
|
|
||||||
formatters:
|
|
||||||
enable:
|
|
||||||
- goimports
|
|
||||||
settings:
|
|
||||||
goimports:
|
|
||||||
local-prefixes:
|
|
||||||
- github.com/filebrowser/filebrowser
|
|
||||||
exclusions:
|
|
||||||
generated: lax
|
|
||||||
paths:
|
paths:
|
||||||
- frontend/
|
- frontend/
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,7 @@ builds:
|
||||||
- linux
|
- linux
|
||||||
- windows
|
- windows
|
||||||
- freebsd
|
- freebsd
|
||||||
|
- openbsd
|
||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
- "386"
|
- "386"
|
||||||
|
|
@ -30,6 +31,12 @@ builds:
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: "386"
|
goarch: "386"
|
||||||
|
# Experimental, may not work properly
|
||||||
|
- goos: openbsd
|
||||||
|
goarch: riscv64
|
||||||
|
# Broken as of Go 1.24, deprecated as of Go 1.26
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm
|
||||||
- goos: freebsd
|
- goos: freebsd
|
||||||
goarch: arm
|
goarch: arm
|
||||||
|
|
||||||
|
|
|
||||||
201
CHANGELOG.md
201
CHANGELOG.md
|
|
@ -2,8 +2,209 @@
|
||||||
|
|
||||||
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
All notable changes to this project will be documented in this file. See [commit-and-tag-version](https://github.com/absolute-version/commit-and-tag-version) for commit guidelines.
|
||||||
|
|
||||||
|
## [2.55.0](https://github.com/filebrowser/filebrowser/compare/v2.54.0...v2.55.0) (2026-01-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* added cut, copy, paste and show command palette functions in header ([#5648](https://github.com/filebrowser/filebrowser/issues/5648)) ([785b7ab](https://github.com/filebrowser/filebrowser/commit/785b7abb7ba7a86cc0deae1052c319ff714c222c))
|
||||||
|
* update translations ([#5677](https://github.com/filebrowser/filebrowser/issues/5677)) ([e7ea1ad](https://github.com/filebrowser/filebrowser/commit/e7ea1ad27d3d17e249489d3338be40bfea15e2a1))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* prevent context menu clicks from clearing file selection ([#5681](https://github.com/filebrowser/filebrowser/issues/5681)) ([59ca0c3](https://github.com/filebrowser/filebrowser/commit/59ca0c340afc7774747c70ede9a5a5a3c9349d6b))
|
||||||
|
* request current password when deleting users ([#5667](https://github.com/filebrowser/filebrowser/issues/5667)) ([cfa6c58](https://github.com/filebrowser/filebrowser/commit/cfa6c5864e5e7673aa9f3180e4964e0db92cc4da))
|
||||||
|
* retain file selection when closing the editor ([#5693](https://github.com/filebrowser/filebrowser/issues/5693)) ([4094fb3](https://github.com/filebrowser/filebrowser/commit/4094fb359babac70e88d0ed4bfe3bd100744aad6))
|
||||||
|
|
||||||
|
## [2.54.0](https://github.com/filebrowser/filebrowser/compare/v2.53.1...v2.54.0) (2026-01-10)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add "redirect after copy/move" user setting ([#5662](https://github.com/filebrowser/filebrowser/issues/5662)) ([fda8a99](https://github.com/filebrowser/filebrowser/commit/fda8a992929b1466e75fb2813f2c4e293c12d244))
|
||||||
|
* force file sync while uploading file ([#5668](https://github.com/filebrowser/filebrowser/issues/5668)) ([4fd18a3](https://github.com/filebrowser/filebrowser/commit/4fd18a382c31bbe7059d6733ffa371e70051865b))
|
||||||
|
* update translations ([#5659](https://github.com/filebrowser/filebrowser/issues/5659)) ([464b581](https://github.com/filebrowser/filebrowser/commit/464b581953139c17e3276b774e381e4052827125))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* clear selection by clicking on empty area ([#5663](https://github.com/filebrowser/filebrowser/issues/5663)) ([208535a](https://github.com/filebrowser/filebrowser/commit/208535a8cc23254de0013dfab9008486707ee6c2))
|
||||||
|
* hide "change password form" in noauth setting ([#5652](https://github.com/filebrowser/filebrowser/issues/5652)) ([219582c](https://github.com/filebrowser/filebrowser/commit/219582c0b03fd90979b1d1398dba7919d086a23f))
|
||||||
|
|
||||||
|
## [2.53.1](https://github.com/filebrowser/filebrowser/compare/v2.53.0...v2.53.1) (2026-01-03)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* download path encoding file paths ([#5655](https://github.com/filebrowser/filebrowser/issues/5655)) ([ffa893e](https://github.com/filebrowser/filebrowser/commit/ffa893e9ac387a49dba5917a41df7c3b7ce120fc))
|
||||||
|
* request a password to change sensitive user data ([#5629](https://github.com/filebrowser/filebrowser/issues/5629)) ([b8151a0](https://github.com/filebrowser/filebrowser/commit/b8151a038a1ea55afae8073b439b74e364cac12f))
|
||||||
|
|
||||||
|
## [2.53.0](https://github.com/filebrowser/filebrowser/compare/v2.52.0...v2.53.0) (2025-12-29)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add "disable image resolution calculation" flag ([#5638](https://github.com/filebrowser/filebrowser/issues/5638)) ([a2d80c6](https://github.com/filebrowser/filebrowser/commit/a2d80c62c1c17962e566f68fb7cac6960ed3e4cb))
|
||||||
|
* support streaming response for search results ([#5630](https://github.com/filebrowser/filebrowser/issues/5630)) ([20bfd13](https://github.com/filebrowser/filebrowser/commit/20bfd131c6a4fca48a645b52171c2d1cc3ce92b7))
|
||||||
|
* update translations ([a12a612](https://github.com/filebrowser/filebrowser/commit/a12a612970d6cc3dfbca1b35ef3a60a887a4effb))
|
||||||
|
* update translations ([#5626](https://github.com/filebrowser/filebrowser/issues/5626)) ([f899756](https://github.com/filebrowser/filebrowser/commit/f89975603e29b9f1fc05aec58afb42bbd56ed696))
|
||||||
|
* update translations ([#5631](https://github.com/filebrowser/filebrowser/issues/5631)) ([032d6c7](https://github.com/filebrowser/filebrowser/commit/032d6c7520a64686c9d9b1218562256f629b4703))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* conversion of backslashes in file paths for archive creation ([#5637](https://github.com/filebrowser/filebrowser/issues/5637)) ([9595f39](https://github.com/filebrowser/filebrowser/commit/9595f3939c1c129ed875a47adcc4fbcfad9a0e65))
|
||||||
|
* Don't crash on invalid config import ([#5640](https://github.com/filebrowser/filebrowser/issues/5640)) ([79d1aa9](https://github.com/filebrowser/filebrowser/commit/79d1aa9229b076ee8e3b71d6cf061fc90738f4da))
|
||||||
|
* fix nil deref in config set command ([#5641](https://github.com/filebrowser/filebrowser/issues/5641)) ([60b1ee8](https://github.com/filebrowser/filebrowser/commit/60b1ee8bb9e18b21d7f2c04cb1cc90046cecd3e1))
|
||||||
|
|
||||||
|
## [2.52.0](https://github.com/filebrowser/filebrowser/compare/v2.51.2...v2.52.0) (2025-12-13)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* sync translations with Transifex ([7fa3432](https://github.com/filebrowser/filebrowser/commit/7fa3432f25610bbb55a718bc709b9a7bf41d92f0))
|
||||||
|
* update translations ([#5615](https://github.com/filebrowser/filebrowser/issues/5615)) ([3fdca6d](https://github.com/filebrowser/filebrowser/commit/3fdca6dfd9a18c3f4895b4ef3cbd216824dbb57a))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* display the directory name in the shared folder view ([#5617](https://github.com/filebrowser/filebrowser/issues/5617)) ([6d4c867](https://github.com/filebrowser/filebrowser/commit/6d4c86767239dad4f09f30f48678f2f3a716eb12))
|
||||||
|
* hide the context menu when changing the route ([#5613](https://github.com/filebrowser/filebrowser/issues/5613)) ([cf96657](https://github.com/filebrowser/filebrowser/commit/cf966578d8c6beab111b74f495bac6bdec173f41))
|
||||||
|
|
||||||
|
## [2.51.2](https://github.com/filebrowser/filebrowser/compare/v2.51.1...v2.51.2) (2025-12-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **frontend:** add missing i18n strings ([c171599](https://github.com/filebrowser/filebrowser/commit/c1715992bda46517f801c1aa496df8a3b42a4e4d))
|
||||||
|
|
||||||
|
## [2.51.1](https://github.com/filebrowser/filebrowser/compare/v2.51.0...v2.51.1) (2025-12-07)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* **frontend:** csv viewer i18n strings ([4cbb4b7](https://github.com/filebrowser/filebrowser/commit/4cbb4b73af816104475f15c1d996640b56203602))
|
||||||
|
* prevent the right-click from selecting multiple items when the "single-click" option is active ([#5608](https://github.com/filebrowser/filebrowser/issues/5608)) ([152f830](https://github.com/filebrowser/filebrowser/commit/152f8302f7cda21bde37692b175c22c124233f45))
|
||||||
|
|
||||||
|
## [2.51.0](https://github.com/filebrowser/filebrowser/compare/v2.50.0...v2.51.0) (2025-12-06)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* update translations ([2d88c06](https://github.com/filebrowser/filebrowser/commit/2d88c067611e936056dbbf04247f1c1c709b2a09))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* added column separator select (comma, semicolon and both) in CSV viewer ([#5604](https://github.com/filebrowser/filebrowser/issues/5604)) ([204a3f0](https://github.com/filebrowser/filebrowser/commit/204a3f0eeaa0c68781b60651bf27c4b27eac44e6))
|
||||||
|
|
||||||
|
|
||||||
|
### Refactorings
|
||||||
|
|
||||||
|
* cleanup package names ([#5605](https://github.com/filebrowser/filebrowser/issues/5605)) ([f029c30](https://github.com/filebrowser/filebrowser/commit/f029c3005e450cfbebb074c42dbdf65db9c8d56a))
|
||||||
|
|
||||||
|
## [2.50.0](https://github.com/filebrowser/filebrowser/compare/v2.49.0...v2.50.0) (2025-11-30)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* configurable logout page URL for proxy/hook auth ([#3884](https://github.com/filebrowser/filebrowser/issues/3884)) ([b9ac45d](https://github.com/filebrowser/filebrowser/commit/b9ac45d5dac4b4eb2ba364629090fbf306cffd2b))
|
||||||
|
* render CSVs as table ([#5569](https://github.com/filebrowser/filebrowser/issues/5569)) ([982405e](https://github.com/filebrowser/filebrowser/commit/982405ec944f94baf43594b0ed2f06329ff4e9ed))
|
||||||
|
* update frontend/src/i18n/hr.json ([279a5cc](https://github.com/filebrowser/filebrowser/commit/279a5ccd1e8d7bde4568b63cb3c506af48b6c618))
|
||||||
|
* update translations ([78e0395](https://github.com/filebrowser/filebrowser/commit/78e039596070a3a9e643a693cc99960c69dcfe92))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* do not close editor if save failed ([701522a](https://github.com/filebrowser/filebrowser/commit/701522a0600cfa542469540ed764630c0ba1a732)), closes [#5591](https://github.com/filebrowser/filebrowser/issues/5591)
|
||||||
|
|
||||||
|
## [2.49.0](https://github.com/filebrowser/filebrowser/compare/v2.48.2...v2.49.0) (2025-11-22)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add "copy download link to clipboard" button to Share prompt ([#5173](https://github.com/filebrowser/filebrowser/issues/5173)) ([d48f566](https://github.com/filebrowser/filebrowser/commit/d48f5665d6975c4cbbdf9be20dc2e0106db02f01))
|
||||||
|
* add Bulgarian language ([8db2411](https://github.com/filebrowser/filebrowser/commit/8db2411cd43a23ae3292a817e3524cfdb5ae9b86))
|
||||||
|
* Updates for project File Browser ([#5566](https://github.com/filebrowser/filebrowser/issues/5566)) ([54306bd](https://github.com/filebrowser/filebrowser/commit/54306bdc8700fac489326ae81e28ac5db0580d13))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* display friendly error message for password validation on signup ([#5563](https://github.com/filebrowser/filebrowser/issues/5563)) ([6d5aa35](https://github.com/filebrowser/filebrowser/commit/6d5aa355e433d613e5a3ae137f410c63baeddf0f))
|
||||||
|
|
||||||
|
## [2.48.2](https://github.com/filebrowser/filebrowser/compare/v2.48.1...v2.48.2) (2025-11-18)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add transitionary support for FB_BASEURL ([984ea7b](https://github.com/filebrowser/filebrowser/commit/984ea7b569e3bd33b6f91ebdf63684a618d51e94))
|
||||||
|
|
||||||
|
|
||||||
|
### Refactorings
|
||||||
|
|
||||||
|
* rename python for clarification ([fd7b70c](https://github.com/filebrowser/filebrowser/commit/fd7b70cf38ac67c8c9ff79f2e7fde5e2ec45a1de))
|
||||||
|
|
||||||
|
## [2.48.1](https://github.com/filebrowser/filebrowser/compare/v2.48.0...v2.48.1) (2025-11-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* options should only override if set ([420adea](https://github.com/filebrowser/filebrowser/commit/420adea7e61a1c182cddd6fb2544a0752e5709f7))
|
||||||
|
|
||||||
|
## [2.48.0](https://github.com/filebrowser/filebrowser/compare/v2.47.0...v2.48.0) (2025-11-17)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* consistent flags and environment variables ([#5549](https://github.com/filebrowser/filebrowser/issues/5549)) ([0a0cb80](https://github.com/filebrowser/filebrowser/commit/0a0cb8046fce52f1ff926171b34bcdb7cd39aab3))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* add tokenExpirationTime to `config init` and troubleshoot docs ([#5546](https://github.com/filebrowser/filebrowser/issues/5546)) ([8c5dc76](https://github.com/filebrowser/filebrowser/commit/8c5dc7641e6f8aadd9e5d5d3b25a2ad9f1ec9a1e))
|
||||||
|
* use all available flags in quick setup ([f41585f](https://github.com/filebrowser/filebrowser/commit/f41585f0392d65c08c01ab65b62d3eeb04c03b7d))
|
||||||
|
|
||||||
|
|
||||||
|
### Refactorings
|
||||||
|
|
||||||
|
* reuse logic for config init and set ([89be0b1](https://github.com/filebrowser/filebrowser/commit/89be0b1873527987dd2dddac746e93b8bc684d46))
|
||||||
|
|
||||||
|
## [2.47.0](https://github.com/filebrowser/filebrowser/compare/v2.46.1...v2.47.0) (2025-11-16)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add TUS settings to the command line ([#5556](https://github.com/filebrowser/filebrowser/issues/5556)) ([e24e1f1](https://github.com/filebrowser/filebrowser/commit/e24e1f1abae9e80add620c4ad65660ca1b575a49))
|
||||||
|
* remove importer of v1 config ([#5550](https://github.com/filebrowser/filebrowser/issues/5550)) ([ceb5e72](https://github.com/filebrowser/filebrowser/commit/ceb5e723f3ee2c966bb561a804015246450280ca))
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* exit 0 when gracefully shutting down ([#5555](https://github.com/filebrowser/filebrowser/issues/5555)) ([5de4099](https://github.com/filebrowser/filebrowser/commit/5de4099cba2cf012d4a213c8eb29c412fc72c151))
|
||||||
|
|
||||||
|
## [2.46.1](https://github.com/filebrowser/filebrowser/compare/v2.46.0...v2.46.1) (2025-11-15)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* env key replacer and remove unused function ([#5547](https://github.com/filebrowser/filebrowser/issues/5547)) ([13814e1](https://github.com/filebrowser/filebrowser/commit/13814e11197ebd9101940883e3ca85998f86d442))
|
||||||
|
* remove duplicated 'hide-defaults' flag (is 'hideDefaults') ([#5548](https://github.com/filebrowser/filebrowser/issues/5548)) ([ffc8504](https://github.com/filebrowser/filebrowser/commit/ffc850454e4cb8f10b970511681d6c627340afc7))
|
||||||
|
|
||||||
|
## [2.46.0](https://github.com/filebrowser/filebrowser/compare/v2.45.3...v2.46.0) (2025-11-14)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* add 'hide-dotfiles' as command line parameter ([#3802](https://github.com/filebrowser/filebrowser/issues/3802)) ([0d973d3](https://github.com/filebrowser/filebrowser/commit/0d973d3aad70ceb88950f2cd9c297fc76e7955b1))
|
||||||
|
* add context menu ([#3343](https://github.com/filebrowser/filebrowser/issues/3343)) ([1ace579](https://github.com/filebrowser/filebrowser/commit/1ace579a553486bb15af2d11f537414156606434))
|
||||||
|
* add option to hide the login button from public-facing pages ([#3922](https://github.com/filebrowser/filebrowser/issues/3922)) ([ac7b49c](https://github.com/filebrowser/filebrowser/commit/ac7b49c1484b4e27a1149310542ccd1e90659ee2))
|
||||||
|
* Updates for project File Browser ([#5544](https://github.com/filebrowser/filebrowser/issues/5544)) ([fb5d099](https://github.com/filebrowser/filebrowser/commit/fb5d099f8514516216f407be012d2e3f25de2441))
|
||||||
|
|
||||||
## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13)
|
## [2.45.3](https://github.com/filebrowser/filebrowser/compare/v2.45.2...v2.45.3) (2025-11-13)
|
||||||
|
|
||||||
|
This is a test release to ensure the updated workflow works.
|
||||||
|
|
||||||
## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13)
|
## [2.45.2](https://github.com/filebrowser/filebrowser/compare/v2.45.1...v2.45.2) (2025-11-13)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ task docs
|
||||||
To start a local server on port `8000` to view the built documentation:
|
To start a local server on port `8000` to view the built documentation:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
task docs-serve
|
task docs:serve
|
||||||
```
|
```
|
||||||
|
|
||||||
## Release
|
## Release
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
## Multistage build: First stage fetches dependencies
|
## Multistage build: First stage fetches dependencies
|
||||||
FROM alpine:3.22 AS fetcher
|
FROM alpine:3.23 AS fetcher
|
||||||
|
|
||||||
# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
|
# install and copy ca-certificates, mailcap, and tini-static; download JSON.sh
|
||||||
RUN apk update && \
|
RUN apk update && \
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
FROM ghcr.io/linuxserver/baseimage-alpine:3.22
|
FROM ghcr.io/linuxserver/baseimage-alpine:3.23
|
||||||
|
|
||||||
RUN apk update && \
|
RUN apk update && \
|
||||||
apk --no-cache add ca-certificates mailcap jq libcap
|
apk --no-cache add ca-certificates mailcap jq libcap
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
|
<img src="https://raw.githubusercontent.com/filebrowser/filebrowser/master/branding/banner.png" width="550"/>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
[](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml)
|
[](https://github.com/filebrowser/filebrowser/actions/workflows/ci.yaml)
|
||||||
[](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2)
|
[](https://goreportcard.com/report/github.com/filebrowser/filebrowser/v2)
|
||||||
[](https://github.com/filebrowser/filebrowser/releases/latest)
|
[](https://github.com/filebrowser/filebrowser/releases/latest)
|
||||||
|
|
||||||
|
|
@ -19,7 +19,7 @@ This project is a finished product which fulfills its goal: be a single binary w
|
||||||
- It can take a while until someone gets back to you. Please be patient.
|
- It can take a while until someone gets back to you. Please be patient.
|
||||||
- [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions).
|
- [Issues](https://github.com/filebrowser/filebrowser/issues) are meant to track bugs. Unrelated issues will be converted into [discussions](https://github.com/filebrowser/filebrowser/discussions).
|
||||||
- No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis.
|
- No new features will be implemented by maintainers. Pull requests for new features will be reviewed on a case by case basis.
|
||||||
- The priority is triaging issues, addressing security issues, and fixing bug fixes.
|
- The priority is triaging issues, addressing security issues and reviewing pull requests meant to solve bugs.
|
||||||
|
|
||||||
## Contributing
|
## Contributing
|
||||||
|
|
||||||
|
|
|
||||||
38
Taskfile.yml
38
Taskfile.yml
|
|
@ -10,14 +10,14 @@ vars:
|
||||||
-v ./CONTRIBUTING.md:/docs/docs/contributing.md
|
-v ./CONTRIBUTING.md:/docs/docs/contributing.md
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
build-frontend:
|
build:frontend:
|
||||||
desc: Build frontend assets
|
desc: Build frontend assets
|
||||||
dir: frontend
|
dir: frontend
|
||||||
cmds:
|
cmds:
|
||||||
- pnpm install --frozen-lockfile
|
- pnpm install --frozen-lockfile
|
||||||
- pnpm run build
|
- pnpm run build
|
||||||
|
|
||||||
build-backend:
|
build:backend:
|
||||||
desc: Build backend binary
|
desc: Build backend binary
|
||||||
cmds:
|
cmds:
|
||||||
- go build -ldflags='-s -w -X "github.com/filebrowser/filebrowser/v2/version.Version={{.VERSION}}" -X "github.com/filebrowser/filebrowser/v2/version.CommitSHA={{.GIT_COMMIT}}"' -o filebrowser .
|
- go build -ldflags='-s -w -X "github.com/filebrowser/filebrowser/v2/version.Version={{.VERSION}}" -X "github.com/filebrowser/filebrowser/v2/version.CommitSHA={{.GIT_COMMIT}}"' -o filebrowser .
|
||||||
|
|
@ -30,16 +30,16 @@ tasks:
|
||||||
build:
|
build:
|
||||||
desc: Build both frontend and backend
|
desc: Build both frontend and backend
|
||||||
cmds:
|
cmds:
|
||||||
- task: build-frontend
|
- task: build:frontend
|
||||||
- task: build-backend
|
- task: build:backend
|
||||||
|
|
||||||
release-make:
|
release:make:
|
||||||
internal: true
|
internal: true
|
||||||
prompt: Do you wish to proceed?
|
prompt: Do you wish to proceed?
|
||||||
cmds:
|
cmds:
|
||||||
- pnpm dlx commit-and-tag-version -s
|
- pnpm dlx commit-and-tag-version -s
|
||||||
|
|
||||||
release-dry-run:
|
release:dry-run:
|
||||||
internal: true
|
internal: true
|
||||||
cmds:
|
cmds:
|
||||||
- pnpm dlx commit-and-tag-version --dry-run --skip
|
- pnpm dlx commit-and-tag-version --dry-run --skip
|
||||||
|
|
@ -47,10 +47,24 @@ tasks:
|
||||||
release:
|
release:
|
||||||
desc: Create a new release
|
desc: Create a new release
|
||||||
cmds:
|
cmds:
|
||||||
- task: release-dry-run
|
- task: docs:cli:generate
|
||||||
- task: release-make
|
- git add www/docs/cli
|
||||||
|
- |
|
||||||
|
if [[ `git status www/docs/cli --porcelain` ]]; then
|
||||||
|
git commit -m 'chore(docs): update CLI documentation'
|
||||||
|
fi
|
||||||
|
- task: release:dry-run
|
||||||
|
- task: release:make
|
||||||
|
|
||||||
docs-image-make:
|
docs:cli:generate:
|
||||||
|
cmds:
|
||||||
|
- rm -rf www/docs/cli
|
||||||
|
- mkdir -p www/docs/cli
|
||||||
|
- go run . docs
|
||||||
|
generates:
|
||||||
|
- www/docs/cli
|
||||||
|
|
||||||
|
docs:docker:generate:
|
||||||
internal: true
|
internal: true
|
||||||
cmds:
|
cmds:
|
||||||
- docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
|
- docker build -f www/Dockerfile --progress=plain -t filebrowser.site www
|
||||||
|
|
@ -59,11 +73,11 @@ tasks:
|
||||||
desc: Generate documentation
|
desc: Generate documentation
|
||||||
cmds:
|
cmds:
|
||||||
- rm -rf www/public
|
- rm -rf www/public
|
||||||
- task: docs-image-make
|
- task: docs:docker:generate
|
||||||
- docker run --rm {{.SITE_DOCKER_FLAGS}} filebrowser.site build -d "public"
|
- docker run --rm {{.SITE_DOCKER_FLAGS}} filebrowser.site build -d "public"
|
||||||
|
|
||||||
docs-serve:
|
docs:serve:
|
||||||
desc: Serve documentation
|
desc: Serve documentation
|
||||||
cmds:
|
cmds:
|
||||||
- task: docs-image-make
|
- task: docs:docker:generate
|
||||||
- docker run --rm -it -p 8000:8000 {{.SITE_DOCKER_FLAGS}} filebrowser.site
|
- docker run --rm -it -p 8000:8000 {{.SITE_DOCKER_FLAGS}} filebrowser.site
|
||||||
|
|
|
||||||
43
auth/hook.go
43
auth/hook.go
|
|
@ -11,7 +11,7 @@ import (
|
||||||
"slices"
|
"slices"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
"github.com/filebrowser/filebrowser/v2/files"
|
"github.com/filebrowser/filebrowser/v2/files"
|
||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
"github.com/filebrowser/filebrowser/v2/settings"
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
"github.com/filebrowser/filebrowser/v2/users"
|
||||||
|
|
@ -103,7 +103,7 @@ func (a *HookAuth) RunCommand() (string, error) {
|
||||||
command[i] = os.Expand(arg, envMapping)
|
command[i] = os.Expand(arg, envMapping)
|
||||||
}
|
}
|
||||||
|
|
||||||
cmd := exec.Command(command[0], command[1:]...) //nolint:gosec
|
cmd := exec.Command(command[0], command[1:]...)
|
||||||
cmd.Env = append(os.Environ(), fmt.Sprintf("USERNAME=%s", a.Cred.Username))
|
cmd.Env = append(os.Environ(), fmt.Sprintf("USERNAME=%s", a.Cred.Username))
|
||||||
cmd.Env = append(cmd.Env, fmt.Sprintf("PASSWORD=%s", a.Cred.Password))
|
cmd.Env = append(cmd.Env, fmt.Sprintf("PASSWORD=%s", a.Cred.Password))
|
||||||
out, err := cmd.Output()
|
out, err := cmd.Output()
|
||||||
|
|
@ -146,7 +146,7 @@ func (a *HookAuth) GetValues(s string) {
|
||||||
// SaveUser updates the existing user or creates a new one when not found
|
// SaveUser updates the existing user or creates a new one when not found
|
||||||
func (a *HookAuth) SaveUser() (*users.User, error) {
|
func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||||
u, err := a.Users.Get(a.Server.Root, a.Cred.Username)
|
u, err := a.Users.Get(a.Server.Root, a.Cred.Username)
|
||||||
if err != nil && !errors.Is(err, fbErrors.ErrNotExist) {
|
if err != nil && !errors.Is(err, fberrors.ErrNotExist) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -158,16 +158,17 @@ func (a *HookAuth) SaveUser() (*users.User, error) {
|
||||||
|
|
||||||
// create user with the provided credentials
|
// create user with the provided credentials
|
||||||
d := &users.User{
|
d := &users.User{
|
||||||
Username: a.Cred.Username,
|
Username: a.Cred.Username,
|
||||||
Password: pass,
|
Password: pass,
|
||||||
Scope: a.Settings.Defaults.Scope,
|
Scope: a.Settings.Defaults.Scope,
|
||||||
Locale: a.Settings.Defaults.Locale,
|
Locale: a.Settings.Defaults.Locale,
|
||||||
ViewMode: a.Settings.Defaults.ViewMode,
|
ViewMode: a.Settings.Defaults.ViewMode,
|
||||||
SingleClick: a.Settings.Defaults.SingleClick,
|
SingleClick: a.Settings.Defaults.SingleClick,
|
||||||
Sorting: a.Settings.Defaults.Sorting,
|
RedirectAfterCopyMove: a.Settings.Defaults.RedirectAfterCopyMove,
|
||||||
Perm: a.Settings.Defaults.Perm,
|
Sorting: a.Settings.Defaults.Sorting,
|
||||||
Commands: a.Settings.Defaults.Commands,
|
Perm: a.Settings.Defaults.Perm,
|
||||||
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
Commands: a.Settings.Defaults.Commands,
|
||||||
|
HideDotfiles: a.Settings.Defaults.HideDotfiles,
|
||||||
}
|
}
|
||||||
u = a.GetUser(d)
|
u = a.GetUser(d)
|
||||||
|
|
||||||
|
|
@ -219,13 +220,14 @@ func (a *HookAuth) GetUser(d *users.User) *users.User {
|
||||||
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
|
Download: isAdmin || a.Fields.GetBoolean("user.perm.download", d.Perm.Download),
|
||||||
}
|
}
|
||||||
user := users.User{
|
user := users.User{
|
||||||
ID: d.ID,
|
ID: d.ID,
|
||||||
Username: d.Username,
|
Username: d.Username,
|
||||||
Password: d.Password,
|
Password: d.Password,
|
||||||
Scope: a.Fields.GetString("user.scope", d.Scope),
|
Scope: a.Fields.GetString("user.scope", d.Scope),
|
||||||
Locale: a.Fields.GetString("user.locale", d.Locale),
|
Locale: a.Fields.GetString("user.locale", d.Locale),
|
||||||
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
ViewMode: users.ViewMode(a.Fields.GetString("user.viewMode", string(d.ViewMode))),
|
||||||
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
SingleClick: a.Fields.GetBoolean("user.singleClick", d.SingleClick),
|
||||||
|
RedirectAfterCopyMove: a.Fields.GetBoolean("user.redirectAfterCopyMove", d.RedirectAfterCopyMove),
|
||||||
Sorting: files.Sorting{
|
Sorting: files.Sorting{
|
||||||
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
|
Asc: a.Fields.GetBoolean("user.sorting.asc", d.Sorting.Asc),
|
||||||
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
|
By: a.Fields.GetString("user.sorting.by", d.Sorting.By),
|
||||||
|
|
@ -251,6 +253,7 @@ var validHookFields = []string{
|
||||||
"user.locale",
|
"user.locale",
|
||||||
"user.viewMode",
|
"user.viewMode",
|
||||||
"user.singleClick",
|
"user.singleClick",
|
||||||
|
"user.redirectAfterCopyMove",
|
||||||
"user.sorting.by",
|
"user.sorting.by",
|
||||||
"user.sorting.asc",
|
"user.sorting.asc",
|
||||||
"user.commands",
|
"user.commands",
|
||||||
|
|
|
||||||
18
auth/json.go
18
auth/json.go
|
|
@ -14,6 +14,10 @@ import (
|
||||||
// MethodJSONAuth is used to identify json auth.
|
// MethodJSONAuth is used to identify json auth.
|
||||||
const MethodJSONAuth settings.AuthMethod = "json"
|
const MethodJSONAuth settings.AuthMethod = "json"
|
||||||
|
|
||||||
|
// dummyHash is used to prevent user enumeration timing attacks.
|
||||||
|
// It MUST be a valid bcrypt hash.
|
||||||
|
const dummyHash = "$2a$10$O4mEMeOL/nit6zqe.WQXauLRbRlzb3IgLHsa26Pf0N/GiU9b.wK1m"
|
||||||
|
|
||||||
type jsonCred struct {
|
type jsonCred struct {
|
||||||
Password string `json:"password"`
|
Password string `json:"password"`
|
||||||
Username string `json:"username"`
|
Username string `json:"username"`
|
||||||
|
|
@ -40,7 +44,7 @@ func (a JSONAuth) Auth(r *http.Request, usr users.Store, _ *settings.Settings, s
|
||||||
|
|
||||||
// If ReCaptcha is enabled, check the code.
|
// If ReCaptcha is enabled, check the code.
|
||||||
if a.ReCaptcha != nil && a.ReCaptcha.Secret != "" {
|
if a.ReCaptcha != nil && a.ReCaptcha.Secret != "" {
|
||||||
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:govet
|
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -52,7 +56,17 @@ func (a JSONAuth) Auth(r *http.Request, usr users.Store, _ *settings.Settings, s
|
||||||
}
|
}
|
||||||
|
|
||||||
u, err := usr.Get(srv.Root, cred.Username)
|
u, err := usr.Get(srv.Root, cred.Username)
|
||||||
if err != nil || !users.CheckPwd(cred.Password, u.Password) {
|
|
||||||
|
hash := dummyHash
|
||||||
|
if err == nil {
|
||||||
|
hash = u.Password
|
||||||
|
}
|
||||||
|
|
||||||
|
if !users.CheckPwd(cred.Password, hash) {
|
||||||
|
return nil, os.ErrPermission
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
return nil, os.ErrPermission
|
return nil, os.ErrPermission
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
"github.com/filebrowser/filebrowser/v2/settings"
|
||||||
"github.com/filebrowser/filebrowser/v2/users"
|
"github.com/filebrowser/filebrowser/v2/users"
|
||||||
)
|
)
|
||||||
|
|
@ -21,7 +21,7 @@ type ProxyAuth struct {
|
||||||
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) {
|
func (a ProxyAuth) Auth(r *http.Request, usr users.Store, setting *settings.Settings, srv *settings.Server) (*users.User, error) {
|
||||||
username := r.Header.Get(a.Header)
|
username := r.Header.Get(a.Header)
|
||||||
user, err := usr.Get(srv.Root, username)
|
user, err := usr.Get(srv.Root, username)
|
||||||
if errors.Is(err, fbErrors.ErrNotExist) {
|
if errors.Is(err, fberrors.ErrNotExist) {
|
||||||
return a.createUser(usr, setting, srv, username)
|
return a.createUser(usr, setting, srv, username)
|
||||||
}
|
}
|
||||||
return user, err
|
return user, err
|
||||||
|
|
|
||||||
35
cmd/cmd_test.go
Normal file
35
cmd/cmd_test.go
Normal file
|
|
@ -0,0 +1,35 @@
|
||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/samber/lo"
|
||||||
|
"github.com/spf13/cobra"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestEnvCollisions ensures that there are no collisions in the produced environment
|
||||||
|
// variable names for all commands and their flags.
|
||||||
|
func TestEnvCollisions(t *testing.T) {
|
||||||
|
testEnvCollisions(t, rootCmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func testEnvCollisions(t *testing.T, cmd *cobra.Command) {
|
||||||
|
for _, cmd := range cmd.Commands() {
|
||||||
|
testEnvCollisions(t, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
replacements := generateEnvKeyReplacements(cmd)
|
||||||
|
envVariables := []string{}
|
||||||
|
|
||||||
|
for i := range replacements {
|
||||||
|
if i%2 != 0 {
|
||||||
|
envVariables = append(envVariables, replacements[i])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicates := lo.FindDuplicates(envVariables)
|
||||||
|
|
||||||
|
if len(duplicates) > 0 {
|
||||||
|
t.Errorf("Found duplicate environment variable keys for command %q: %v", cmd.Name(), duplicates)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -15,18 +15,18 @@ var cmdsAddCmd = &cobra.Command{
|
||||||
Short: "Add a command to run on a specific event",
|
Short: "Add a command to run on a specific event",
|
||||||
Long: `Add a command to run on a specific event.`,
|
Long: `Add a command to run on a specific event.`,
|
||||||
Args: cobra.MinimumNArgs(2),
|
Args: cobra.MinimumNArgs(2),
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
command := strings.Join(args[1:], " ")
|
command := strings.Join(args[1:], " ")
|
||||||
s.Commands[args[0]] = append(s.Commands[args[0]], command)
|
s.Commands[args[0]] = append(s.Commands[args[0]], command)
|
||||||
err = d.store.Settings.Save(s)
|
err = st.Settings.Save(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printEvents(s.Commands)
|
printEvents(s.Commands)
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,12 +14,13 @@ var cmdsLsCmd = &cobra.Command{
|
||||||
Short: "List all commands for each event",
|
Short: "List all commands for each event",
|
||||||
Long: `List all commands for each event.`,
|
Long: `List all commands for each event.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
evt, err := getString(cmd.Flags(), "event")
|
|
||||||
|
evt, err := cmd.Flags().GetString("event")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -32,6 +33,7 @@ var cmdsLsCmd = &cobra.Command{
|
||||||
show["after_"+evt] = s.Commands["after_"+evt]
|
show["after_"+evt] = s.Commands["after_"+evt]
|
||||||
printEvents(show)
|
printEvents(show)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ including 'index_end'.`,
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
s, err := d.store.Settings.Get()
|
s, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -55,11 +55,11 @@ including 'index_end'.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...)
|
s.Commands[evt] = append(s.Commands[evt][:i], s.Commands[evt][f+1:]...)
|
||||||
err = d.store.Settings.Save(s)
|
err = st.Settings.Save(s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printEvents(s.Commands)
|
printEvents(s.Commands)
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
186
cmd/config.go
186
cmd/config.go
|
|
@ -2,7 +2,7 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
nerrors "errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
@ -12,7 +12,7 @@ import (
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/auth"
|
"github.com/filebrowser/filebrowser/v2/auth"
|
||||||
"github.com/filebrowser/filebrowser/v2/errors"
|
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
"github.com/filebrowser/filebrowser/v2/settings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -30,14 +30,22 @@ var configCmd = &cobra.Command{
|
||||||
func addConfigFlags(flags *pflag.FlagSet) {
|
func addConfigFlags(flags *pflag.FlagSet) {
|
||||||
addServerFlags(flags)
|
addServerFlags(flags)
|
||||||
addUserFlags(flags)
|
addUserFlags(flags)
|
||||||
|
|
||||||
flags.BoolP("signup", "s", false, "allow users to signup")
|
flags.BoolP("signup", "s", false, "allow users to signup")
|
||||||
flags.Bool("create-user-dir", false, "generate user's home directory automatically")
|
flags.Bool("hideLoginButton", false, "hide login button from public pages")
|
||||||
flags.Uint("minimum-password-length", settings.DefaultMinimumPasswordLength, "minimum password length for new users")
|
flags.Bool("createUserDir", false, "generate user's home directory automatically")
|
||||||
|
flags.Uint("minimumPasswordLength", settings.DefaultMinimumPasswordLength, "minimum password length for new users")
|
||||||
flags.String("shell", "", "shell command to which other commands should be appended")
|
flags.String("shell", "", "shell command to which other commands should be appended")
|
||||||
|
|
||||||
|
// NB: these are string so they can be presented as octal in the help text
|
||||||
|
// as that's the conventional representation for modes in Unix.
|
||||||
|
flags.String("fileMode", fmt.Sprintf("%O", settings.DefaultFileMode), "mode bits that new files are created with")
|
||||||
|
flags.String("dirMode", fmt.Sprintf("%O", settings.DefaultDirMode), "mode bits that new directories are created with")
|
||||||
|
|
||||||
flags.String("auth.method", string(auth.MethodJSONAuth), "authentication type")
|
flags.String("auth.method", string(auth.MethodJSONAuth), "authentication type")
|
||||||
flags.String("auth.header", "", "HTTP header for auth.method=proxy")
|
flags.String("auth.header", "", "HTTP header for auth.method=proxy")
|
||||||
flags.String("auth.command", "", "command for auth.method=hook")
|
flags.String("auth.command", "", "command for auth.method=hook")
|
||||||
|
flags.String("auth.logoutPage", "", "url of custom logout page")
|
||||||
|
|
||||||
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
|
flags.String("recaptcha.host", "https://www.google.com", "use another host for ReCAPTCHA. recaptcha.net might be useful in China")
|
||||||
flags.String("recaptcha.key", "", "ReCaptcha site key")
|
flags.String("recaptcha.key", "", "ReCaptcha site key")
|
||||||
|
|
@ -49,14 +57,13 @@ func addConfigFlags(flags *pflag.FlagSet) {
|
||||||
flags.String("branding.files", "", "path to directory with images and custom styles")
|
flags.String("branding.files", "", "path to directory with images and custom styles")
|
||||||
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
|
flags.Bool("branding.disableExternal", false, "disable external links such as GitHub links")
|
||||||
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")
|
flags.Bool("branding.disableUsedPercentage", false, "disable used disk percentage graph")
|
||||||
// NB: these are string so they can be presented as octal in the help text
|
|
||||||
// as that's the conventional representation for modes in Unix.
|
flags.Uint64("tus.chunkSize", settings.DefaultTusChunkSize, "the tus chunk size")
|
||||||
flags.String("file-mode", fmt.Sprintf("%O", settings.DefaultFileMode), "Mode bits that new files are created with")
|
flags.Uint16("tus.retryCount", settings.DefaultTusRetryCount, "the tus retry count")
|
||||||
flags.String("dir-mode", fmt.Sprintf("%O", settings.DefaultDirMode), "Mode bits that new directories are created with")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
|
func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.AuthMethod, map[string]interface{}, error) {
|
||||||
methodStr, err := getString(flags, "auth.method")
|
methodStr, err := flags.GetString("auth.method")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", nil, err
|
return "", nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -87,17 +94,17 @@ func getAuthMethod(flags *pflag.FlagSet, defaults ...interface{}) (settings.Auth
|
||||||
}
|
}
|
||||||
|
|
||||||
func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
func getProxyAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
header, err := getString(flags, "auth.header")
|
header, err := flags.GetString("auth.header")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if header == "" {
|
if header == "" && defaultAuther != nil {
|
||||||
header = defaultAuther["header"].(string)
|
header = defaultAuther["header"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if header == "" {
|
if header == "" {
|
||||||
return nil, nerrors.New("you must set the flag 'auth.header' for method 'proxy'")
|
return nil, errors.New("you must set the flag 'auth.header' for method 'proxy'")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &auth.ProxyAuth{Header: header}, nil
|
return &auth.ProxyAuth{Header: header}, nil
|
||||||
|
|
@ -109,15 +116,17 @@ func getNoAuth() auth.Auther {
|
||||||
|
|
||||||
func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
jsonAuth := &auth.JSONAuth{}
|
jsonAuth := &auth.JSONAuth{}
|
||||||
host, err := getString(flags, "recaptcha.host")
|
host, err := flags.GetString("recaptcha.host")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
key, err := getString(flags, "recaptcha.key")
|
|
||||||
|
key, err := flags.GetString("recaptcha.key")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
secret, err := getString(flags, "recaptcha.secret")
|
|
||||||
|
secret, err := flags.GetString("recaptcha.secret")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -145,17 +154,16 @@ func getJSONAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (au
|
||||||
}
|
}
|
||||||
|
|
||||||
func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
func getHookAuth(flags *pflag.FlagSet, defaultAuther map[string]interface{}) (auth.Auther, error) {
|
||||||
command, err := getString(flags, "auth.command")
|
command, err := flags.GetString("auth.command")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if command == "" {
|
if command == "" {
|
||||||
command = defaultAuther["command"].(string)
|
command = defaultAuther["command"].(string)
|
||||||
}
|
}
|
||||||
|
|
||||||
if command == "" {
|
if command == "" {
|
||||||
return nil, nerrors.New("you must set the flag 'auth.command' for method 'hook'")
|
return nil, errors.New("you must set the flag 'auth.command' for method 'hook'")
|
||||||
}
|
}
|
||||||
|
|
||||||
return &auth.HookAuth{Command: command}, nil
|
return &auth.HookAuth{Command: command}, nil
|
||||||
|
|
@ -178,7 +186,7 @@ func getAuthentication(flags *pflag.FlagSet, defaults ...interface{}) (settings.
|
||||||
case auth.MethodHookAuth:
|
case auth.MethodHookAuth:
|
||||||
auther, err = getHookAuth(flags, defaultAuther)
|
auther, err = getHookAuth(flags, defaultAuther)
|
||||||
default:
|
default:
|
||||||
return "", nil, errors.ErrInvalidAuthMethod
|
return "", nil, fberrors.ErrInvalidAuthMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -192,10 +200,13 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||||
|
|
||||||
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
fmt.Fprintf(w, "Sign up:\t%t\n", set.Signup)
|
||||||
|
fmt.Fprintf(w, "Hide Login Button:\t%t\n", set.HideLoginButton)
|
||||||
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
|
fmt.Fprintf(w, "Create User Dir:\t%t\n", set.CreateUserDir)
|
||||||
|
fmt.Fprintf(w, "Logout Page:\t%s\n", set.LogoutPage)
|
||||||
fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength)
|
fmt.Fprintf(w, "Minimum Password Length:\t%d\n", set.MinimumPasswordLength)
|
||||||
fmt.Fprintf(w, "Auth method:\t%s\n", set.AuthMethod)
|
fmt.Fprintf(w, "Auth Method:\t%s\n", set.AuthMethod)
|
||||||
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
|
fmt.Fprintf(w, "Shell:\t%s\t\n", strings.Join(set.Shell, " "))
|
||||||
|
|
||||||
fmt.Fprintln(w, "\nBranding:")
|
fmt.Fprintln(w, "\nBranding:")
|
||||||
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
|
fmt.Fprintf(w, "\tName:\t%s\n", set.Branding.Name)
|
||||||
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
|
fmt.Fprintf(w, "\tFiles override:\t%s\n", set.Branding.Files)
|
||||||
|
|
@ -203,6 +214,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||||
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
|
fmt.Fprintf(w, "\tDisable used disk percentage graph:\t%t\n", set.Branding.DisableUsedPercentage)
|
||||||
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
|
fmt.Fprintf(w, "\tColor:\t%s\n", set.Branding.Color)
|
||||||
fmt.Fprintf(w, "\tTheme:\t%s\n", set.Branding.Theme)
|
fmt.Fprintf(w, "\tTheme:\t%s\n", set.Branding.Theme)
|
||||||
|
|
||||||
fmt.Fprintln(w, "\nServer:")
|
fmt.Fprintln(w, "\nServer:")
|
||||||
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
|
fmt.Fprintf(w, "\tLog:\t%s\n", ser.Log)
|
||||||
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)
|
fmt.Fprintf(w, "\tPort:\t%s\n", ser.Port)
|
||||||
|
|
@ -212,19 +224,32 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||||
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
|
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
|
||||||
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
|
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
|
||||||
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
|
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
|
||||||
|
fmt.Fprintf(w, "\tToken Expiration Time:\t%s\n", ser.TokenExpirationTime)
|
||||||
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
|
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
|
||||||
|
fmt.Fprintf(w, "\tThumbnails Enabled:\t%t\n", ser.EnableThumbnails)
|
||||||
|
fmt.Fprintf(w, "\tResize Preview:\t%t\n", ser.ResizePreview)
|
||||||
|
fmt.Fprintf(w, "\tType Detection by Header:\t%t\n", ser.TypeDetectionByHeader)
|
||||||
|
|
||||||
|
fmt.Fprintln(w, "\nTUS:")
|
||||||
|
fmt.Fprintf(w, "\tChunk size:\t%d\n", set.Tus.ChunkSize)
|
||||||
|
fmt.Fprintf(w, "\tRetry count:\t%d\n", set.Tus.RetryCount)
|
||||||
|
|
||||||
fmt.Fprintln(w, "\nDefaults:")
|
fmt.Fprintln(w, "\nDefaults:")
|
||||||
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
||||||
|
fmt.Fprintf(w, "\tHideDotfiles:\t%t\n", set.Defaults.HideDotfiles)
|
||||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||||
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
|
fmt.Fprintf(w, "\tView mode:\t%s\n", set.Defaults.ViewMode)
|
||||||
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
|
fmt.Fprintf(w, "\tSingle Click:\t%t\n", set.Defaults.SingleClick)
|
||||||
|
fmt.Fprintf(w, "\tRedirect after Copy/Move:\t%t\n", set.Defaults.RedirectAfterCopyMove)
|
||||||
fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode)
|
fmt.Fprintf(w, "\tFile Creation Mode:\t%O\n", set.FileMode)
|
||||||
fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode)
|
fmt.Fprintf(w, "\tDirectory Creation Mode:\t%O\n", set.DirMode)
|
||||||
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
fmt.Fprintf(w, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
||||||
fmt.Fprintf(w, "\tAce editor syntax highlighting theme:\t%s\n", set.Defaults.AceEditorTheme)
|
fmt.Fprintf(w, "\tAce editor syntax highlighting theme:\t%s\n", set.Defaults.AceEditorTheme)
|
||||||
|
|
||||||
fmt.Fprintf(w, "\tSorting:\n")
|
fmt.Fprintf(w, "\tSorting:\n")
|
||||||
fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By)
|
fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By)
|
||||||
fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.Defaults.Sorting.Asc)
|
fmt.Fprintf(w, "\t\tAsc:\t%t\n", set.Defaults.Sorting.Asc)
|
||||||
|
|
||||||
fmt.Fprintf(w, "\tPermissions:\n")
|
fmt.Fprintf(w, "\tPermissions:\n")
|
||||||
fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.Defaults.Perm.Admin)
|
fmt.Fprintf(w, "\t\tAdmin:\t%t\n", set.Defaults.Perm.Admin)
|
||||||
fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.Defaults.Perm.Execute)
|
fmt.Fprintf(w, "\t\tExecute:\t%t\n", set.Defaults.Perm.Execute)
|
||||||
|
|
@ -234,6 +259,7 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||||
fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.Defaults.Perm.Delete)
|
fmt.Fprintf(w, "\t\tDelete:\t%t\n", set.Defaults.Perm.Delete)
|
||||||
fmt.Fprintf(w, "\t\tShare:\t%t\n", set.Defaults.Perm.Share)
|
fmt.Fprintf(w, "\t\tShare:\t%t\n", set.Defaults.Perm.Share)
|
||||||
fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.Defaults.Perm.Download)
|
fmt.Fprintf(w, "\t\tDownload:\t%t\n", set.Defaults.Perm.Download)
|
||||||
|
|
||||||
w.Flush()
|
w.Flush()
|
||||||
|
|
||||||
b, err := json.MarshalIndent(auther, "", " ")
|
b, err := json.MarshalIndent(auther, "", " ")
|
||||||
|
|
@ -243,3 +269,123 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||||
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
|
fmt.Printf("\nAuther configuration (raw):\n\n%s\n\n", string(b))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getSettings(flags *pflag.FlagSet, set *settings.Settings, ser *settings.Server, auther auth.Auther, all bool) (auth.Auther, error) {
|
||||||
|
errs := []error{}
|
||||||
|
hasAuth := false
|
||||||
|
|
||||||
|
visit := func(flag *pflag.Flag) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
switch flag.Name {
|
||||||
|
// Server flags from [addServerFlags]
|
||||||
|
case "address":
|
||||||
|
ser.Address, err = flags.GetString(flag.Name)
|
||||||
|
case "log":
|
||||||
|
ser.Log, err = flags.GetString(flag.Name)
|
||||||
|
case "port":
|
||||||
|
ser.Port, err = flags.GetString(flag.Name)
|
||||||
|
case "cert":
|
||||||
|
ser.TLSCert, err = flags.GetString(flag.Name)
|
||||||
|
case "key":
|
||||||
|
ser.TLSKey, err = flags.GetString(flag.Name)
|
||||||
|
case "root":
|
||||||
|
ser.Root, err = flags.GetString(flag.Name)
|
||||||
|
case "socket":
|
||||||
|
ser.Socket, err = flags.GetString(flag.Name)
|
||||||
|
case "baseURL":
|
||||||
|
ser.BaseURL, err = flags.GetString(flag.Name)
|
||||||
|
case "tokenExpirationTime":
|
||||||
|
ser.TokenExpirationTime, err = flags.GetString(flag.Name)
|
||||||
|
case "disableThumbnails":
|
||||||
|
ser.EnableThumbnails, err = flags.GetBool(flag.Name)
|
||||||
|
ser.EnableThumbnails = !ser.EnableThumbnails
|
||||||
|
case "disablePreviewResize":
|
||||||
|
ser.ResizePreview, err = flags.GetBool(flag.Name)
|
||||||
|
ser.ResizePreview = !ser.ResizePreview
|
||||||
|
case "disableExec":
|
||||||
|
ser.EnableExec, err = flags.GetBool(flag.Name)
|
||||||
|
ser.EnableExec = !ser.EnableExec
|
||||||
|
case "disableTypeDetectionByHeader":
|
||||||
|
ser.TypeDetectionByHeader, err = flags.GetBool(flag.Name)
|
||||||
|
ser.TypeDetectionByHeader = !ser.TypeDetectionByHeader
|
||||||
|
case "disableImageResolutionCalc":
|
||||||
|
ser.ImageResolutionCal, err = flags.GetBool(flag.Name)
|
||||||
|
ser.ImageResolutionCal = !ser.ImageResolutionCal
|
||||||
|
|
||||||
|
// Settings flags from [addConfigFlags]
|
||||||
|
case "signup":
|
||||||
|
set.Signup, err = flags.GetBool(flag.Name)
|
||||||
|
case "hideLoginButton":
|
||||||
|
set.HideLoginButton, err = flags.GetBool(flag.Name)
|
||||||
|
case "createUserDir":
|
||||||
|
set.CreateUserDir, err = flags.GetBool(flag.Name)
|
||||||
|
case "minimumPasswordLength":
|
||||||
|
set.MinimumPasswordLength, err = flags.GetUint(flag.Name)
|
||||||
|
case "shell":
|
||||||
|
var shell string
|
||||||
|
shell, err = flags.GetString(flag.Name)
|
||||||
|
if err == nil {
|
||||||
|
set.Shell = convertCmdStrToCmdArray(shell)
|
||||||
|
}
|
||||||
|
case "fileMode":
|
||||||
|
set.FileMode, err = getAndParseFileMode(flags, flag.Name)
|
||||||
|
case "dirMode":
|
||||||
|
set.DirMode, err = getAndParseFileMode(flags, flag.Name)
|
||||||
|
case "auth.method":
|
||||||
|
hasAuth = true
|
||||||
|
case "auth.logoutPage":
|
||||||
|
set.LogoutPage, err = flags.GetString(flag.Name)
|
||||||
|
case "branding.name":
|
||||||
|
set.Branding.Name, err = flags.GetString(flag.Name)
|
||||||
|
case "branding.theme":
|
||||||
|
set.Branding.Theme, err = flags.GetString(flag.Name)
|
||||||
|
case "branding.color":
|
||||||
|
set.Branding.Color, err = flags.GetString(flag.Name)
|
||||||
|
case "branding.files":
|
||||||
|
set.Branding.Files, err = flags.GetString(flag.Name)
|
||||||
|
case "branding.disableExternal":
|
||||||
|
set.Branding.DisableExternal, err = flags.GetBool(flag.Name)
|
||||||
|
case "branding.disableUsedPercentage":
|
||||||
|
set.Branding.DisableUsedPercentage, err = flags.GetBool(flag.Name)
|
||||||
|
case "tus.chunkSize":
|
||||||
|
set.Tus.ChunkSize, err = flags.GetUint64(flag.Name)
|
||||||
|
case "tus.retryCount":
|
||||||
|
set.Tus.RetryCount, err = flags.GetUint16(flag.Name)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
errs = append(errs, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if all {
|
||||||
|
flags.VisitAll(visit)
|
||||||
|
} else {
|
||||||
|
flags.Visit(visit)
|
||||||
|
}
|
||||||
|
|
||||||
|
err := errors.Join(errs...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = getUserDefaults(flags, &set.Defaults, all)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if all {
|
||||||
|
set.AuthMethod, auther, err = getAuthentication(flags)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return auther, nil
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,19 +13,19 @@ var configCatCmd = &cobra.Command{
|
||||||
Short: "Prints the configuration",
|
Short: "Prints the configuration",
|
||||||
Long: `Prints the configuration.`,
|
Long: `Prints the configuration.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: python(func(_ *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, _ []string, st *store) error {
|
||||||
set, err := d.store.Settings.Get()
|
set, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ser, err := d.store.Settings.GetServer()
|
ser, err := st.Settings.GetServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
auther, err := d.store.Auth.Get(set.AuthMethod)
|
auther, err := st.Auth.Get(set.AuthMethod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return printSettings(ser, set, auther)
|
return printSettings(ser, set, auther)
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -15,18 +15,18 @@ var configExportCmd = &cobra.Command{
|
||||||
json or yaml file. This exported configuration can be changed,
|
json or yaml file. This exported configuration can be changed,
|
||||||
and imported again with 'config import' command.`,
|
and imported again with 'config import' command.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
settings, err := d.store.Settings.Get()
|
settings, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := d.store.Settings.GetServer()
|
server, err := st.Settings.GetServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
auther, err := d.store.Auth.Get(settings.AuthMethod)
|
auther, err := st.Auth.Get(settings.AuthMethod)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -42,5 +42,5 @@ and imported again with 'config import' command.`,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -34,11 +34,11 @@ database.
|
||||||
|
|
||||||
The path must be for a json or yaml file.`,
|
The path must be for a json or yaml file.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
var key []byte
|
var key []byte
|
||||||
var err error
|
var err error
|
||||||
if d.hadDB {
|
if st.databaseExisted {
|
||||||
settings, settingErr := d.store.Settings.Get()
|
settings, settingErr := st.Settings.Get()
|
||||||
if settingErr != nil {
|
if settingErr != nil {
|
||||||
return settingErr
|
return settingErr
|
||||||
}
|
}
|
||||||
|
|
@ -53,13 +53,17 @@ The path must be for a json or yaml file.`,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if file.Settings == nil || file.Server == nil {
|
||||||
|
return errors.New("invalid configuration file: 'settings' or 'server' fields are missing. Please ensure you are importing a file generated by the 'config export' command")
|
||||||
|
}
|
||||||
|
|
||||||
file.Settings.Key = key
|
file.Settings.Key = key
|
||||||
err = d.store.Settings.Save(file.Settings)
|
err = st.Settings.Save(file.Settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Settings.SaveServer(file.Server)
|
err = st.Settings.SaveServer(file.Server)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -98,13 +102,13 @@ The path must be for a json or yaml file.`,
|
||||||
return autherErr
|
return autherErr
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Auth.Save(auther)
|
err = st.Auth.Save(auther)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return printSettings(file.Server, file.Settings, auther)
|
return printSettings(file.Server, file.Settings, auther)
|
||||||
}, pythonConfig{allowNoDB: true}),
|
}, storeOptions{allowsNoDatabase: true}),
|
||||||
}
|
}
|
||||||
|
|
||||||
func getAuther(sample auth.Auther, data interface{}) (interface{}, error) {
|
func getAuther(sample auth.Auther, data interface{}) (interface{}, error) {
|
||||||
|
|
|
||||||
|
|
@ -22,152 +22,31 @@ this options can be changed in the future with the command
|
||||||
to the defaults when creating new users and you don't
|
to the defaults when creating new users and you don't
|
||||||
override the options.`,
|
override the options.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
|
||||||
defaults := settings.UserDefaults{}
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
err := getUserDefaults(flags, &defaults, true)
|
|
||||||
if err != nil {
|
// Initialize config
|
||||||
return err
|
s := &settings.Settings{Key: generateKey()}
|
||||||
}
|
ser := &settings.Server{}
|
||||||
authMethod, auther, err := getAuthentication(flags)
|
|
||||||
|
// Fill config with options
|
||||||
|
auther, err := getSettings(flags, s, ser, nil, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
key := generateKey()
|
// Save updated config
|
||||||
|
err = st.Settings.Save(s)
|
||||||
signup, err := getBool(flags, "signup")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
createUserDir, err := getBool(flags, "create-user-dir")
|
err = st.Settings.SaveServer(ser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
minLength, err := getUint(flags, "minimum-password-length")
|
err = st.Auth.Save(auther)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
shell, err := getString(flags, "shell")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
brandingName, err := getString(flags, "branding.name")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
brandingDisableExternal, err := getBool(flags, "branding.disableExternal")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
brandingDisableUsedPercentage, err := getBool(flags, "branding.disableUsedPercentage")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
brandingTheme, err := getString(flags, "branding.theme")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
brandingFiles, err := getString(flags, "branding.files")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
s := &settings.Settings{
|
|
||||||
Key: key,
|
|
||||||
Signup: signup,
|
|
||||||
CreateUserDir: createUserDir,
|
|
||||||
MinimumPasswordLength: minLength,
|
|
||||||
Shell: convertCmdStrToCmdArray(shell),
|
|
||||||
AuthMethod: authMethod,
|
|
||||||
Defaults: defaults,
|
|
||||||
Branding: settings.Branding{
|
|
||||||
Name: brandingName,
|
|
||||||
DisableExternal: brandingDisableExternal,
|
|
||||||
DisableUsedPercentage: brandingDisableUsedPercentage,
|
|
||||||
Theme: brandingTheme,
|
|
||||||
Files: brandingFiles,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
s.FileMode, err = getMode(flags, "file-mode")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
s.DirMode, err = getMode(flags, "dir-mode")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
address, err := getString(flags, "address")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
socket, err := getString(flags, "socket")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
root, err := getString(flags, "root")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
baseURL, err := getString(flags, "baseurl")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
tlsKey, err := getString(flags, "key")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
cert, err := getString(flags, "cert")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
port, err := getString(flags, "port")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log, err := getString(flags, "log")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
ser := &settings.Server{
|
|
||||||
Address: address,
|
|
||||||
Socket: socket,
|
|
||||||
Root: root,
|
|
||||||
BaseURL: baseURL,
|
|
||||||
TLSKey: tlsKey,
|
|
||||||
TLSCert: cert,
|
|
||||||
Port: port,
|
|
||||||
Log: log,
|
|
||||||
}
|
|
||||||
|
|
||||||
err = d.store.Settings.Save(s)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = d.store.Settings.SaveServer(ser)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = d.store.Auth.Save(auther)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -178,5 +57,5 @@ Now add your first user via 'filebrowser users add' and then you just
|
||||||
need to call the main command to boot up the server.
|
need to call the main command to boot up the server.
|
||||||
`)
|
`)
|
||||||
return printSettings(ser, s, auther)
|
return printSettings(ser, s, auther)
|
||||||
}, pythonConfig{noDB: true}),
|
}, storeOptions{expectsNoDatabase: true}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
|
@ -16,105 +15,47 @@ var configSetCmd = &cobra.Command{
|
||||||
Long: `Updates the configuration. Set the flags for the options
|
Long: `Updates the configuration. Set the flags for the options
|
||||||
you want to change. Other options will remain unchanged.`,
|
you want to change. Other options will remain unchanged.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
set, err := d.store.Settings.Get()
|
|
||||||
|
// Read existing config
|
||||||
|
set, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ser, err := d.store.Settings.GetServer()
|
ser, err := st.Settings.GetServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
hasAuth := false
|
auther, err := st.Auth.Get(set.AuthMethod)
|
||||||
flags.Visit(func(flag *pflag.Flag) {
|
|
||||||
if err != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
switch flag.Name {
|
|
||||||
case "baseurl":
|
|
||||||
ser.BaseURL, err = getString(flags, flag.Name)
|
|
||||||
case "root":
|
|
||||||
ser.Root, err = getString(flags, flag.Name)
|
|
||||||
case "socket":
|
|
||||||
ser.Socket, err = getString(flags, flag.Name)
|
|
||||||
case "cert":
|
|
||||||
ser.TLSCert, err = getString(flags, flag.Name)
|
|
||||||
case "key":
|
|
||||||
ser.TLSKey, err = getString(flags, flag.Name)
|
|
||||||
case "address":
|
|
||||||
ser.Address, err = getString(flags, flag.Name)
|
|
||||||
case "port":
|
|
||||||
ser.Port, err = getString(flags, flag.Name)
|
|
||||||
case "log":
|
|
||||||
ser.Log, err = getString(flags, flag.Name)
|
|
||||||
case "signup":
|
|
||||||
set.Signup, err = getBool(flags, flag.Name)
|
|
||||||
case "auth.method":
|
|
||||||
hasAuth = true
|
|
||||||
case "shell":
|
|
||||||
var shell string
|
|
||||||
shell, err = getString(flags, flag.Name)
|
|
||||||
set.Shell = convertCmdStrToCmdArray(shell)
|
|
||||||
case "create-user-dir":
|
|
||||||
set.CreateUserDir, err = getBool(flags, flag.Name)
|
|
||||||
case "minimum-password-length":
|
|
||||||
set.MinimumPasswordLength, err = getUint(flags, flag.Name)
|
|
||||||
case "branding.name":
|
|
||||||
set.Branding.Name, err = getString(flags, flag.Name)
|
|
||||||
case "branding.color":
|
|
||||||
set.Branding.Color, err = getString(flags, flag.Name)
|
|
||||||
case "branding.theme":
|
|
||||||
set.Branding.Theme, err = getString(flags, flag.Name)
|
|
||||||
case "branding.disableExternal":
|
|
||||||
set.Branding.DisableExternal, err = getBool(flags, flag.Name)
|
|
||||||
case "branding.disableUsedPercentage":
|
|
||||||
set.Branding.DisableUsedPercentage, err = getBool(flags, flag.Name)
|
|
||||||
case "branding.files":
|
|
||||||
set.Branding.Files, err = getString(flags, flag.Name)
|
|
||||||
case "file-mode":
|
|
||||||
set.FileMode, err = getMode(flags, flag.Name)
|
|
||||||
case "dir-mode":
|
|
||||||
set.DirMode, err = getMode(flags, flag.Name)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = getUserDefaults(flags, &set.Defaults, false)
|
// Get updated config
|
||||||
|
auther, err = getSettings(flags, set, ser, auther, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// read the defaults
|
// Save updated config
|
||||||
auther, err := d.store.Auth.Get(set.AuthMethod)
|
err = st.Auth.Save(auther)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there are new flags for existing auth method
|
err = st.Settings.Save(set)
|
||||||
set.AuthMethod, auther, err = getAuthentication(flags, hasAuth, set, auther)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Auth.Save(auther)
|
err = st.Settings.SaveServer(ser)
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = d.store.Settings.Save(set)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = d.store.Settings.SaveServer(ser)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return printSettings(ser, set, auther)
|
return printSettings(ser, set, auther)
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
158
cmd/docs.go
158
cmd/docs.go
|
|
@ -3,36 +3,18 @@ package cmd
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path"
|
||||||
"sort"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/cobra/doc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
rootCmd.AddCommand(docsCmd)
|
rootCmd.AddCommand(docsCmd)
|
||||||
docsCmd.Flags().StringP("path", "p", "./docs", "path to save the docs")
|
docsCmd.Flags().String("out", "www/docs/cli", "directory to write the docs to")
|
||||||
}
|
|
||||||
|
|
||||||
func printToc(names []string) {
|
|
||||||
for i, name := range names {
|
|
||||||
name = strings.TrimSuffix(name, filepath.Ext(name))
|
|
||||||
name = strings.Replace(name, "-", " ", -1)
|
|
||||||
names[i] = name
|
|
||||||
}
|
|
||||||
|
|
||||||
sort.Strings(names)
|
|
||||||
|
|
||||||
toc := ""
|
|
||||||
for _, name := range names {
|
|
||||||
toc += "* [" + name + "](cli/" + strings.Replace(name, " ", "-", -1) + ".md)\n"
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Println(toc)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var docsCmd = &cobra.Command{
|
var docsCmd = &cobra.Command{
|
||||||
|
|
@ -40,115 +22,61 @@ var docsCmd = &cobra.Command{
|
||||||
Hidden: true,
|
Hidden: true,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
RunE: func(cmd *cobra.Command, _ []string) error {
|
||||||
dir, err := getString(cmd.Flags(), "path")
|
outputDir, err := cmd.Flags().GetString("out")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = generateDocs(rootCmd, dir)
|
tempDir, err := os.MkdirTemp(os.TempDir(), "filebrowser-docs-")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
names := []string{}
|
defer os.RemoveAll(tempDir)
|
||||||
|
|
||||||
err = filepath.Walk(dir, func(_ string, info os.FileInfo, err error) error {
|
rootCmd.Root().DisableAutoGenTag = true
|
||||||
if err != nil || info.IsDir() {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
if !strings.HasPrefix(info.Name(), "filebrowser") {
|
err = doc.GenMarkdownTreeCustom(cmd.Root(), tempDir, func(_ string) string {
|
||||||
return nil
|
return ""
|
||||||
}
|
}, func(s string) string {
|
||||||
|
return s
|
||||||
names = append(names, info.Name())
|
|
||||||
return nil
|
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
printToc(names)
|
entries, err := os.ReadDir(tempDir)
|
||||||
return nil
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateDocs(cmd *cobra.Command, dir string) error {
|
|
||||||
for _, c := range cmd.Commands() {
|
|
||||||
if !c.IsAvailableCommand() || c.IsAdditionalHelpTopicCommand() {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
err := generateDocs(c, dir)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
basename := strings.Replace(cmd.CommandPath(), " ", "-", -1) + ".md"
|
headerRegex := regexp.MustCompile(`(?m)^(##)(.*)$`)
|
||||||
filename := filepath.Join(dir, basename)
|
linkRegex := regexp.MustCompile(`\(filebrowser(.*)\.md\)`)
|
||||||
f, err := os.Create(filename)
|
|
||||||
if err != nil {
|
fmt.Println("Generated Documents:")
|
||||||
return err
|
|
||||||
}
|
for _, entry := range entries {
|
||||||
defer f.Close()
|
srcPath := path.Join(tempDir, entry.Name())
|
||||||
return generateMarkdown(cmd, f)
|
dstPath := path.Join(outputDir, strings.ReplaceAll(entry.Name(), "_", "-"))
|
||||||
}
|
|
||||||
|
data, err := os.ReadFile(srcPath)
|
||||||
func generateMarkdown(cmd *cobra.Command, w io.Writer) error {
|
if err != nil {
|
||||||
cmd.InitDefaultHelpCmd()
|
return err
|
||||||
cmd.InitDefaultHelpFlag()
|
}
|
||||||
|
|
||||||
buf := new(bytes.Buffer)
|
data = headerRegex.ReplaceAll(data, []byte("#$2"))
|
||||||
name := cmd.CommandPath()
|
data = linkRegex.ReplaceAllFunc(data, func(b []byte) []byte {
|
||||||
|
return bytes.ReplaceAll(b, []byte("_"), []byte("-"))
|
||||||
short := cmd.Short
|
})
|
||||||
long := cmd.Long
|
data = bytes.ReplaceAll(data, []byte("## SEE ALSO"), []byte("## See Also"))
|
||||||
if long == "" {
|
|
||||||
long = short
|
err = os.WriteFile(dstPath, data, 0666)
|
||||||
}
|
if err != nil {
|
||||||
|
return err
|
||||||
buf.WriteString("---\ndescription: " + short + "\n---\n\n")
|
}
|
||||||
buf.WriteString("# " + name + "\n\n")
|
|
||||||
buf.WriteString("## Synopsis\n\n")
|
fmt.Println("- " + dstPath)
|
||||||
buf.WriteString(long + "\n\n")
|
}
|
||||||
|
|
||||||
if cmd.Runnable() {
|
return nil
|
||||||
_, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.UseLine())
|
},
|
||||||
}
|
|
||||||
|
|
||||||
if cmd.Example != "" {
|
|
||||||
buf.WriteString("## Examples\n\n")
|
|
||||||
_, _ = fmt.Fprintf(buf, "```\n%s\n```\n\n", cmd.Example)
|
|
||||||
}
|
|
||||||
|
|
||||||
printOptions(buf, cmd)
|
|
||||||
_, err := buf.WriteTo(w)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateFlagsTable(fs *pflag.FlagSet, buf io.StringWriter) {
|
|
||||||
_, _ = buf.WriteString("| Name | Shorthand | Usage |\n")
|
|
||||||
_, _ = buf.WriteString("|------|-----------|-------|\n")
|
|
||||||
|
|
||||||
fs.VisitAll(func(f *pflag.Flag) {
|
|
||||||
_, _ = buf.WriteString("|" + f.Name + "|" + f.Shorthand + "|" + f.Usage + "|\n")
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func printOptions(buf *bytes.Buffer, cmd *cobra.Command) {
|
|
||||||
flags := cmd.NonInheritedFlags()
|
|
||||||
flags.SetOutput(buf)
|
|
||||||
if flags.HasAvailableFlags() {
|
|
||||||
buf.WriteString("## Options\n\n")
|
|
||||||
generateFlagsTable(flags, buf)
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
parentFlags := cmd.InheritedFlags()
|
|
||||||
parentFlags.SetOutput(buf)
|
|
||||||
if parentFlags.HasAvailableFlags() {
|
|
||||||
buf.WriteString("### Inherited\n\n")
|
|
||||||
generateFlagsTable(parentFlags, buf)
|
|
||||||
buf.WriteString("\n")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
396
cmd/root.go
396
cmd/root.go
|
|
@ -13,20 +13,17 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
homedir "github.com/mitchellh/go-homedir"
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
v "github.com/spf13/viper"
|
"github.com/spf13/viper"
|
||||||
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/auth"
|
"github.com/filebrowser/filebrowser/v2/auth"
|
||||||
"github.com/filebrowser/filebrowser/v2/diskcache"
|
"github.com/filebrowser/filebrowser/v2/diskcache"
|
||||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
|
||||||
"github.com/filebrowser/filebrowser/v2/frontend"
|
"github.com/filebrowser/filebrowser/v2/frontend"
|
||||||
fbhttp "github.com/filebrowser/filebrowser/v2/http"
|
fbhttp "github.com/filebrowser/filebrowser/v2/http"
|
||||||
"github.com/filebrowser/filebrowser/v2/img"
|
"github.com/filebrowser/filebrowser/v2/img"
|
||||||
|
|
@ -36,28 +33,67 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
cfgFile string
|
flagNamesMigrations = map[string]string{
|
||||||
|
"file-mode": "fileMode",
|
||||||
|
"dir-mode": "dirMode",
|
||||||
|
"hide-login-button": "hideLoginButton",
|
||||||
|
"create-user-dir": "createUserDir",
|
||||||
|
"minimum-password-length": "minimumPasswordLength",
|
||||||
|
"socket-perm": "socketPerm",
|
||||||
|
"disable-thumbnails": "disableThumbnails",
|
||||||
|
"disable-preview-resize": "disablePreviewResize",
|
||||||
|
"disable-exec": "disableExec",
|
||||||
|
"disable-type-detection-by-header": "disableTypeDetectionByHeader",
|
||||||
|
"img-processors": "imageProcessors",
|
||||||
|
"cache-dir": "cacheDir",
|
||||||
|
"token-expiration-time": "tokenExpirationTime",
|
||||||
|
"baseurl": "baseURL",
|
||||||
|
}
|
||||||
|
|
||||||
|
warnedFlags = map[string]bool{}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// TODO(remove): remove after July 2026.
|
||||||
|
func migrateFlagNames(_ *pflag.FlagSet, name string) pflag.NormalizedName {
|
||||||
|
if newName, ok := flagNamesMigrations[name]; ok {
|
||||||
|
|
||||||
|
if !warnedFlags[name] {
|
||||||
|
warnedFlags[name] = true
|
||||||
|
log.Printf("DEPRECATION NOTICE: Flag --%s has been deprecated, use --%s instead\n", name, newName)
|
||||||
|
}
|
||||||
|
|
||||||
|
name = newName
|
||||||
|
}
|
||||||
|
|
||||||
|
return pflag.NormalizedName(name)
|
||||||
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
cobra.OnInitialize(initConfig)
|
|
||||||
rootCmd.SilenceUsage = true
|
rootCmd.SilenceUsage = true
|
||||||
|
rootCmd.SetGlobalNormalizationFunc(migrateFlagNames)
|
||||||
|
|
||||||
cobra.MousetrapHelpText = ""
|
cobra.MousetrapHelpText = ""
|
||||||
|
|
||||||
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
||||||
|
|
||||||
flags := rootCmd.Flags()
|
// Flags available across the whole program
|
||||||
persistent := rootCmd.PersistentFlags()
|
persistent := rootCmd.PersistentFlags()
|
||||||
|
persistent.StringP("config", "c", "", "config file path")
|
||||||
persistent.StringVarP(&cfgFile, "config", "c", "", "config file path")
|
|
||||||
persistent.StringP("database", "d", "./filebrowser.db", "database path")
|
persistent.StringP("database", "d", "./filebrowser.db", "database path")
|
||||||
flags.Bool("noauth", false, "use the noauth auther when using quick setup")
|
|
||||||
flags.String("username", "admin", "username for the first user when using quick config")
|
|
||||||
flags.String("password", "", "hashed password for the first user when using quick config")
|
|
||||||
|
|
||||||
|
// Runtime flags for the root command
|
||||||
|
flags := rootCmd.Flags()
|
||||||
|
flags.Bool("noauth", false, "use the noauth auther when using quick setup")
|
||||||
|
flags.String("username", "admin", "username for the first user when using quick setup")
|
||||||
|
flags.String("password", "", "hashed password for the first user when using quick setup")
|
||||||
|
flags.Uint32("socketPerm", 0666, "unix socket file permissions")
|
||||||
|
flags.String("cacheDir", "", "file cache directory (disabled if empty)")
|
||||||
|
flags.Int("imageProcessors", 4, "image processors count")
|
||||||
addServerFlags(flags)
|
addServerFlags(flags)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// addServerFlags adds server related flags to the given FlagSet. These flags are available
|
||||||
|
// in both the root command, config set and config init commands.
|
||||||
func addServerFlags(flags *pflag.FlagSet) {
|
func addServerFlags(flags *pflag.FlagSet) {
|
||||||
flags.StringP("address", "a", "127.0.0.1", "address to listen on")
|
flags.StringP("address", "a", "127.0.0.1", "address to listen on")
|
||||||
flags.StringP("log", "l", "stdout", "log output")
|
flags.StringP("log", "l", "stdout", "log output")
|
||||||
|
|
@ -66,15 +102,13 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||||
flags.StringP("key", "k", "", "tls key")
|
flags.StringP("key", "k", "", "tls key")
|
||||||
flags.StringP("root", "r", ".", "root to prepend to relative paths")
|
flags.StringP("root", "r", ".", "root to prepend to relative paths")
|
||||||
flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
|
flags.String("socket", "", "socket to listen to (cannot be used with address, port, cert nor key flags)")
|
||||||
flags.Uint32("socket-perm", 0666, "unix socket file permissions")
|
flags.StringP("baseURL", "b", "", "base url")
|
||||||
flags.StringP("baseurl", "b", "", "base url")
|
flags.String("tokenExpirationTime", "2h", "user session timeout")
|
||||||
flags.String("cache-dir", "", "file cache directory (disabled if empty)")
|
flags.Bool("disableThumbnails", false, "disable image thumbnails")
|
||||||
flags.String("token-expiration-time", "2h", "user session timeout")
|
flags.Bool("disablePreviewResize", false, "disable resize of image previews")
|
||||||
flags.Int("img-processors", 4, "image processors count") //nolint:mnd
|
flags.Bool("disableExec", true, "disables Command Runner feature")
|
||||||
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
|
flags.Bool("disableTypeDetectionByHeader", false, "disables type detection by reading file headers")
|
||||||
flags.Bool("disable-preview-resize", false, "disable resize of image previews")
|
flags.Bool("disableImageResolutionCalc", false, "disables image resolution calculation by reading image files")
|
||||||
flags.Bool("disable-exec", true, "disables Command Runner feature")
|
|
||||||
flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var rootCmd = &cobra.Command{
|
var rootCmd = &cobra.Command{
|
||||||
|
|
@ -89,65 +123,60 @@ it. Don't worry: you don't need to setup a separate database server.
|
||||||
We're using Bolt DB which is a single file database and all managed
|
We're using Bolt DB which is a single file database and all managed
|
||||||
by ourselves.
|
by ourselves.
|
||||||
|
|
||||||
For this specific command, all the flags you have available (except
|
For this command, all flags are available as environmental variables,
|
||||||
"config" for the configuration file), can be given either through
|
except for "--config", which specifies the configuration file to use.
|
||||||
environment variables or configuration files.
|
The environment variables are prefixed by "FB_" followed by the flag name in
|
||||||
|
UPPER_SNAKE_CASE. For example, the flag "--disablePreviewResize" is available
|
||||||
|
as FB_DISABLE_PREVIEW_RESIZE.
|
||||||
|
|
||||||
If you don't set "config", it will look for a configuration file called
|
If "--config" is not specified, File Browser will look for a configuration
|
||||||
.filebrowser.{json, toml, yaml, yml} in the following directories:
|
file named .filebrowser.{json, toml, yaml, yml} in the following directories:
|
||||||
|
|
||||||
- ./
|
- ./
|
||||||
- $HOME/
|
- $HOME/
|
||||||
- /etc/filebrowser/
|
- /etc/filebrowser/
|
||||||
|
|
||||||
|
**Note:** Only the options listed below can be set via the config file or
|
||||||
|
environment variables. Other configuration options live exclusively in the
|
||||||
|
database and so they must be set by the "config set" or "config
|
||||||
|
import" commands.
|
||||||
|
|
||||||
The precedence of the configuration values are as follows:
|
The precedence of the configuration values are as follows:
|
||||||
|
|
||||||
- flags
|
- Flags
|
||||||
- environment variables
|
- Environment variables
|
||||||
- configuration file
|
- Configuration file
|
||||||
- database values
|
- Database values
|
||||||
- defaults
|
- Defaults
|
||||||
|
|
||||||
The environment variables are prefixed by "FB_" followed by the option
|
|
||||||
name in caps. So to set "database" via an env variable, you should
|
|
||||||
set FB_DATABASE.
|
|
||||||
|
|
||||||
Also, if the database path doesn't exist, File Browser will enter into
|
Also, if the database path doesn't exist, File Browser will enter into
|
||||||
the quick setup mode and a new database will be bootstrapped and a new
|
the quick setup mode and a new database will be bootstrapped and a new
|
||||||
user created with the credentials from options "username" and "password".`,
|
user created with the credentials from options "username" and "password".`,
|
||||||
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withViperAndStore(func(_ *cobra.Command, _ []string, v *viper.Viper, st *store) error {
|
||||||
log.Println(cfgFile)
|
if !st.databaseExisted {
|
||||||
|
err := quickSetup(v, st.Storage)
|
||||||
if !d.hadDB {
|
|
||||||
err := quickSetup(cmd.Flags(), *d)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// build img service
|
// build img service
|
||||||
workersCount, err := cmd.Flags().GetInt("img-processors")
|
imgWorkersCount := v.GetInt("imageProcessors")
|
||||||
if err != nil {
|
if imgWorkersCount < 1 {
|
||||||
return err
|
|
||||||
}
|
|
||||||
if workersCount < 1 {
|
|
||||||
return errors.New("image resize workers count could not be < 1")
|
return errors.New("image resize workers count could not be < 1")
|
||||||
}
|
}
|
||||||
imgSvc := img.New(workersCount)
|
imageService := img.New(imgWorkersCount)
|
||||||
|
|
||||||
var fileCache diskcache.Interface = diskcache.NewNoOp()
|
var fileCache diskcache.Interface = diskcache.NewNoOp()
|
||||||
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
cacheDir := v.GetString("cacheDir")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if cacheDir != "" {
|
if cacheDir != "" {
|
||||||
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
|
if err := os.MkdirAll(cacheDir, 0700); err != nil {
|
||||||
return fmt.Errorf("can't make directory %s: %w", cacheDir, err)
|
return fmt.Errorf("can't make directory %s: %w", cacheDir, err)
|
||||||
}
|
}
|
||||||
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
server, err := getRunParams(cmd.Flags(), d.store)
|
server, err := getServerSettings(v, st.Storage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -169,16 +198,13 @@ user created with the credentials from options "username" and "password".`,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
|
socketPerm := v.GetUint32("socketPerm")
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
|
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
case server.TLSKey != "" && server.TLSCert != "":
|
case server.TLSKey != "" && server.TLSCert != "":
|
||||||
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
|
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -201,7 +227,7 @@ user created with the credentials from options "username" and "password".`,
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs)
|
handler, err := fbhttp.NewHandler(imageService, fileCache, st.Storage, server, assetsFs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -233,7 +259,7 @@ user created with the credentials from options "username" and "password".`,
|
||||||
sig := <-sigc
|
sig := <-sigc
|
||||||
log.Println("Got signal:", sig)
|
log.Println("Got signal:", sig)
|
||||||
|
|
||||||
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second) //nolint:mnd
|
shutdownCtx, shutdownRelease := context.WithTimeout(context.Background(), 10*time.Second)
|
||||||
defer shutdownRelease()
|
defer shutdownRelease()
|
||||||
|
|
||||||
if err := srv.Shutdown(shutdownCtx); err != nil {
|
if err := srv.Shutdown(shutdownCtx); err != nil {
|
||||||
|
|
@ -241,66 +267,82 @@ user created with the credentials from options "username" and "password".`,
|
||||||
}
|
}
|
||||||
log.Println("Graceful shutdown complete.")
|
log.Println("Graceful shutdown complete.")
|
||||||
|
|
||||||
switch sig {
|
return nil
|
||||||
case syscall.SIGHUP:
|
}, storeOptions{allowsNoDatabase: true}),
|
||||||
d.err = fbErrors.ErrSighup
|
|
||||||
case syscall.SIGINT:
|
|
||||||
d.err = fbErrors.ErrSigint
|
|
||||||
case syscall.SIGQUIT:
|
|
||||||
d.err = fbErrors.ErrSigquit
|
|
||||||
case syscall.SIGTERM:
|
|
||||||
d.err = fbErrors.ErrSigTerm
|
|
||||||
}
|
|
||||||
|
|
||||||
return d.err
|
|
||||||
}, pythonConfig{allowNoDB: true}),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
func getServerSettings(v *viper.Viper, st *storage.Storage) (*settings.Server, error) {
|
||||||
func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server, error) {
|
|
||||||
server, err := st.Settings.GetServer()
|
server, err := st.Settings.GetServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "root"); set {
|
|
||||||
server.Root = val
|
|
||||||
}
|
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "baseurl"); set {
|
|
||||||
server.BaseURL = val
|
|
||||||
}
|
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "log"); set {
|
|
||||||
server.Log = val
|
|
||||||
}
|
|
||||||
|
|
||||||
isSocketSet := false
|
isSocketSet := false
|
||||||
isAddrSet := false
|
isAddrSet := false
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "address"); set {
|
if v.IsSet("address") {
|
||||||
server.Address = val
|
server.Address = v.GetString("address")
|
||||||
isAddrSet = isAddrSet || set
|
isAddrSet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "port"); set {
|
if v.IsSet("log") {
|
||||||
server.Port = val
|
server.Log = v.GetString("log")
|
||||||
isAddrSet = isAddrSet || set
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "key"); set {
|
if v.IsSet("port") {
|
||||||
server.TLSKey = val
|
server.Port = v.GetString("port")
|
||||||
isAddrSet = isAddrSet || set
|
isAddrSet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "cert"); set {
|
if v.IsSet("cert") {
|
||||||
server.TLSCert = val
|
server.TLSCert = v.GetString("cert")
|
||||||
isAddrSet = isAddrSet || set
|
isAddrSet = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "socket"); set {
|
if v.IsSet("key") {
|
||||||
server.Socket = val
|
server.TLSKey = v.GetString("key")
|
||||||
isSocketSet = isSocketSet || set
|
isAddrSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("root") {
|
||||||
|
server.Root = v.GetString("root")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("socket") {
|
||||||
|
server.Socket = v.GetString("socket")
|
||||||
|
isSocketSet = true
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("baseURL") {
|
||||||
|
server.BaseURL = v.GetString("baseURL")
|
||||||
|
// TODO(remove): remove after July 2026.
|
||||||
|
} else if v := os.Getenv("FB_BASEURL"); v != "" {
|
||||||
|
log.Println("DEPRECATION NOTICE: Environment variable FB_BASEURL has been deprecated, use FB_BASE_URL instead")
|
||||||
|
server.BaseURL = v
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("tokenExpirationTime") {
|
||||||
|
server.TokenExpirationTime = v.GetString("tokenExpirationTime")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("disableThumbnails") {
|
||||||
|
server.EnableThumbnails = !v.GetBool("disableThumbnails")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("disablePreviewResize") {
|
||||||
|
server.ResizePreview = !v.GetBool("disablePreviewResize")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("disableTypeDetectionByHeader") {
|
||||||
|
server.TypeDetectionByHeader = !v.GetBool("disableTypeDetectionByHeader")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("disableImageResolutionCalc") {
|
||||||
|
server.ImageResolutionCal = !v.GetBool("disableImageResolutionCalc")
|
||||||
|
}
|
||||||
|
|
||||||
|
if v.IsSet("disableExec") {
|
||||||
|
server.EnableExec = !v.GetBool("disableExec")
|
||||||
}
|
}
|
||||||
|
|
||||||
if isAddrSet && isSocketSet {
|
if isAddrSet && isSocketSet {
|
||||||
|
|
@ -312,18 +354,6 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server,
|
||||||
server.Socket = ""
|
server.Socket = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
disableThumbnails := getBoolParam(flags, "disable-thumbnails")
|
|
||||||
server.EnableThumbnails = !disableThumbnails
|
|
||||||
|
|
||||||
disablePreviewResize := getBoolParam(flags, "disable-preview-resize")
|
|
||||||
server.ResizePreview = !disablePreviewResize
|
|
||||||
|
|
||||||
disableTypeDetectionByHeader := getBoolParam(flags, "disable-type-detection-by-header")
|
|
||||||
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
|
|
||||||
|
|
||||||
disableExec := getBoolParam(flags, "disable-exec")
|
|
||||||
server.EnableExec = !disableExec
|
|
||||||
|
|
||||||
if server.EnableExec {
|
if server.EnableExec {
|
||||||
log.Println("WARNING: Command Runner feature enabled!")
|
log.Println("WARNING: Command Runner feature enabled!")
|
||||||
log.Println("WARNING: This feature has known security vulnerabilities and should not")
|
log.Println("WARNING: This feature has known security vulnerabilities and should not")
|
||||||
|
|
@ -331,71 +361,9 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) (*settings.Server,
|
||||||
log.Println("WARNING: read https://github.com/filebrowser/filebrowser/issues/5199")
|
log.Println("WARNING: read https://github.com/filebrowser/filebrowser/issues/5199")
|
||||||
}
|
}
|
||||||
|
|
||||||
if val, set := getStringParamB(flags, "token-expiration-time"); set {
|
|
||||||
server.TokenExpirationTime = val
|
|
||||||
}
|
|
||||||
|
|
||||||
return server, nil
|
return server, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getBoolParamB returns a parameter as a string and a boolean to tell if it is different from the default
|
|
||||||
//
|
|
||||||
// NOTE: we could simply bind the flags to viper and use IsSet.
|
|
||||||
// Although there is a bug on Viper that always returns true on IsSet
|
|
||||||
// if a flag is binded. Our alternative way is to manually check
|
|
||||||
// the flag and then the value from env/config/gotten by viper.
|
|
||||||
// https://github.com/spf13/viper/pull/331
|
|
||||||
func getBoolParamB(flags *pflag.FlagSet, key string) (value, ok bool) {
|
|
||||||
value, _ = flags.GetBool(key)
|
|
||||||
|
|
||||||
// If set on Flags, use it.
|
|
||||||
if flags.Changed(key) {
|
|
||||||
return value, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If set through viper (env, config), return it.
|
|
||||||
if v.IsSet(key) {
|
|
||||||
return v.GetBool(key), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise use default value on flags.
|
|
||||||
return value, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func getBoolParam(flags *pflag.FlagSet, key string) bool {
|
|
||||||
val, _ := getBoolParamB(flags, key)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
// getStringParamB returns a parameter as a string and a boolean to tell if it is different from the default
|
|
||||||
//
|
|
||||||
// NOTE: we could simply bind the flags to viper and use IsSet.
|
|
||||||
// Although there is a bug on Viper that always returns true on IsSet
|
|
||||||
// if a flag is binded. Our alternative way is to manually check
|
|
||||||
// the flag and then the value from env/config/gotten by viper.
|
|
||||||
// https://github.com/spf13/viper/pull/331
|
|
||||||
func getStringParamB(flags *pflag.FlagSet, key string) (string, bool) {
|
|
||||||
value, _ := flags.GetString(key)
|
|
||||||
|
|
||||||
// If set on Flags, use it.
|
|
||||||
if flags.Changed(key) {
|
|
||||||
return value, true
|
|
||||||
}
|
|
||||||
|
|
||||||
// If set through viper (env, config), return it.
|
|
||||||
if v.IsSet(key) {
|
|
||||||
return v.GetString(key), true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise use default value on flags.
|
|
||||||
return value, false
|
|
||||||
}
|
|
||||||
|
|
||||||
func getStringParam(flags *pflag.FlagSet, key string) string {
|
|
||||||
val, _ := getStringParamB(flags, key)
|
|
||||||
return val
|
|
||||||
}
|
|
||||||
|
|
||||||
func setupLog(logMethod string) {
|
func setupLog(logMethod string) {
|
||||||
switch logMethod {
|
switch logMethod {
|
||||||
case "stdout":
|
case "stdout":
|
||||||
|
|
@ -414,20 +382,22 @@ func setupLog(logMethod string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func quickSetup(flags *pflag.FlagSet, d pythonData) error {
|
func quickSetup(v *viper.Viper, s *storage.Storage) error {
|
||||||
log.Println("Performing quick setup")
|
log.Println("Performing quick setup")
|
||||||
|
|
||||||
set := &settings.Settings{
|
set := &settings.Settings{
|
||||||
Key: generateKey(),
|
Key: generateKey(),
|
||||||
Signup: false,
|
Signup: false,
|
||||||
|
HideLoginButton: true,
|
||||||
CreateUserDir: false,
|
CreateUserDir: false,
|
||||||
MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
|
MinimumPasswordLength: settings.DefaultMinimumPasswordLength,
|
||||||
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
|
UserHomeBasePath: settings.DefaultUsersHomeBasePath,
|
||||||
Defaults: settings.UserDefaults{
|
Defaults: settings.UserDefaults{
|
||||||
Scope: ".",
|
Scope: ".",
|
||||||
Locale: "en",
|
Locale: "en",
|
||||||
SingleClick: false,
|
SingleClick: false,
|
||||||
AceEditorTheme: getStringParam(flags, "defaults.aceEditorTheme"),
|
RedirectAfterCopyMove: true,
|
||||||
|
AceEditorTheme: v.GetString("defaults.aceEditorTheme"),
|
||||||
Perm: users.Permissions{
|
Perm: users.Permissions{
|
||||||
Admin: false,
|
Admin: false,
|
||||||
Execute: true,
|
Execute: true,
|
||||||
|
|
@ -451,39 +421,45 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
if _, noauth := getStringParamB(flags, "noauth"); noauth {
|
if v.GetBool("noauth") {
|
||||||
set.AuthMethod = auth.MethodNoAuth
|
set.AuthMethod = auth.MethodNoAuth
|
||||||
err = d.store.Auth.Save(&auth.NoAuth{})
|
err = s.Auth.Save(&auth.NoAuth{})
|
||||||
} else {
|
} else {
|
||||||
set.AuthMethod = auth.MethodJSONAuth
|
set.AuthMethod = auth.MethodJSONAuth
|
||||||
err = d.store.Auth.Save(&auth.JSONAuth{})
|
err = s.Auth.Save(&auth.JSONAuth{})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Settings.Save(set)
|
err = s.Settings.Save(set)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
ser := &settings.Server{
|
ser := &settings.Server{
|
||||||
BaseURL: getStringParam(flags, "baseurl"),
|
BaseURL: v.GetString("baseURL"),
|
||||||
Port: getStringParam(flags, "port"),
|
Port: v.GetString("port"),
|
||||||
Log: getStringParam(flags, "log"),
|
Log: v.GetString("log"),
|
||||||
TLSKey: getStringParam(flags, "key"),
|
TLSKey: v.GetString("key"),
|
||||||
TLSCert: getStringParam(flags, "cert"),
|
TLSCert: v.GetString("cert"),
|
||||||
Address: getStringParam(flags, "address"),
|
Address: v.GetString("address"),
|
||||||
Root: getStringParam(flags, "root"),
|
Root: v.GetString("root"),
|
||||||
|
TokenExpirationTime: v.GetString("tokenExpirationTime"),
|
||||||
|
EnableThumbnails: !v.GetBool("disableThumbnails"),
|
||||||
|
ResizePreview: !v.GetBool("disablePreviewResize"),
|
||||||
|
EnableExec: !v.GetBool("disableExec"),
|
||||||
|
TypeDetectionByHeader: !v.GetBool("disableTypeDetectionByHeader"),
|
||||||
|
ImageResolutionCal: !v.GetBool("disableImageResolutionCalc"),
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Settings.SaveServer(ser)
|
err = s.Settings.SaveServer(ser)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
username := getStringParam(flags, "username")
|
username := v.GetString("username")
|
||||||
password := getStringParam(flags, "password")
|
password := v.GetString("password")
|
||||||
|
|
||||||
if password == "" {
|
if password == "" {
|
||||||
var pwd string
|
var pwd string
|
||||||
|
|
@ -514,35 +490,5 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) error {
|
||||||
set.Defaults.Apply(user)
|
set.Defaults.Apply(user)
|
||||||
user.Perm.Admin = true
|
user.Perm.Admin = true
|
||||||
|
|
||||||
return d.store.Users.Save(user)
|
return s.Users.Save(user)
|
||||||
}
|
|
||||||
|
|
||||||
func initConfig() {
|
|
||||||
if cfgFile == "" {
|
|
||||||
home, err := homedir.Dir()
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
v.AddConfigPath(".")
|
|
||||||
v.AddConfigPath(home)
|
|
||||||
v.AddConfigPath("/etc/filebrowser/")
|
|
||||||
v.SetConfigName(".filebrowser")
|
|
||||||
} else {
|
|
||||||
v.SetConfigFile(cfgFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
v.SetEnvPrefix("FB")
|
|
||||||
v.AutomaticEnv()
|
|
||||||
v.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
|
|
||||||
v.SetEnvKeyReplacer(strings.NewReplacer("-", "_"))
|
|
||||||
|
|
||||||
if err := v.ReadInConfig(); err != nil {
|
|
||||||
var configParseError v.ConfigParseError
|
|
||||||
if errors.As(err, &configParseError) {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
cfgFile = "No config file used"
|
|
||||||
} else {
|
|
||||||
cfgFile = "Using config file: " + v.ConfigFileUsed()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ including 'index_end'.`,
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
|
||||||
i, err := strconv.Atoi(args[0])
|
i, err := strconv.Atoi(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -55,14 +55,14 @@ including 'index_end'.`,
|
||||||
|
|
||||||
user := func(u *users.User) error {
|
user := func(u *users.User) error {
|
||||||
u.Rules = append(u.Rules[:i], u.Rules[f+1:]...)
|
u.Rules = append(u.Rules[:i], u.Rules[f+1:]...)
|
||||||
return d.store.Users.Save(u)
|
return st.Users.Save(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
global := func(s *settings.Settings) error {
|
global := func(s *settings.Settings) error {
|
||||||
s.Rules = append(s.Rules[:i], s.Rules[f+1:]...)
|
s.Rules = append(s.Rules[:i], s.Rules[f+1:]...)
|
||||||
return d.store.Settings.Save(s)
|
return st.Settings.Save(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runRules(d.store, cmd, user, global)
|
return runRules(st.Storage, cmd, user, global)
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,11 +69,12 @@ func runRules(st *storage.Storage, cmd *cobra.Command, usersFn func(*users.User)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) {
|
func getUserIdentifier(flags *pflag.FlagSet) (interface{}, error) {
|
||||||
id, err := getUint(flags, "id")
|
id, err := flags.GetUint("id")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
username, err := getString(flags, "username")
|
|
||||||
|
username, err := flags.GetString("username")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,15 +21,19 @@ var rulesAddCmd = &cobra.Command{
|
||||||
Short: "Add a global rule or user rule",
|
Short: "Add a global rule or user rule",
|
||||||
Long: `Add a global rule or user rule.`,
|
Long: `Add a global rule or user rule.`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
|
||||||
allow, err := getBool(cmd.Flags(), "allow")
|
flags := cmd.Flags()
|
||||||
|
|
||||||
|
allow, err := flags.GetBool("allow")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
regex, err := getBool(cmd.Flags(), "regex")
|
|
||||||
|
regex, err := flags.GetBool("regex")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
exp := args[0]
|
exp := args[0]
|
||||||
|
|
||||||
if regex {
|
if regex {
|
||||||
|
|
@ -49,14 +53,14 @@ var rulesAddCmd = &cobra.Command{
|
||||||
|
|
||||||
user := func(u *users.User) error {
|
user := func(u *users.User) error {
|
||||||
u.Rules = append(u.Rules, rule)
|
u.Rules = append(u.Rules, rule)
|
||||||
return d.store.Users.Save(u)
|
return st.Users.Save(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
global := func(s *settings.Settings) error {
|
global := func(s *settings.Settings) error {
|
||||||
s.Rules = append(s.Rules, rule)
|
s.Rules = append(s.Rules, rule)
|
||||||
return d.store.Settings.Save(s)
|
return st.Settings.Save(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
return runRules(d.store, cmd, user, global)
|
return runRules(st.Storage, cmd, user, global)
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ var rulesLsCommand = &cobra.Command{
|
||||||
Short: "List global rules or user specific rules",
|
Short: "List global rules or user specific rules",
|
||||||
Long: `List global rules or user specific rules.`,
|
Long: `List global rules or user specific rules.`,
|
||||||
Args: cobra.NoArgs,
|
Args: cobra.NoArgs,
|
||||||
RunE: python(func(cmd *cobra.Command, _ []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, _ []string, st *store) error {
|
||||||
return runRules(d.store, cmd, nil, nil)
|
return runRules(st.Storage, cmd, nil, nil)
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +0,0 @@
|
||||||
package cmd
|
|
||||||
|
|
||||||
import (
|
|
||||||
"github.com/spf13/cobra"
|
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/storage/bolt/importer"
|
|
||||||
)
|
|
||||||
|
|
||||||
func init() {
|
|
||||||
rootCmd.AddCommand(upgradeCmd)
|
|
||||||
|
|
||||||
upgradeCmd.Flags().String("old.database", "", "")
|
|
||||||
upgradeCmd.Flags().String("old.config", "", "")
|
|
||||||
_ = upgradeCmd.MarkFlagRequired("old.database")
|
|
||||||
}
|
|
||||||
|
|
||||||
var upgradeCmd = &cobra.Command{
|
|
||||||
Use: "upgrade",
|
|
||||||
Short: "Upgrades an old configuration",
|
|
||||||
Long: `Upgrades an old configuration. This command DOES NOT
|
|
||||||
import share links because they are incompatible with
|
|
||||||
this version.`,
|
|
||||||
Args: cobra.NoArgs,
|
|
||||||
RunE: func(cmd *cobra.Command, _ []string) error {
|
|
||||||
flags := cmd.Flags()
|
|
||||||
oldDB, err := getString(flags, "old.database")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
oldConf, err := getString(flags, "old.config")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
db, err := getString(flags, "database")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return importer.Import(oldDB, oldConf, db)
|
|
||||||
},
|
|
||||||
}
|
|
||||||
57
cmd/users.go
57
cmd/users.go
|
|
@ -30,13 +30,14 @@ func printUsers(usrs []*users.User) {
|
||||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\tS.Click\tAdmin\tExecute\tCreate\tRename\tModify\tDelete\tShare\tDownload\tPwd Lock")
|
||||||
|
|
||||||
for _, u := range usrs {
|
for _, u := range usrs {
|
||||||
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
|
fmt.Fprintf(w, "%d\t%s\t%s\t%s\t%s\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t%t\t\n",
|
||||||
u.ID,
|
u.ID,
|
||||||
u.Username,
|
u.Username,
|
||||||
u.Scope,
|
u.Scope,
|
||||||
u.Locale,
|
u.Locale,
|
||||||
u.ViewMode,
|
u.ViewMode,
|
||||||
u.SingleClick,
|
u.SingleClick,
|
||||||
|
u.RedirectAfterCopyMove,
|
||||||
u.Perm.Admin,
|
u.Perm.Admin,
|
||||||
u.Perm.Execute,
|
u.Perm.Execute,
|
||||||
u.Perm.Create,
|
u.Perm.Create,
|
||||||
|
|
@ -77,67 +78,72 @@ func addUserFlags(flags *pflag.FlagSet) {
|
||||||
flags.String("locale", "en", "locale for users")
|
flags.String("locale", "en", "locale for users")
|
||||||
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
||||||
flags.Bool("singleClick", false, "use single clicks only")
|
flags.Bool("singleClick", false, "use single clicks only")
|
||||||
|
flags.Bool("redirectAfterCopyMove", false, "redirect to destination after copy/move")
|
||||||
flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)")
|
flags.Bool("dateFormat", false, "use date format (true for absolute time, false for relative)")
|
||||||
flags.Bool("hideDotfiles", false, "hide dotfiles")
|
flags.Bool("hideDotfiles", false, "hide dotfiles")
|
||||||
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
|
flags.String("aceEditorTheme", "", "ace editor's syntax highlighting theme for users")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
|
func getAndParseViewMode(flags *pflag.FlagSet) (users.ViewMode, error) {
|
||||||
viewModeStr, err := getString(flags, "viewMode")
|
viewModeStr, err := flags.GetString("viewMode")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
viewMode := users.ViewMode(viewModeStr)
|
viewMode := users.ViewMode(viewModeStr)
|
||||||
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
|
if viewMode != users.ListViewMode && viewMode != users.MosaicViewMode {
|
||||||
return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")
|
return "", errors.New("view mode must be \"" + string(users.ListViewMode) + "\" or \"" + string(users.MosaicViewMode) + "\"")
|
||||||
}
|
}
|
||||||
|
|
||||||
return viewMode, nil
|
return viewMode, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gocyclo
|
|
||||||
func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error {
|
func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all bool) error {
|
||||||
var visitErr error
|
errs := []error{}
|
||||||
|
|
||||||
visit := func(flag *pflag.Flag) {
|
visit := func(flag *pflag.Flag) {
|
||||||
if visitErr != nil {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
var err error
|
var err error
|
||||||
switch flag.Name {
|
switch flag.Name {
|
||||||
case "scope":
|
case "scope":
|
||||||
defaults.Scope, err = getString(flags, flag.Name)
|
defaults.Scope, err = flags.GetString(flag.Name)
|
||||||
case "locale":
|
case "locale":
|
||||||
defaults.Locale, err = getString(flags, flag.Name)
|
defaults.Locale, err = flags.GetString(flag.Name)
|
||||||
case "viewMode":
|
case "viewMode":
|
||||||
defaults.ViewMode, err = getViewMode(flags)
|
defaults.ViewMode, err = getAndParseViewMode(flags)
|
||||||
case "singleClick":
|
case "singleClick":
|
||||||
defaults.SingleClick, err = getBool(flags, flag.Name)
|
defaults.SingleClick, err = flags.GetBool(flag.Name)
|
||||||
|
case "redirectAfterCopyMove":
|
||||||
|
defaults.RedirectAfterCopyMove, err = flags.GetBool(flag.Name)
|
||||||
case "aceEditorTheme":
|
case "aceEditorTheme":
|
||||||
defaults.AceEditorTheme, err = getString(flags, flag.Name)
|
defaults.AceEditorTheme, err = flags.GetString(flag.Name)
|
||||||
case "perm.admin":
|
case "perm.admin":
|
||||||
defaults.Perm.Admin, err = getBool(flags, flag.Name)
|
defaults.Perm.Admin, err = flags.GetBool(flag.Name)
|
||||||
case "perm.execute":
|
case "perm.execute":
|
||||||
defaults.Perm.Execute, err = getBool(flags, flag.Name)
|
defaults.Perm.Execute, err = flags.GetBool(flag.Name)
|
||||||
case "perm.create":
|
case "perm.create":
|
||||||
defaults.Perm.Create, err = getBool(flags, flag.Name)
|
defaults.Perm.Create, err = flags.GetBool(flag.Name)
|
||||||
case "perm.rename":
|
case "perm.rename":
|
||||||
defaults.Perm.Rename, err = getBool(flags, flag.Name)
|
defaults.Perm.Rename, err = flags.GetBool(flag.Name)
|
||||||
case "perm.modify":
|
case "perm.modify":
|
||||||
defaults.Perm.Modify, err = getBool(flags, flag.Name)
|
defaults.Perm.Modify, err = flags.GetBool(flag.Name)
|
||||||
case "perm.delete":
|
case "perm.delete":
|
||||||
defaults.Perm.Delete, err = getBool(flags, flag.Name)
|
defaults.Perm.Delete, err = flags.GetBool(flag.Name)
|
||||||
case "perm.share":
|
case "perm.share":
|
||||||
defaults.Perm.Share, err = getBool(flags, flag.Name)
|
defaults.Perm.Share, err = flags.GetBool(flag.Name)
|
||||||
case "perm.download":
|
case "perm.download":
|
||||||
defaults.Perm.Download, err = getBool(flags, flag.Name)
|
defaults.Perm.Download, err = flags.GetBool(flag.Name)
|
||||||
case "commands":
|
case "commands":
|
||||||
defaults.Commands, err = flags.GetStringSlice(flag.Name)
|
defaults.Commands, err = flags.GetStringSlice(flag.Name)
|
||||||
case "sorting.by":
|
case "sorting.by":
|
||||||
defaults.Sorting.By, err = getString(flags, flag.Name)
|
defaults.Sorting.By, err = flags.GetString(flag.Name)
|
||||||
case "sorting.asc":
|
case "sorting.asc":
|
||||||
defaults.Sorting.Asc, err = getBool(flags, flag.Name)
|
defaults.Sorting.Asc, err = flags.GetBool(flag.Name)
|
||||||
|
case "hideDotfiles":
|
||||||
|
defaults.HideDotfiles, err = flags.GetBool(flag.Name)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
visitErr = err
|
errs = append(errs, err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -146,5 +152,6 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
|
||||||
} else {
|
} else {
|
||||||
flags.Visit(visit)
|
flags.Visit(visit)
|
||||||
}
|
}
|
||||||
return visitErr
|
|
||||||
|
return errors.Join(errs...)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,12 +16,13 @@ var usersAddCmd = &cobra.Command{
|
||||||
Short: "Create a new user",
|
Short: "Create a new user",
|
||||||
Long: `Create a new user and add it to the database.`,
|
Long: `Create a new user and add it to the database.`,
|
||||||
Args: cobra.ExactArgs(2),
|
Args: cobra.ExactArgs(2),
|
||||||
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
|
||||||
s, err := d.store.Settings.Get()
|
flags := cmd.Flags()
|
||||||
|
s, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
err = getUserDefaults(cmd.Flags(), &s.Defaults, false)
|
err = getUserDefaults(flags, &s.Defaults, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -31,39 +32,36 @@ var usersAddCmd = &cobra.Command{
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
lockPassword, err := getBool(cmd.Flags(), "lockPassword")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
dateFormat, err := getBool(cmd.Flags(), "dateFormat")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
hideDotfiles, err := getBool(cmd.Flags(), "hideDotfiles")
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
user := &users.User{
|
user := &users.User{
|
||||||
Username: args[0],
|
Username: args[0],
|
||||||
Password: password,
|
Password: password,
|
||||||
LockPassword: lockPassword,
|
}
|
||||||
DateFormat: dateFormat,
|
|
||||||
HideDotfiles: hideDotfiles,
|
user.LockPassword, err = flags.GetBool("lockPassword")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user.DateFormat, err = flags.GetBool("dateFormat")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
user.HideDotfiles, err = flags.GetBool("hideDotfiles")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s.Defaults.Apply(user)
|
s.Defaults.Apply(user)
|
||||||
|
|
||||||
servSettings, err := d.store.Settings.GetServer()
|
servSettings, err := st.Settings.GetServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
// since getUserDefaults() polluted s.Defaults.Scope
|
// since getUserDefaults() polluted s.Defaults.Scope
|
||||||
// which makes the Scope not the one saved in the db
|
// which makes the Scope not the one saved in the db
|
||||||
// we need the right s.Defaults.Scope here
|
// we need the right s.Defaults.Scope here
|
||||||
s2, err := d.store.Settings.Get()
|
s2, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -74,11 +72,11 @@ var usersAddCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
user.Scope = userHome
|
user.Scope = userHome
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = st.Users.Save(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printUsers([]*users.User{user})
|
printUsers([]*users.User{user})
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,8 @@ var usersExportCmd = &cobra.Command{
|
||||||
Long: `Export all users to a json or yaml file. Please indicate the
|
Long: `Export all users to a json or yaml file. Please indicate the
|
||||||
path to the file where you want to write the users.`,
|
path to the file where you want to write the users.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
list, err := d.store.Users.Gets("")
|
list, err := st.Users.Gets("")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -25,5 +25,5 @@ path to the file where you want to write the users.`,
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,7 +26,7 @@ var usersLsCmd = &cobra.Command{
|
||||||
RunE: findUsers,
|
RunE: findUsers,
|
||||||
}
|
}
|
||||||
|
|
||||||
var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
var findUsers = withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
var (
|
var (
|
||||||
list []*users.User
|
list []*users.User
|
||||||
user *users.User
|
user *users.User
|
||||||
|
|
@ -36,14 +36,14 @@ var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) erro
|
||||||
if len(args) == 1 {
|
if len(args) == 1 {
|
||||||
username, id := parseUsernameOrID(args[0])
|
username, id := parseUsernameOrID(args[0])
|
||||||
if username != "" {
|
if username != "" {
|
||||||
user, err = d.store.Users.Get("", username)
|
user, err = st.Users.Get("", username)
|
||||||
} else {
|
} else {
|
||||||
user, err = d.store.Users.Get("", id)
|
user, err = st.Users.Get("", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
list = []*users.User{user}
|
list = []*users.User{user}
|
||||||
} else {
|
} else {
|
||||||
list, err = d.store.Users.Gets("")
|
list, err = st.Users.Gets("")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -51,4 +51,4 @@ var findUsers = python(func(_ *cobra.Command, args []string, d *pythonData) erro
|
||||||
}
|
}
|
||||||
printUsers(list)
|
printUsers(list)
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{})
|
}, storeOptions{})
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,8 @@ file. You can use this command to import new users to your
|
||||||
installation. For that, just don't place their ID on the files
|
installation. For that, just don't place their ID on the files
|
||||||
list or set it to 0.`,
|
list or set it to 0.`,
|
||||||
Args: jsonYamlArg,
|
Args: jsonYamlArg,
|
||||||
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
|
||||||
|
flags := cmd.Flags()
|
||||||
fd, err := os.Open(args[0])
|
fd, err := os.Open(args[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
@ -45,13 +46,13 @@ list or set it to 0.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
replace, err := getBool(cmd.Flags(), "replace")
|
replace, err := flags.GetBool("replace")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if replace {
|
if replace {
|
||||||
oldUsers, userImportErr := d.store.Users.Gets("")
|
oldUsers, userImportErr := st.Users.Gets("")
|
||||||
if userImportErr != nil {
|
if userImportErr != nil {
|
||||||
return userImportErr
|
return userImportErr
|
||||||
}
|
}
|
||||||
|
|
@ -62,20 +63,20 @@ list or set it to 0.`,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, user := range oldUsers {
|
for _, user := range oldUsers {
|
||||||
err = d.store.Users.Delete(user.ID)
|
err = st.Users.Delete(user.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
overwrite, err := getBool(cmd.Flags(), "overwrite")
|
overwrite, err := flags.GetBool("overwrite")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, user := range list {
|
for _, user := range list {
|
||||||
onDB, err := d.store.Users.Get("", user.ID)
|
onDB, err := st.Users.Get("", user.ID)
|
||||||
|
|
||||||
// User exists in DB.
|
// User exists in DB.
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -87,7 +88,7 @@ list or set it to 0.`,
|
||||||
// with the new username. If there is, print an error and cancel the
|
// with the new username. If there is, print an error and cancel the
|
||||||
// operation
|
// operation
|
||||||
if user.Username != onDB.Username {
|
if user.Username != onDB.Username {
|
||||||
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
|
if conflictuous, err := st.Users.Get("", user.Username); err == nil {
|
||||||
return usernameConflictError(user.Username, conflictuous.ID, user.ID)
|
return usernameConflictError(user.Username, conflictuous.ID, user.ID)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -97,13 +98,13 @@ list or set it to 0.`,
|
||||||
user.ID = 0
|
user.ID = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Users.Save(user)
|
err = st.Users.Save(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
||||||
func usernameConflictError(username string, originalID, newID uint) error {
|
func usernameConflictError(username string, originalID, newID uint) error {
|
||||||
|
|
|
||||||
|
|
@ -15,14 +15,14 @@ var usersRmCmd = &cobra.Command{
|
||||||
Short: "Delete a user by username or id",
|
Short: "Delete a user by username or id",
|
||||||
Long: `Delete a user by username or id`,
|
Long: `Delete a user by username or id`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: python(func(_ *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(_ *cobra.Command, args []string, st *store) error {
|
||||||
username, id := parseUsernameOrID(args[0])
|
username, id := parseUsernameOrID(args[0])
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
if username != "" {
|
if username != "" {
|
||||||
err = d.store.Users.Delete(username)
|
err = st.Users.Delete(username)
|
||||||
} else {
|
} else {
|
||||||
err = d.store.Users.Delete(id)
|
err = st.Users.Delete(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -30,5 +30,5 @@ var usersRmCmd = &cobra.Command{
|
||||||
}
|
}
|
||||||
fmt.Println("user deleted successfully")
|
fmt.Println("user deleted successfully")
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,20 @@ var usersUpdateCmd = &cobra.Command{
|
||||||
Long: `Updates an existing user. Set the flags for the
|
Long: `Updates an existing user. Set the flags for the
|
||||||
options you want to change.`,
|
options you want to change.`,
|
||||||
Args: cobra.ExactArgs(1),
|
Args: cobra.ExactArgs(1),
|
||||||
RunE: python(func(cmd *cobra.Command, args []string, d *pythonData) error {
|
RunE: withStore(func(cmd *cobra.Command, args []string, st *store) error {
|
||||||
username, id := parseUsernameOrID(args[0])
|
|
||||||
flags := cmd.Flags()
|
flags := cmd.Flags()
|
||||||
password, err := getString(flags, "password")
|
username, id := parseUsernameOrID(args[0])
|
||||||
if err != nil {
|
password, err := flags.GetString("password")
|
||||||
return err
|
|
||||||
}
|
|
||||||
newUsername, err := getString(flags, "username")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := d.store.Settings.Get()
|
newUsername, err := flags.GetString("username")
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := st.Settings.Get()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -41,46 +42,50 @@ options you want to change.`,
|
||||||
var (
|
var (
|
||||||
user *users.User
|
user *users.User
|
||||||
)
|
)
|
||||||
|
|
||||||
if id != 0 {
|
if id != 0 {
|
||||||
user, err = d.store.Users.Get("", id)
|
user, err = st.Users.Get("", id)
|
||||||
} else {
|
} else {
|
||||||
user, err = d.store.Users.Get("", username)
|
user, err = st.Users.Get("", username)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
defaults := settings.UserDefaults{
|
defaults := settings.UserDefaults{
|
||||||
Scope: user.Scope,
|
Scope: user.Scope,
|
||||||
Locale: user.Locale,
|
Locale: user.Locale,
|
||||||
ViewMode: user.ViewMode,
|
ViewMode: user.ViewMode,
|
||||||
SingleClick: user.SingleClick,
|
SingleClick: user.SingleClick,
|
||||||
Perm: user.Perm,
|
RedirectAfterCopyMove: user.RedirectAfterCopyMove,
|
||||||
Sorting: user.Sorting,
|
Perm: user.Perm,
|
||||||
Commands: user.Commands,
|
Sorting: user.Sorting,
|
||||||
|
Commands: user.Commands,
|
||||||
}
|
}
|
||||||
|
|
||||||
err = getUserDefaults(flags, &defaults, false)
|
err = getUserDefaults(flags, &defaults, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
user.Scope = defaults.Scope
|
user.Scope = defaults.Scope
|
||||||
user.Locale = defaults.Locale
|
user.Locale = defaults.Locale
|
||||||
user.ViewMode = defaults.ViewMode
|
user.ViewMode = defaults.ViewMode
|
||||||
user.SingleClick = defaults.SingleClick
|
user.SingleClick = defaults.SingleClick
|
||||||
|
user.RedirectAfterCopyMove = defaults.RedirectAfterCopyMove
|
||||||
user.Perm = defaults.Perm
|
user.Perm = defaults.Perm
|
||||||
user.Commands = defaults.Commands
|
user.Commands = defaults.Commands
|
||||||
user.Sorting = defaults.Sorting
|
user.Sorting = defaults.Sorting
|
||||||
user.LockPassword, err = getBool(flags, "lockPassword")
|
user.LockPassword, err = flags.GetBool("lockPassword")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user.DateFormat, err = getBool(flags, "dateFormat")
|
|
||||||
|
user.DateFormat, err = flags.GetBool("dateFormat")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
user.HideDotfiles, err = getBool(flags, "hideDotfiles")
|
|
||||||
|
user.HideDotfiles, err = flags.GetBool("hideDotfiles")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
@ -96,11 +101,11 @@ options you want to change.`,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = d.store.Users.Update(user)
|
err = st.Users.Update(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
printUsers([]*users.User{user})
|
printUsers([]*users.User{user})
|
||||||
return nil
|
return nil
|
||||||
}, pythonConfig{}),
|
}, storeOptions{}),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
186
cmd/utils.go
186
cmd/utils.go
|
|
@ -12,8 +12,11 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/asdine/storm/v3"
|
"github.com/asdine/storm/v3"
|
||||||
|
homedir "github.com/mitchellh/go-homedir"
|
||||||
|
"github.com/samber/lo"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
"github.com/spf13/viper"
|
||||||
yaml "gopkg.in/yaml.v3"
|
yaml "gopkg.in/yaml.v3"
|
||||||
|
|
||||||
"github.com/filebrowser/filebrowser/v2/settings"
|
"github.com/filebrowser/filebrowser/v2/settings"
|
||||||
|
|
@ -21,42 +24,22 @@ import (
|
||||||
"github.com/filebrowser/filebrowser/v2/storage/bolt"
|
"github.com/filebrowser/filebrowser/v2/storage/bolt"
|
||||||
)
|
)
|
||||||
|
|
||||||
const dbPerms = 0640
|
const databasePermissions = 0640
|
||||||
|
|
||||||
func returnErr(err error) error {
|
func getAndParseFileMode(flags *pflag.FlagSet, name string) (fs.FileMode, error) {
|
||||||
if err != nil {
|
mode, err := flags.GetString(name)
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getString(flags *pflag.FlagSet, flag string) (string, error) {
|
|
||||||
s, err := flags.GetString(flag)
|
|
||||||
return s, returnErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getMode(flags *pflag.FlagSet, flag string) (fs.FileMode, error) {
|
|
||||||
s, err := getString(flags, flag)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
b, err := strconv.ParseUint(s, 0, 32)
|
|
||||||
|
b, err := strconv.ParseUint(mode, 0, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, err
|
return 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return fs.FileMode(b), nil
|
return fs.FileMode(b), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func getBool(flags *pflag.FlagSet, flag string) (bool, error) {
|
|
||||||
b, err := flags.GetBool(flag)
|
|
||||||
return b, returnErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUint(flags *pflag.FlagSet, flag string) (uint, error) {
|
|
||||||
b, err := flags.GetUint(flag)
|
|
||||||
return b, returnErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
func generateKey() []byte {
|
func generateKey() []byte {
|
||||||
k, err := settings.GenerateKey()
|
k, err := settings.GenerateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -65,20 +48,6 @@ func generateKey() []byte {
|
||||||
return k
|
return k
|
||||||
}
|
}
|
||||||
|
|
||||||
type cobraFunc func(cmd *cobra.Command, args []string) error
|
|
||||||
type pythonFunc func(cmd *cobra.Command, args []string, data *pythonData) error
|
|
||||||
|
|
||||||
type pythonConfig struct {
|
|
||||||
noDB bool
|
|
||||||
allowNoDB bool
|
|
||||||
}
|
|
||||||
|
|
||||||
type pythonData struct {
|
|
||||||
hadDB bool
|
|
||||||
store *storage.Storage
|
|
||||||
err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func dbExists(path string) (bool, error) {
|
func dbExists(path string) (bool, error) {
|
||||||
stat, err := os.Stat(path)
|
stat, err := os.Stat(path)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
|
@ -89,7 +58,7 @@ func dbExists(path string) (bool, error) {
|
||||||
d := filepath.Dir(path)
|
d := filepath.Dir(path)
|
||||||
_, err = os.Stat(d)
|
_, err = os.Stat(d)
|
||||||
if os.IsNotExist(err) {
|
if os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet
|
if err := os.MkdirAll(d, 0700); err != nil {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
return false, nil
|
return false, nil
|
||||||
|
|
@ -99,42 +68,137 @@ func dbExists(path string) (bool, error) {
|
||||||
return false, err
|
return false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func python(fn pythonFunc, cfg pythonConfig) cobraFunc {
|
// Generate the replacements for all environment variables. This allows to
|
||||||
|
// use FB_BRANDING_DISABLE_EXTERNAL environment variables, even when the
|
||||||
|
// option name is branding.disableExternal.
|
||||||
|
func generateEnvKeyReplacements(cmd *cobra.Command) []string {
|
||||||
|
replacements := []string{}
|
||||||
|
|
||||||
|
cmd.Flags().VisitAll(func(f *pflag.Flag) {
|
||||||
|
oldName := strings.ToUpper(f.Name)
|
||||||
|
newName := strings.ToUpper(lo.SnakeCase(f.Name))
|
||||||
|
replacements = append(replacements, oldName, newName)
|
||||||
|
})
|
||||||
|
|
||||||
|
return replacements
|
||||||
|
}
|
||||||
|
|
||||||
|
func initViper(cmd *cobra.Command) (*viper.Viper, error) {
|
||||||
|
v := viper.New()
|
||||||
|
|
||||||
|
// Get config file from flag
|
||||||
|
cfgFile, err := cmd.Flags().GetString("config")
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configuration file
|
||||||
|
if cfgFile == "" {
|
||||||
|
home, err := homedir.Dir()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
v.AddConfigPath(".")
|
||||||
|
v.AddConfigPath(home)
|
||||||
|
v.AddConfigPath("/etc/filebrowser/")
|
||||||
|
v.SetConfigName(".filebrowser")
|
||||||
|
} else {
|
||||||
|
v.SetConfigFile(cfgFile)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Environment variables
|
||||||
|
v.SetEnvPrefix("FB")
|
||||||
|
v.AutomaticEnv()
|
||||||
|
v.SetEnvKeyReplacer(strings.NewReplacer(generateEnvKeyReplacements(cmd)...))
|
||||||
|
|
||||||
|
// Bind the flags
|
||||||
|
err = v.BindPFlags(cmd.Flags())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read in configuration
|
||||||
|
if err := v.ReadInConfig(); err != nil {
|
||||||
|
if errors.Is(err, viper.ConfigParseError{}) {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("No config file used")
|
||||||
|
} else {
|
||||||
|
log.Printf("Using config file: %s", v.ConfigFileUsed())
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return Viper
|
||||||
|
return v, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type store struct {
|
||||||
|
*storage.Storage
|
||||||
|
databaseExisted bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type storeOptions struct {
|
||||||
|
expectsNoDatabase bool
|
||||||
|
allowsNoDatabase bool
|
||||||
|
}
|
||||||
|
|
||||||
|
type cobraFunc func(cmd *cobra.Command, args []string) error
|
||||||
|
|
||||||
|
// withViperAndStore initializes Viper and the storage.Store and passes them to the callback function.
|
||||||
|
// This function should only be used by [withStore] and the root command. No other command should call
|
||||||
|
// this function directly.
|
||||||
|
func withViperAndStore(fn func(cmd *cobra.Command, args []string, v *viper.Viper, store *store) error, options storeOptions) cobraFunc {
|
||||||
return func(cmd *cobra.Command, args []string) error {
|
return func(cmd *cobra.Command, args []string) error {
|
||||||
data := &pythonData{hadDB: true}
|
v, err := initViper(cmd)
|
||||||
|
|
||||||
path := getStringParam(cmd.Flags(), "database")
|
|
||||||
absPath, err := filepath.Abs(path)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
path, err := filepath.Abs(v.GetString("database"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
exists, err := dbExists(path)
|
exists, err := dbExists(path)
|
||||||
|
switch {
|
||||||
if err != nil {
|
case err != nil:
|
||||||
panic(err)
|
return err
|
||||||
} else if exists && cfg.noDB {
|
case exists && options.expectsNoDatabase:
|
||||||
log.Fatal(absPath + " already exists")
|
log.Fatal(path + " already exists")
|
||||||
} else if !exists && !cfg.noDB && !cfg.allowNoDB {
|
case !exists && !options.expectsNoDatabase && !options.allowsNoDatabase:
|
||||||
log.Fatal(absPath + " does not exist. Please run 'filebrowser config init' first.")
|
log.Fatal(path + " does not exist. Please run 'filebrowser config init' first.")
|
||||||
} else if !exists && !cfg.noDB {
|
case !exists && !options.expectsNoDatabase:
|
||||||
log.Println("Warning: filebrowser.db can't be found. Initialing in " + strings.TrimSuffix(absPath, "filebrowser.db"))
|
log.Println("WARNING: filebrowser.db can't be found. Initialing in " + strings.TrimSuffix(path, "filebrowser.db"))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Println("Using database: " + absPath)
|
log.Println("Using database: " + path)
|
||||||
data.hadDB = exists
|
|
||||||
db, err := storm.Open(path, storm.BoltOptions(dbPerms, nil))
|
db, err := storm.Open(path, storm.BoltOptions(databasePermissions, nil))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
data.store, err = bolt.NewStorage(db)
|
|
||||||
|
storage, err := bolt.NewStorage(db)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return fn(cmd, args, data)
|
|
||||||
|
store := &store{
|
||||||
|
Storage: storage,
|
||||||
|
databaseExisted: exists,
|
||||||
|
}
|
||||||
|
|
||||||
|
return fn(cmd, args, v, store)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func withStore(fn func(cmd *cobra.Command, args []string, store *store) error, options storeOptions) cobraFunc {
|
||||||
|
return withViperAndStore(func(cmd *cobra.Command, args []string, _ *viper.Viper, store *store) error {
|
||||||
|
return fn(cmd, args, store)
|
||||||
|
}, options)
|
||||||
|
}
|
||||||
|
|
||||||
func marshal(filename string, data interface{}) error {
|
func marshal(filename string, data interface{}) error {
|
||||||
fd, err := os.Create(filename)
|
fd, err := os.Create(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,34 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
rules: {
|
|
||||||
'body-leading-blank': [1, 'always'],
|
|
||||||
'body-max-line-length': [2, 'always', 100],
|
|
||||||
'footer-leading-blank': [1, 'always'],
|
|
||||||
'footer-max-line-length': [2, 'always', 100],
|
|
||||||
'header-max-length': [2, 'always', 100],
|
|
||||||
'scope-case': [2, 'always', 'lower-case'],
|
|
||||||
'subject-case': [
|
|
||||||
2,
|
|
||||||
'never',
|
|
||||||
['sentence-case', 'start-case', 'pascal-case', 'upper-case'],
|
|
||||||
],
|
|
||||||
'subject-full-stop': [2, 'never', '.'],
|
|
||||||
'type-case': [2, 'always', 'lower-case'],
|
|
||||||
'type-empty': [2, 'never'],
|
|
||||||
'type-enum': [
|
|
||||||
2,
|
|
||||||
'always',
|
|
||||||
[
|
|
||||||
'feat',
|
|
||||||
'fix',
|
|
||||||
'perf',
|
|
||||||
'revert',
|
|
||||||
'refactor',
|
|
||||||
'build',
|
|
||||||
'ci',
|
|
||||||
'test',
|
|
||||||
'chore',
|
|
||||||
'docs',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
@ -2,7 +2,7 @@ package diskcache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto/sha1" //nolint:gosec
|
"crypto/sha1"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
@ -103,7 +103,7 @@ func (f *FileCache) getScopedLocks(key string) (lock sync.Locker) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FileCache) getFileName(key string) string {
|
func (f *FileCache) getFileName(key string) string {
|
||||||
hasher := sha1.New() //nolint:gosec
|
hasher := sha1.New()
|
||||||
_, _ = hasher.Write([]byte(key))
|
_, _ = hasher.Write([]byte(key))
|
||||||
hash := hex.EncodeToString(hasher.Sum(nil))
|
hash := hex.EncodeToString(hasher.Sum(nil))
|
||||||
return fmt.Sprintf("%s/%s/%s", hash[:1], hash[1:3], hash)
|
return fmt.Sprintf("%s/%s/%s", hash[:1], hash[1:3], hash)
|
||||||
|
|
|
||||||
|
|
@ -25,12 +25,12 @@ func TestFileCache(t *testing.T) {
|
||||||
// store new key
|
// store new key
|
||||||
err := cache.Store(ctx, key, []byte(value))
|
err := cache.Store(ctx, key, []byte(value))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, value)
|
checkValue(ctx, t, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, value)
|
||||||
|
|
||||||
// update existing key
|
// update existing key
|
||||||
err = cache.Store(ctx, key, []byte(newValue))
|
err = cache.Store(ctx, key, []byte(newValue))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, newValue)
|
checkValue(ctx, t, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, newValue)
|
||||||
|
|
||||||
// delete key
|
// delete key
|
||||||
err = cache.Delete(ctx, key)
|
err = cache.Delete(ctx, key)
|
||||||
|
|
@ -40,7 +40,7 @@ func TestFileCache(t *testing.T) {
|
||||||
require.False(t, exists)
|
require.False(t, exists)
|
||||||
}
|
}
|
||||||
|
|
||||||
func checkValue(t *testing.T, ctx context.Context, fs afero.Fs, fileFullPath string, cache *FileCache, key, wantValue string) { //nolint:revive
|
func checkValue(ctx context.Context, t *testing.T, fs afero.Fs, fileFullPath string, cache *FileCache, key, wantValue string) {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
// check actual file content
|
// check actual file content
|
||||||
b, err := afero.ReadFile(fs, fileFullPath)
|
b, err := afero.ReadFile(fs, fileFullPath)
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,4 @@
|
||||||
"log": "stdout",
|
"log": "stdout",
|
||||||
"database": "/database/filebrowser.db",
|
"database": "/database/filebrowser.db",
|
||||||
"root": "/srv"
|
"root": "/srv"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,40 +1,28 @@
|
||||||
package errors
|
package fberrors
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExitCodeSigTerm = 128 + int(syscall.SIGTERM)
|
|
||||||
ExitCodeSighup = 128 + int(syscall.SIGHUP)
|
|
||||||
ExitCodeSigint = 128 + int(syscall.SIGINT)
|
|
||||||
ExitCodeSigquit = 128 + int(syscall.SIGQUIT)
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
ErrEmptyKey = errors.New("empty key")
|
ErrEmptyKey = errors.New("empty key")
|
||||||
ErrExist = errors.New("the resource already exists")
|
ErrExist = errors.New("the resource already exists")
|
||||||
ErrNotExist = errors.New("the resource does not exist")
|
ErrNotExist = errors.New("the resource does not exist")
|
||||||
ErrEmptyPassword = errors.New("password is empty")
|
ErrEmptyPassword = errors.New("password is empty")
|
||||||
ErrEasyPassword = errors.New("password is too easy")
|
ErrEasyPassword = errors.New("password is too easy")
|
||||||
ErrEmptyUsername = errors.New("username is empty")
|
ErrEmptyUsername = errors.New("username is empty")
|
||||||
ErrEmptyRequest = errors.New("empty request")
|
ErrEmptyRequest = errors.New("empty request")
|
||||||
ErrScopeIsRelative = errors.New("scope is a relative path")
|
ErrScopeIsRelative = errors.New("scope is a relative path")
|
||||||
ErrInvalidDataType = errors.New("invalid data type")
|
ErrInvalidDataType = errors.New("invalid data type")
|
||||||
ErrIsDirectory = errors.New("file is directory")
|
ErrIsDirectory = errors.New("file is directory")
|
||||||
ErrInvalidOption = errors.New("invalid option")
|
ErrInvalidOption = errors.New("invalid option")
|
||||||
ErrInvalidAuthMethod = errors.New("invalid auth method")
|
ErrInvalidAuthMethod = errors.New("invalid auth method")
|
||||||
ErrPermissionDenied = errors.New("permission denied")
|
ErrPermissionDenied = errors.New("permission denied")
|
||||||
ErrInvalidRequestParams = errors.New("invalid request params")
|
ErrInvalidRequestParams = errors.New("invalid request params")
|
||||||
ErrSourceIsParent = errors.New("source is parent")
|
ErrSourceIsParent = errors.New("source is parent")
|
||||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||||
ErrSigTerm = errors.New("exit on signal: sigterm")
|
ErrCurrentPasswordIncorrect = errors.New("the current password is incorrect")
|
||||||
ErrSighup = errors.New("exit on signal: sighup")
|
|
||||||
ErrSigint = errors.New("exit on signal: sigint")
|
|
||||||
ErrSigquit = errors.New("exit on signal: sigquit")
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ErrShortPassword struct {
|
type ErrShortPassword struct {
|
||||||
|
|
@ -44,44 +32,3 @@ type ErrShortPassword struct {
|
||||||
func (e ErrShortPassword) Error() string {
|
func (e ErrShortPassword) Error() string {
|
||||||
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
|
return fmt.Sprintf("password is too short, minimum length is %d", e.MinimumLength)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetExitCode returns the exit code for a given error.
|
|
||||||
func GetExitCode(err error) int {
|
|
||||||
if err == nil {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
exitCodeMap := map[error]int{
|
|
||||||
ErrSigTerm: ExitCodeSigTerm,
|
|
||||||
ErrSighup: ExitCodeSighup,
|
|
||||||
ErrSigint: ExitCodeSigint,
|
|
||||||
ErrSigquit: ExitCodeSigquit,
|
|
||||||
}
|
|
||||||
|
|
||||||
for e, code := range exitCodeMap {
|
|
||||||
if errors.Is(err, e) {
|
|
||||||
return code
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if exitErr, ok := err.(interface{ ExitCode() int }); ok {
|
|
||||||
return exitErr.ExitCode()
|
|
||||||
}
|
|
||||||
|
|
||||||
var pathErr *os.PathError
|
|
||||||
if errors.As(err, &pathErr) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
var syscallErr *os.SyscallError
|
|
||||||
if errors.As(err, &syscallErr) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
var errno syscall.Errno
|
|
||||||
if errors.As(err, &errno) {
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
package files
|
package files
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/md5" //nolint:gosec
|
"crypto/md5"
|
||||||
"crypto/sha1" //nolint:gosec
|
"crypto/sha1"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"crypto/sha512"
|
"crypto/sha512"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
|
|
@ -23,7 +23,7 @@ import (
|
||||||
|
|
||||||
"github.com/spf13/afero"
|
"github.com/spf13/afero"
|
||||||
|
|
||||||
fbErrors "github.com/filebrowser/filebrowser/v2/errors"
|
fberrors "github.com/filebrowser/filebrowser/v2/errors"
|
||||||
"github.com/filebrowser/filebrowser/v2/rules"
|
"github.com/filebrowser/filebrowser/v2/rules"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -60,6 +60,7 @@ type FileOptions struct {
|
||||||
Modify bool
|
Modify bool
|
||||||
Expand bool
|
Expand bool
|
||||||
ReadHeader bool
|
ReadHeader bool
|
||||||
|
CalcImgRes bool
|
||||||
Token string
|
Token string
|
||||||
Checker rules.Checker
|
Checker rules.Checker
|
||||||
Content bool
|
Content bool
|
||||||
|
|
@ -90,13 +91,13 @@ func NewFileInfo(opts *FileOptions) (*FileInfo, error) {
|
||||||
|
|
||||||
if opts.Expand {
|
if opts.Expand {
|
||||||
if file.IsDir {
|
if file.IsDir {
|
||||||
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
if err := file.readListing(opts.Checker, opts.ReadHeader, opts.CalcImgRes); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return file, nil
|
return file, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
err = file.detectType(opts.Modify, opts.Content, true)
|
err = file.detectType(opts.Modify, opts.Content, true, opts.CalcImgRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
@ -168,7 +169,7 @@ func stat(opts *FileOptions) (*FileInfo, error) {
|
||||||
// algorithm. The checksums data is saved on File object.
|
// algorithm. The checksums data is saved on File object.
|
||||||
func (i *FileInfo) Checksum(algo string) error {
|
func (i *FileInfo) Checksum(algo string) error {
|
||||||
if i.IsDir {
|
if i.IsDir {
|
||||||
return fbErrors.ErrIsDirectory
|
return fberrors.ErrIsDirectory
|
||||||
}
|
}
|
||||||
|
|
||||||
if i.Checksums == nil {
|
if i.Checksums == nil {
|
||||||
|
|
@ -183,7 +184,6 @@ func (i *FileInfo) Checksum(algo string) error {
|
||||||
|
|
||||||
var h hash.Hash
|
var h hash.Hash
|
||||||
|
|
||||||
//nolint:gosec
|
|
||||||
switch algo {
|
switch algo {
|
||||||
case "md5":
|
case "md5":
|
||||||
h = md5.New()
|
h = md5.New()
|
||||||
|
|
@ -194,7 +194,7 @@ func (i *FileInfo) Checksum(algo string) error {
|
||||||
case "sha512":
|
case "sha512":
|
||||||
h = sha512.New()
|
h = sha512.New()
|
||||||
default:
|
default:
|
||||||
return fbErrors.ErrInvalidOption
|
return fberrors.ErrInvalidOption
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = io.Copy(h, reader)
|
_, err = io.Copy(h, reader)
|
||||||
|
|
@ -219,7 +219,7 @@ func (i *FileInfo) RealPath() string {
|
||||||
return i.Path
|
return i.Path
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
func (i *FileInfo) detectType(modify, saveContent, readHeader bool, calcImgRes bool) error {
|
||||||
if IsNamedPipe(i.Mode) {
|
if IsNamedPipe(i.Mode) {
|
||||||
i.Type = "blob"
|
i.Type = "blob"
|
||||||
return nil
|
return nil
|
||||||
|
|
@ -250,11 +250,13 @@ func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||||
return nil
|
return nil
|
||||||
case strings.HasPrefix(mimetype, "image"):
|
case strings.HasPrefix(mimetype, "image"):
|
||||||
i.Type = "image"
|
i.Type = "image"
|
||||||
resolution, err := calculateImageResolution(i.Fs, i.Path)
|
if calcImgRes {
|
||||||
if err != nil {
|
resolution, err := calculateImageResolution(i.Fs, i.Path)
|
||||||
log.Printf("Error calculating image resolution: %v", err)
|
if err != nil {
|
||||||
} else {
|
log.Printf("Error calculating image resolution: %v", err)
|
||||||
i.Resolution = resolution
|
} else {
|
||||||
|
i.Resolution = resolution
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
case strings.HasSuffix(mimetype, "pdf"):
|
case strings.HasSuffix(mimetype, "pdf"):
|
||||||
|
|
@ -388,7 +390,7 @@ func (i *FileInfo) addSubtitle(fPath string) {
|
||||||
i.Subtitles = append(i.Subtitles, fPath)
|
i.Subtitles = append(i.Subtitles, fPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool, calcImgRes bool) error {
|
||||||
afs := &afero.Afero{Fs: i.Fs}
|
afs := &afero.Afero{Fs: i.Fs}
|
||||||
dir, err := afs.ReadDir(i.Path)
|
dir, err := afs.ReadDir(i.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -435,7 +437,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
currentDir: dir,
|
currentDir: dir,
|
||||||
}
|
}
|
||||||
|
|
||||||
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") {
|
if !file.IsDir && strings.HasPrefix(mime.TypeByExtension(file.Extension), "image/") && calcImgRes {
|
||||||
resolution, err := calculateImageResolution(file.Fs, file.Path)
|
resolution, err := calculateImageResolution(file.Fs, file.Path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
|
log.Printf("Error calculating resolution for image %s: %v", file.Path, err)
|
||||||
|
|
@ -452,7 +454,7 @@ func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||||
if isInvalidLink {
|
if isInvalidLink {
|
||||||
file.Type = "invalid_link"
|
file.Type = "invalid_link"
|
||||||
} else {
|
} else {
|
||||||
err := file.detectType(true, false, readHeader)
|
err := file.detectType(true, false, readHeader, calcImgRes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -600,7 +600,6 @@ var types = map[string]string{
|
||||||
".epub": "application/epub+zip",
|
".epub": "application/epub+zip",
|
||||||
}
|
}
|
||||||
|
|
||||||
//nolint:gochecknoinits
|
|
||||||
func init() {
|
func init() {
|
||||||
for ext, typ := range types {
|
for ext, typ := range types {
|
||||||
// skip errors
|
// skip errors
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,7 @@
|
||||||
DisableUsedPercentage: false,
|
DisableUsedPercentage: false,
|
||||||
EnableExec: true,
|
EnableExec: true,
|
||||||
EnableThumbs: true,
|
EnableThumbs: true,
|
||||||
|
LogoutPage: "",
|
||||||
LoginPage: true,
|
LoginPage: true,
|
||||||
Name: "",
|
Name: "",
|
||||||
NoAuth: false,
|
NoAuth: false,
|
||||||
|
|
|
||||||
|
|
@ -71,5 +71,5 @@
|
||||||
"vite-plugin-compression2": "^2.3.1",
|
"vite-plugin-compression2": "^2.3.1",
|
||||||
"vue-tsc": "^3.1.3"
|
"vue-tsc": "^3.1.3"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@10.22.0+sha512.bf049efe995b28f527fd2b41ae0474ce29186f7edcb3bf545087bd61fbbebb2bf75362d1307fda09c2d288e1e499787ac12d4fcb617a974718a6051f2eee741c"
|
"packageManager": "pnpm@10.28.0+sha512.05df71d1421f21399e053fde567cea34d446fa02c76571441bfc1c7956e98e363088982d940465fd34480d4d90a0668bc12362f8aa88000a64e83d0b0e47be48"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1726
frontend/pnpm-lock.yaml
generated
1726
frontend/pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load diff
|
|
@ -41,12 +41,12 @@ export function download(
|
||||||
let url = `${baseURL}/api/public/dl/${hash}`;
|
let url = `${baseURL}/api/public/dl/${hash}`;
|
||||||
|
|
||||||
if (files.length === 1) {
|
if (files.length === 1) {
|
||||||
url += encodeURIComponent(files[0]) + "?";
|
url += files[0] + "?";
|
||||||
} else {
|
} else {
|
||||||
let arg = "";
|
let arg = "";
|
||||||
|
|
||||||
for (const file of files) {
|
for (const file of files) {
|
||||||
arg += encodeURIComponent(file) + ",";
|
arg += file + ",";
|
||||||
}
|
}
|
||||||
|
|
||||||
arg = arg.substring(0, arg.length - 1);
|
arg = arg.substring(0, arg.length - 1);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
import { fetchURL, removePrefix } from "./utils";
|
import { fetchURL, removePrefix, StatusError } from "./utils";
|
||||||
import url from "../utils/url";
|
import url from "../utils/url";
|
||||||
|
|
||||||
export default async function search(base: string, query: string) {
|
export default async function search(
|
||||||
|
base: string,
|
||||||
|
query: string,
|
||||||
|
signal: AbortSignal,
|
||||||
|
callback: (item: ResourceItem) => void
|
||||||
|
) {
|
||||||
base = removePrefix(base);
|
base = removePrefix(base);
|
||||||
query = encodeURIComponent(query);
|
query = encodeURIComponent(query);
|
||||||
|
|
||||||
|
|
@ -9,19 +14,60 @@ export default async function search(base: string, query: string) {
|
||||||
base += "/";
|
base += "/";
|
||||||
}
|
}
|
||||||
|
|
||||||
const res = await fetchURL(`/api/search${base}?query=${query}`, {});
|
const res = await fetchURL(`/api/search${base}?query=${query}`, { signal });
|
||||||
|
if (!res.body) {
|
||||||
|
throw new StatusError("000 No connection", 0);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// Try streaming approach first (modern browsers)
|
||||||
|
if (res.body && typeof res.body.pipeThrough === "function") {
|
||||||
|
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
|
||||||
|
let buffer = "";
|
||||||
|
while (true) {
|
||||||
|
const { done, value } = await reader.read();
|
||||||
|
if (value) {
|
||||||
|
buffer += value;
|
||||||
|
}
|
||||||
|
const lines = buffer.split(/\n/);
|
||||||
|
let lastLine = lines.pop();
|
||||||
|
// Save incomplete last line
|
||||||
|
if (!lastLine) {
|
||||||
|
lastLine = "";
|
||||||
|
}
|
||||||
|
buffer = lastLine;
|
||||||
|
|
||||||
let data = await res.json();
|
for (const line of lines) {
|
||||||
|
if (line) {
|
||||||
data = data.map((item: ResourceItem & { dir: boolean }) => {
|
const item = JSON.parse(line) as ResourceItem;
|
||||||
item.url = `/files${base}` + url.encodePath(item.path);
|
item.url = `/files${base}` + url.encodePath(item.path);
|
||||||
|
if (item.isDir) {
|
||||||
if (item.dir) {
|
item.url += "/";
|
||||||
item.url += "/";
|
}
|
||||||
|
callback(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (done) break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Fallback for browsers without streaming support (e.g., Safari)
|
||||||
|
const text = await res.text();
|
||||||
|
const lines = text.split(/\n/);
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line) {
|
||||||
|
const item = JSON.parse(line) as ResourceItem;
|
||||||
|
item.url = `/files${base}` + url.encodePath(item.path);
|
||||||
|
if (item.isDir) {
|
||||||
|
item.url += "/";
|
||||||
|
}
|
||||||
|
callback(item);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
return item;
|
// Check if the error is an intentional cancellation
|
||||||
});
|
if (e instanceof Error && e.name === "AbortError") {
|
||||||
|
throw new StatusError("000 No connection", 0, true);
|
||||||
return data;
|
}
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,12 +8,13 @@ export async function get(id: number) {
|
||||||
return fetchJSON<IUser>(`/api/users/${id}`, {});
|
return fetchJSON<IUser>(`/api/users/${id}`, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function create(user: IUser) {
|
export async function create(user: IUser, currentPassword: string) {
|
||||||
const res = await fetchURL(`/api/users`, {
|
const res = await fetchURL(`/api/users`, {
|
||||||
method: "POST",
|
method: "POST",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
what: "user",
|
what: "user",
|
||||||
which: [],
|
which: [],
|
||||||
|
current_password: currentPassword,
|
||||||
data: user,
|
data: user,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
@ -25,19 +26,30 @@ export async function create(user: IUser) {
|
||||||
throw new StatusError(await res.text(), res.status);
|
throw new StatusError(await res.text(), res.status);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function update(user: Partial<IUser>, which = ["all"]) {
|
export async function update(
|
||||||
|
user: Partial<IUser>,
|
||||||
|
which = ["all"],
|
||||||
|
currentPassword: string | null = null
|
||||||
|
) {
|
||||||
await fetchURL(`/api/users/${user.id}`, {
|
await fetchURL(`/api/users/${user.id}`, {
|
||||||
method: "PUT",
|
method: "PUT",
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
what: "user",
|
what: "user",
|
||||||
which: which,
|
which: which,
|
||||||
|
...(currentPassword != null ? { current_password: currentPassword } : {}),
|
||||||
data: user,
|
data: user,
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function remove(id: number) {
|
export async function remove(
|
||||||
|
id: number,
|
||||||
|
currentPassword: string | null = null
|
||||||
|
) {
|
||||||
await fetchURL(`/api/users/${id}`, {
|
await fetchURL(`/api/users/${id}`, {
|
||||||
method: "DELETE",
|
method: "DELETE",
|
||||||
|
body: JSON.stringify({
|
||||||
|
...(currentPassword != null ? { current_password: currentPassword } : {}),
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
||||||
47
frontend/src/components/ContextMenu.vue
Normal file
47
frontend/src/components/ContextMenu.vue
Normal file
|
|
@ -0,0 +1,47 @@
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="context-menu"
|
||||||
|
ref="contextMenu"
|
||||||
|
v-show="show"
|
||||||
|
:style="{
|
||||||
|
top: `${props.pos.y}px`,
|
||||||
|
left: `${left}px`,
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch, computed, onUnmounted } from "vue";
|
||||||
|
|
||||||
|
const emit = defineEmits(["hide"]);
|
||||||
|
const props = defineProps<{ show: boolean; pos: { x: number; y: number } }>();
|
||||||
|
const contextMenu = ref<HTMLElement | null>(null);
|
||||||
|
|
||||||
|
const left = computed(() => {
|
||||||
|
return Math.min(
|
||||||
|
props.pos.x,
|
||||||
|
window.innerWidth - (contextMenu.value?.clientWidth ?? 0)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
const hideContextMenu = () => {
|
||||||
|
emit("hide");
|
||||||
|
};
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.show,
|
||||||
|
(val) => {
|
||||||
|
if (val) {
|
||||||
|
document.addEventListener("click", hideContextMenu);
|
||||||
|
} else {
|
||||||
|
document.removeEventListener("click", hideContextMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
document.removeEventListener("click", hideContextMenu);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
@ -5,10 +5,11 @@
|
||||||
v-if="active"
|
v-if="active"
|
||||||
class="action"
|
class="action"
|
||||||
@click="close"
|
@click="close"
|
||||||
:aria-label="$t('buttons.close')"
|
:aria-label="closeButtonTitle"
|
||||||
:title="$t('buttons.close')"
|
:title="closeButtonTitle"
|
||||||
>
|
>
|
||||||
<i class="material-icons">arrow_back</i>
|
<i v-if="ongoing" class="material-icons">stop_circle</i>
|
||||||
|
<i v-else class="material-icons">arrow_back</i>
|
||||||
</button>
|
</button>
|
||||||
<i v-else class="material-icons">search</i>
|
<i v-else class="material-icons">search</i>
|
||||||
<input
|
<input
|
||||||
|
|
@ -21,6 +22,15 @@
|
||||||
:aria-label="$t('search.search')"
|
:aria-label="$t('search.search')"
|
||||||
:placeholder="$t('search.search')"
|
:placeholder="$t('search.search')"
|
||||||
/>
|
/>
|
||||||
|
<i
|
||||||
|
v-show="ongoing"
|
||||||
|
class="material-icons spin"
|
||||||
|
style="display: inline-block"
|
||||||
|
>autorenew
|
||||||
|
</i>
|
||||||
|
<span style="margin-top: 5px" v-show="results.length > 0">
|
||||||
|
{{ results.length }}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="result" ref="result">
|
<div id="result" ref="result">
|
||||||
|
|
@ -57,9 +67,6 @@
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
<p id="renew">
|
|
||||||
<i class="material-icons spin">autorenew</i>
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -70,10 +77,11 @@ import { useLayoutStore } from "@/stores/layout";
|
||||||
|
|
||||||
import url from "@/utils/url";
|
import url from "@/utils/url";
|
||||||
import { search } from "@/api";
|
import { search } from "@/api";
|
||||||
import { computed, inject, onMounted, ref, watch } from "vue";
|
import { computed, inject, onMounted, ref, watch, onUnmounted } from "vue";
|
||||||
import { useI18n } from "vue-i18n";
|
import { useI18n } from "vue-i18n";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { storeToRefs } from "pinia";
|
import { storeToRefs } from "pinia";
|
||||||
|
import { StatusError } from "@/api/utils";
|
||||||
|
|
||||||
const boxes = {
|
const boxes = {
|
||||||
image: { label: "images", icon: "insert_photo" },
|
image: { label: "images", icon: "insert_photo" },
|
||||||
|
|
@ -84,6 +92,7 @@ const boxes = {
|
||||||
|
|
||||||
const layoutStore = useLayoutStore();
|
const layoutStore = useLayoutStore();
|
||||||
const fileStore = useFileStore();
|
const fileStore = useFileStore();
|
||||||
|
let searchAbortController = new AbortController();
|
||||||
|
|
||||||
const { currentPromptName } = storeToRefs(layoutStore);
|
const { currentPromptName } = storeToRefs(layoutStore);
|
||||||
|
|
||||||
|
|
@ -124,9 +133,7 @@ watch(currentPromptName, (newVal, oldVal) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(prompt, () => {
|
watch(prompt, () => {
|
||||||
if (results.value.length) {
|
reset();
|
||||||
reset();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// ...mapState(useFileStore, ["isListing"]),
|
// ...mapState(useFileStore, ["isListing"]),
|
||||||
|
|
@ -149,6 +156,10 @@ const filteredResults = computed(() => {
|
||||||
return results.value.slice(0, resultsCount.value);
|
return results.value.slice(0, resultsCount.value);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const closeButtonTitle = computed(() => {
|
||||||
|
return ongoing.value ? t("buttons.stopSearch") : t("buttons.close");
|
||||||
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
if (result.value === null) {
|
if (result.value === null) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -164,14 +175,23 @@ onMounted(() => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
abortLastSearch();
|
||||||
|
});
|
||||||
|
|
||||||
const open = () => {
|
const open = () => {
|
||||||
!active.value && layoutStore.showHover("search");
|
!active.value && layoutStore.showHover("search");
|
||||||
};
|
};
|
||||||
|
|
||||||
const close = (event: Event) => {
|
const close = (event: Event) => {
|
||||||
event.stopPropagation();
|
if (ongoing.value) {
|
||||||
event.preventDefault();
|
abortLastSearch();
|
||||||
layoutStore.closeHovers();
|
ongoing.value = false;
|
||||||
|
} else {
|
||||||
|
event.stopPropagation();
|
||||||
|
event.preventDefault();
|
||||||
|
layoutStore.closeHovers();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const keyup = (event: KeyboardEvent) => {
|
const keyup = (event: KeyboardEvent) => {
|
||||||
|
|
@ -188,11 +208,16 @@ const init = (string: string) => {
|
||||||
};
|
};
|
||||||
|
|
||||||
const reset = () => {
|
const reset = () => {
|
||||||
|
abortLastSearch();
|
||||||
ongoing.value = false;
|
ongoing.value = false;
|
||||||
resultsCount.value = 50;
|
resultsCount.value = 50;
|
||||||
results.value = [];
|
results.value = [];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const abortLastSearch = () => {
|
||||||
|
searchAbortController.abort();
|
||||||
|
};
|
||||||
|
|
||||||
const submit = async (event: Event) => {
|
const submit = async (event: Event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
|
|
@ -208,8 +233,16 @@ const submit = async (event: Event) => {
|
||||||
ongoing.value = true;
|
ongoing.value = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
results.value = await search(path, prompt.value);
|
abortLastSearch();
|
||||||
|
searchAbortController = new AbortController();
|
||||||
|
results.value = [];
|
||||||
|
await search(path, prompt.value, searchAbortController.signal, (item) =>
|
||||||
|
results.value.push(item)
|
||||||
|
);
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
|
if (error instanceof StatusError && error.is_canceled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$showError(error);
|
$showError(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,7 @@
|
||||||
</template>
|
</template>
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<router-link
|
<router-link
|
||||||
|
v-if="!hideLoginButton"
|
||||||
class="action"
|
class="action"
|
||||||
to="/login"
|
to="/login"
|
||||||
:aria-label="$t('sidebar.login')"
|
:aria-label="$t('sidebar.login')"
|
||||||
|
|
@ -124,9 +125,11 @@ import * as auth from "@/utils/auth";
|
||||||
import {
|
import {
|
||||||
version,
|
version,
|
||||||
signup,
|
signup,
|
||||||
|
hideLoginButton,
|
||||||
disableExternal,
|
disableExternal,
|
||||||
disableUsedPercentage,
|
disableUsedPercentage,
|
||||||
noAuth,
|
noAuth,
|
||||||
|
logoutPage,
|
||||||
loginPage,
|
loginPage,
|
||||||
} from "@/utils/constants";
|
} from "@/utils/constants";
|
||||||
import { files as api } from "@/api";
|
import { files as api } from "@/api";
|
||||||
|
|
@ -153,10 +156,11 @@ export default {
|
||||||
return this.currentPromptName === "sidebar";
|
return this.currentPromptName === "sidebar";
|
||||||
},
|
},
|
||||||
signup: () => signup,
|
signup: () => signup,
|
||||||
|
hideLoginButton: () => hideLoginButton,
|
||||||
version: () => version,
|
version: () => version,
|
||||||
disableExternal: () => disableExternal,
|
disableExternal: () => disableExternal,
|
||||||
disableUsedPercentage: () => disableUsedPercentage,
|
disableUsedPercentage: () => disableUsedPercentage,
|
||||||
canLogout: () => !noAuth && loginPage,
|
canLogout: () => !noAuth && (loginPage || logoutPage !== "/login"),
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
|
...mapActions(useLayoutStore, ["closeHovers", "showHover"]),
|
||||||
|
|
|
||||||
252
frontend/src/components/files/CsvViewer.vue
Normal file
252
frontend/src/components/files/CsvViewer.vue
Normal file
|
|
@ -0,0 +1,252 @@
|
||||||
|
<template>
|
||||||
|
<div class="csv-viewer">
|
||||||
|
<div v-if="displayError" class="csv-error">
|
||||||
|
<i class="material-icons">error</i>
|
||||||
|
<p>{{ displayError }}</p>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="data.headers.length === 0" class="csv-empty">
|
||||||
|
<i class="material-icons">description</i>
|
||||||
|
<p>{{ $t("files.lonely") }}</p>
|
||||||
|
</div>
|
||||||
|
<div v-else class="csv-table-container" @wheel.stop @touchmove.stop>
|
||||||
|
<table class="csv-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th v-for="(header, index) in data.headers" :key="index">
|
||||||
|
{{ header || `Column ${index + 1}` }}
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr v-for="(row, rowIndex) in data.rows" :key="rowIndex">
|
||||||
|
<td v-for="(cell, cellIndex) in row" :key="cellIndex">
|
||||||
|
{{ cell }}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<div class="csv-footer">
|
||||||
|
<div class="csv-info" v-if="data.rows.length > 100">
|
||||||
|
<i class="material-icons">info</i>
|
||||||
|
<span>
|
||||||
|
{{ $t("files.showingRows", { count: data.rows.length }) }}</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
<div class="column-separator">
|
||||||
|
<label for="columnSeparator">{{ $t("files.columnSeparator") }}</label>
|
||||||
|
<select
|
||||||
|
id="columnSeparator"
|
||||||
|
class="input input--block"
|
||||||
|
v-model="columnSeparator"
|
||||||
|
>
|
||||||
|
<option :value="[',']">
|
||||||
|
{{ $t("files.csvSeparators.comma") }}
|
||||||
|
</option>
|
||||||
|
<option :value="[';']">
|
||||||
|
{{ $t("files.csvSeparators.semicolon") }}
|
||||||
|
</option>
|
||||||
|
<option :value="[',', ';']">
|
||||||
|
{{ $t("files.csvSeparators.both") }}
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { parseCSV, type CsvData } from "@/utils/csv";
|
||||||
|
import { computed, ref } from "vue";
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
content: string;
|
||||||
|
error?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
|
error: "",
|
||||||
|
});
|
||||||
|
|
||||||
|
const columnSeparator = ref([","]);
|
||||||
|
|
||||||
|
const data = computed<CsvData>(() => {
|
||||||
|
try {
|
||||||
|
return parseCSV(props.content, columnSeparator.value);
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to parse CSV:", e);
|
||||||
|
return { headers: [], rows: [] };
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const displayError = computed(() => {
|
||||||
|
// External error takes priority (e.g., file too large)
|
||||||
|
if (props.error) {
|
||||||
|
return props.error;
|
||||||
|
}
|
||||||
|
// Check for parse errors
|
||||||
|
if (
|
||||||
|
props.content &&
|
||||||
|
props.content.trim().length > 0 &&
|
||||||
|
data.value.headers.length === 0
|
||||||
|
) {
|
||||||
|
return "Failed to parse CSV file";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.csv-viewer {
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
background-color: var(--surfacePrimary);
|
||||||
|
color: var(--textSecondary);
|
||||||
|
padding: 1rem;
|
||||||
|
padding-top: 4em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-error,
|
||||||
|
.csv-empty {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: 100%;
|
||||||
|
gap: 1rem;
|
||||||
|
color: var(--textPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-error i,
|
||||||
|
.csv-empty i {
|
||||||
|
font-size: 4rem;
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-error p,
|
||||||
|
.csv-empty p {
|
||||||
|
font-size: 1.1rem;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table-container {
|
||||||
|
flex: 1;
|
||||||
|
overflow: auto;
|
||||||
|
background-color: var(--surfacePrimary);
|
||||||
|
border-radius: 4px;
|
||||||
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Scrollbar styling for better visibility */
|
||||||
|
.csv-table-container::-webkit-scrollbar {
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table-container::-webkit-scrollbar-track {
|
||||||
|
background: var(--background);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table-container::-webkit-scrollbar-thumb {
|
||||||
|
background: var(--borderSecondary);
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table-container::-webkit-scrollbar-thumb:hover {
|
||||||
|
background: var(--textPrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table {
|
||||||
|
width: 100%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
font-size: 0.875rem;
|
||||||
|
background-color: var(--surfacePrimary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table thead {
|
||||||
|
position: sticky;
|
||||||
|
top: 0;
|
||||||
|
z-index: 10;
|
||||||
|
background-color: var(--surfaceSecondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table th {
|
||||||
|
padding: 0.875rem 1rem;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: 600;
|
||||||
|
border-bottom: 2px solid var(--borderSecondary);
|
||||||
|
background-color: var(--surfaceSecondary);
|
||||||
|
white-space: nowrap;
|
||||||
|
color: var(--textSecondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table td {
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
text-align: left;
|
||||||
|
border-bottom: 1px solid var(--borderPrimary);
|
||||||
|
white-space: nowrap;
|
||||||
|
max-width: 400px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
color: var(--textSecondary);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table tbody tr:nth-child(even) {
|
||||||
|
background-color: var(--background);
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-table tbody tr:hover {
|
||||||
|
background-color: var(--hover);
|
||||||
|
transition: background-color 0.15s ease;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-footer {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
gap: 1rem;
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-footer > :only-child {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-info {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
padding: 0.75rem 1rem;
|
||||||
|
margin-top: 0.5rem;
|
||||||
|
background-color: var(--surfaceSecondary);
|
||||||
|
border-radius: 4px;
|
||||||
|
border-left: 3px solid var(--blue);
|
||||||
|
color: var(--textSecondary);
|
||||||
|
font-size: 0.875rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-separator {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-separator > label {
|
||||||
|
font-size: small;
|
||||||
|
text-align: end;
|
||||||
|
}
|
||||||
|
|
||||||
|
.column-separator > select {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.csv-info i {
|
||||||
|
font-size: 1.2rem;
|
||||||
|
color: var(--blue);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -20,6 +20,7 @@
|
||||||
:aria-label="name"
|
:aria-label="name"
|
||||||
:aria-selected="isSelected"
|
:aria-selected="isSelected"
|
||||||
:data-ext="getExtension(name).toLowerCase()"
|
:data-ext="getExtension(name).toLowerCase()"
|
||||||
|
@contextmenu="contextMenu"
|
||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
<img
|
<img
|
||||||
|
|
@ -239,6 +240,17 @@ const itemClick = (event: Event | KeyboardEvent) => {
|
||||||
else click(event);
|
else click(event);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const contextMenu = (event: MouseEvent) => {
|
||||||
|
event.preventDefault();
|
||||||
|
if (
|
||||||
|
fileStore.selected.length === 0 ||
|
||||||
|
event.ctrlKey ||
|
||||||
|
fileStore.selected.indexOf(props.index) === -1
|
||||||
|
) {
|
||||||
|
click(event);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const click = (event: Event | KeyboardEvent) => {
|
const click = (event: Event | KeyboardEvent) => {
|
||||||
if (!singleClick.value && fileStore.selectedCount !== 0)
|
if (!singleClick.value && fileStore.selectedCount !== 0)
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
@ -253,7 +265,15 @@ const click = (event: Event | KeyboardEvent) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fileStore.selected.indexOf(props.index) !== -1) {
|
if (fileStore.selected.indexOf(props.index) !== -1) {
|
||||||
fileStore.removeSelected(props.index);
|
if (
|
||||||
|
(event as KeyboardEvent).ctrlKey ||
|
||||||
|
(event as KeyboardEvent).metaKey ||
|
||||||
|
fileStore.multiple
|
||||||
|
) {
|
||||||
|
fileStore.removeSelected(props.index);
|
||||||
|
} else {
|
||||||
|
fileStore.selected = [props.index];
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -279,7 +299,6 @@ const click = (event: Event | KeyboardEvent) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
!singleClick.value &&
|
|
||||||
!(event as KeyboardEvent).ctrlKey &&
|
!(event as KeyboardEvent).ctrlKey &&
|
||||||
!(event as KeyboardEvent).metaKey &&
|
!(event as KeyboardEvent).metaKey &&
|
||||||
!fileStore.multiple
|
!fileStore.multiple
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,8 @@ export default {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.$router.push({ path: this.dest });
|
if (this.user.redirectAfterCopyMove)
|
||||||
|
this.$router.push({ path: this.dest });
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
buttons.done("copy");
|
buttons.done("copy");
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref, computed, watch, nextTick, defineProps } from "vue";
|
import { ref, computed, watch, nextTick } from "vue";
|
||||||
import { useRoute } from "vue-router";
|
import { useRoute } from "vue-router";
|
||||||
import { useFileStore } from "@/stores/file";
|
import { useFileStore } from "@/stores/file";
|
||||||
import url from "@/utils/url";
|
import url from "@/utils/url";
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
<p>{{ $t("prompts.moveMessage") }}</p>
|
||||||
<file-list
|
<file-list
|
||||||
ref="fileList"
|
ref="fileList"
|
||||||
@update:selected="(val) => (dest = val)"
|
@update:selected="(val) => (dest = val)"
|
||||||
|
|
@ -78,7 +79,7 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useFileStore, ["req", "selected"]),
|
...mapState(useFileStore, ["req", "selected"]),
|
||||||
...mapState(useAuthStore, ["user"]),
|
...mapState(useAuthStore, ["user"]),
|
||||||
...mapWritableState(useFileStore, ["preselect"]),
|
...mapWritableState(useFileStore, ["reload", "preselect"]),
|
||||||
excludedFolders() {
|
excludedFolders() {
|
||||||
return this.selected
|
return this.selected
|
||||||
.filter((idx) => this.req.items[idx].isDir)
|
.filter((idx) => this.req.items[idx].isDir)
|
||||||
|
|
@ -107,7 +108,9 @@ export default {
|
||||||
.then(() => {
|
.then(() => {
|
||||||
buttons.success("move");
|
buttons.success("move");
|
||||||
this.preselect = removePrefix(items[0].to);
|
this.preselect = removePrefix(items[0].to);
|
||||||
this.$router.push({ path: this.dest });
|
if (this.user.redirectAfterCopyMove)
|
||||||
|
this.$router.push({ path: this.dest });
|
||||||
|
else this.reload = true;
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
buttons.done("move");
|
buttons.done("move");
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@
|
||||||
<th>{{ $t("settings.shareDuration") }}</th>
|
<th>{{ $t("settings.shareDuration") }}</th>
|
||||||
<th></th>
|
<th></th>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th></th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr v-for="link in links" :key="link.hash">
|
<tr v-for="link in links" :key="link.hash">
|
||||||
|
|
@ -24,7 +25,7 @@
|
||||||
</td>
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<button
|
<button
|
||||||
class="action copy-clipboard"
|
class="action"
|
||||||
:aria-label="$t('buttons.copyToClipboard')"
|
:aria-label="$t('buttons.copyToClipboard')"
|
||||||
:title="$t('buttons.copyToClipboard')"
|
:title="$t('buttons.copyToClipboard')"
|
||||||
@click="copyToClipboard(buildLink(link))"
|
@click="copyToClipboard(buildLink(link))"
|
||||||
|
|
@ -32,6 +33,17 @@
|
||||||
<i class="material-icons">content_paste</i>
|
<i class="material-icons">content_paste</i>
|
||||||
</button>
|
</button>
|
||||||
</td>
|
</td>
|
||||||
|
<td class="small">
|
||||||
|
<button
|
||||||
|
class="action"
|
||||||
|
:aria-label="$t('buttons.copyDownloadLinkToClipboard')"
|
||||||
|
:title="$t('buttons.copyDownloadLinkToClipboard')"
|
||||||
|
:disabled="!!link.password_hash"
|
||||||
|
@click="copyToClipboard(buildDownloadLink(link))"
|
||||||
|
>
|
||||||
|
<i class="material-icons">content_paste_go</i>
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
<td class="small">
|
<td class="small">
|
||||||
<button
|
<button
|
||||||
class="action"
|
class="action"
|
||||||
|
|
@ -132,7 +144,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { mapActions, mapState } from "pinia";
|
import { mapActions, mapState } from "pinia";
|
||||||
import { useFileStore } from "@/stores/file";
|
import { useFileStore } from "@/stores/file";
|
||||||
import { share as api } from "@/api";
|
import * as api from "@/api/index";
|
||||||
import dayjs from "dayjs";
|
import dayjs from "dayjs";
|
||||||
import { useLayoutStore } from "@/stores/layout";
|
import { useLayoutStore } from "@/stores/layout";
|
||||||
import { copy } from "@/utils/clipboard";
|
import { copy } from "@/utils/clipboard";
|
||||||
|
|
@ -172,7 +184,7 @@ export default {
|
||||||
},
|
},
|
||||||
async beforeMount() {
|
async beforeMount() {
|
||||||
try {
|
try {
|
||||||
const links = await api.get(this.url);
|
const links = await api.share.get(this.url);
|
||||||
this.links = links;
|
this.links = links;
|
||||||
this.sort();
|
this.sort();
|
||||||
|
|
||||||
|
|
@ -211,9 +223,14 @@ export default {
|
||||||
let res = null;
|
let res = null;
|
||||||
|
|
||||||
if (!this.time) {
|
if (!this.time) {
|
||||||
res = await api.create(this.url, this.password);
|
res = await api.share.create(this.url, this.password);
|
||||||
} else {
|
} else {
|
||||||
res = await api.create(this.url, this.password, this.time, this.unit);
|
res = await api.share.create(
|
||||||
|
this.url,
|
||||||
|
this.password,
|
||||||
|
this.time,
|
||||||
|
this.unit
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.links.push(res);
|
this.links.push(res);
|
||||||
|
|
@ -231,7 +248,7 @@ export default {
|
||||||
deleteLink: async function (event, link) {
|
deleteLink: async function (event, link) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
try {
|
try {
|
||||||
await api.remove(link.hash);
|
await api.share.remove(link.hash);
|
||||||
this.links = this.links.filter((item) => item.hash !== link.hash);
|
this.links = this.links.filter((item) => item.hash !== link.hash);
|
||||||
|
|
||||||
if (this.links.length == 0) {
|
if (this.links.length == 0) {
|
||||||
|
|
@ -245,7 +262,16 @@ export default {
|
||||||
return dayjs(time * 1000).fromNow();
|
return dayjs(time * 1000).fromNow();
|
||||||
},
|
},
|
||||||
buildLink(share) {
|
buildLink(share) {
|
||||||
return api.getShareURL(share);
|
return api.share.getShareURL(share);
|
||||||
|
},
|
||||||
|
buildDownloadLink(share) {
|
||||||
|
return api.pub.getDownloadURL(
|
||||||
|
{
|
||||||
|
hash: share.hash,
|
||||||
|
path: "",
|
||||||
|
},
|
||||||
|
true
|
||||||
|
);
|
||||||
},
|
},
|
||||||
sort() {
|
sort() {
|
||||||
this.links = this.links.sort((a, b) => {
|
this.links = this.links.sort((a, b) => {
|
||||||
|
|
|
||||||
|
|
@ -15,10 +15,8 @@ export default {
|
||||||
data() {
|
data() {
|
||||||
const dataObj = {};
|
const dataObj = {};
|
||||||
const locales = {
|
const locales = {
|
||||||
he: "עברית",
|
|
||||||
hr: "Hrvatski",
|
|
||||||
hu: "Magyar",
|
|
||||||
ar: "العربية",
|
ar: "العربية",
|
||||||
|
bg: "български език",
|
||||||
ca: "Català",
|
ca: "Català",
|
||||||
cs: "Čeština",
|
cs: "Čeština",
|
||||||
de: "Deutsch",
|
de: "Deutsch",
|
||||||
|
|
@ -26,15 +24,18 @@ export default {
|
||||||
en: "English",
|
en: "English",
|
||||||
es: "Español",
|
es: "Español",
|
||||||
fr: "Français",
|
fr: "Français",
|
||||||
|
he: "עברית",
|
||||||
|
hr: "Hrvatski",
|
||||||
|
hu: "Magyar",
|
||||||
is: "Icelandic",
|
is: "Icelandic",
|
||||||
it: "Italiano",
|
it: "Italiano",
|
||||||
ja: "日本語",
|
ja: "日本語",
|
||||||
ko: "한국어",
|
ko: "한국어",
|
||||||
"nl-be": "Dutch (Belgium)",
|
|
||||||
no: "Norsk",
|
no: "Norsk",
|
||||||
|
"nl-be": "Dutch (Belgium)",
|
||||||
pl: "Polski",
|
pl: "Polski",
|
||||||
"pt-br": "Português",
|
"pt-br": "Português (Brasil)",
|
||||||
pt: "Português (Brasil)",
|
pt: "Português (Portugal)",
|
||||||
ro: "Romanian",
|
ro: "Romanian",
|
||||||
ru: "Русский",
|
ru: "Русский",
|
||||||
sk: "Slovenčina",
|
sk: "Slovenčina",
|
||||||
|
|
|
||||||
|
|
@ -185,3 +185,7 @@ html[dir="rtl"] .breadcrumbs a {
|
||||||
.vfm-modal {
|
.vfm-modal {
|
||||||
z-index: 9999999 !important;
|
z-index: 9999999 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
body > div[style*="z-index: 9990"] {
|
||||||
|
z-index: 10000 !important;
|
||||||
|
}
|
||||||
|
|
|
||||||
21
frontend/src/css/context-menu.css
Normal file
21
frontend/src/css/context-menu.css
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
.context-menu {
|
||||||
|
position: absolute;
|
||||||
|
background: var(--surfacePrimary);
|
||||||
|
min-width: 180px;
|
||||||
|
max-width: 220px;
|
||||||
|
border: 1px solid var(--borderSecondary);
|
||||||
|
box-shadow: 0 2px 4px var(--borderPrimary);
|
||||||
|
z-index: 999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu .action {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
border-radius: 0;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.context-menu .action .counter {
|
||||||
|
left: 1.75em;
|
||||||
|
}
|
||||||
|
|
@ -17,6 +17,7 @@
|
||||||
@import "./mobile.css";
|
@import "./mobile.css";
|
||||||
@import "./epubReader.css";
|
@import "./epubReader.css";
|
||||||
@import "./mdPreview.css";
|
@import "./mdPreview.css";
|
||||||
|
@import "./context-menu.css";
|
||||||
|
|
||||||
/* For testing only
|
/* For testing only
|
||||||
:focus {
|
:focus {
|
||||||
|
|
@ -97,7 +98,8 @@ main .spinner .bounce2 {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action.disabled {
|
.action.disabled,
|
||||||
|
.action[disabled] {
|
||||||
opacity: 0.2;
|
opacity: 0.2;
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,7 @@
|
||||||
"ok": "موافق",
|
"ok": "موافق",
|
||||||
"permalink": "الحصول على رابط دائم",
|
"permalink": "الحصول على رابط دائم",
|
||||||
"previous": "السابق",
|
"previous": "السابق",
|
||||||
"preview": "Preview",
|
"preview": "معاينة",
|
||||||
"publish": "نشر",
|
"publish": "نشر",
|
||||||
"rename": "إعادة تسمية",
|
"rename": "إعادة تسمية",
|
||||||
"replace": "استبدال",
|
"replace": "استبدال",
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "رفع",
|
"upload": "رفع",
|
||||||
"openFile": "فتح الملف",
|
"openFile": "فتح الملف",
|
||||||
"discardChanges": "إلغاء التغييرات",
|
"discardChanges": "إلغاء التغييرات",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "توقف عن البحث",
|
||||||
|
"saveChanges": "حفظ التغييرات",
|
||||||
|
"editAsText": "تعديل على شكل نص",
|
||||||
|
"increaseFontSize": "زيادة حجم الخط",
|
||||||
|
"decreaseFontSize": "تصغير حجم الخط"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "تحميل الملف",
|
"downloadFile": "تحميل الملف",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "الترتيب بآخر تعديل",
|
"sortByLastModified": "الترتيب بآخر تعديل",
|
||||||
"sortByName": "الترتيب باﻹسم",
|
"sortByName": "الترتيب باﻹسم",
|
||||||
"sortBySize": "الترتيب بالحجم",
|
"sortBySize": "الترتيب بالحجم",
|
||||||
"noPreview": "لا يوجد عرض مسبق لهذا الملف."
|
"noPreview": "لا يوجد عرض مسبق لهذا الملف.",
|
||||||
|
"csvTooLarge": "حجم الملف اكبر من (<5MB), يرجى تحميل الملف للمعاينة",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "حدد الملف أو المجلد",
|
"click": "حدد الملف أو المجلد",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "إسم المستخدم",
|
"username": "إسم المستخدم",
|
||||||
"usernameTaken": "إسم المستخدم غير متاح",
|
"usernameTaken": "إسم المستخدم غير متاح",
|
||||||
"wrongCredentials": "بيانات دخول خاطئة",
|
"wrongCredentials": "بيانات دخول خاطئة",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -124,7 +138,7 @@
|
||||||
"filesSelected": "تم تحديد {count} ملفات.",
|
"filesSelected": "تم تحديد {count} ملفات.",
|
||||||
"lastModified": "آخر تعديل",
|
"lastModified": "آخر تعديل",
|
||||||
"move": "نقل",
|
"move": "نقل",
|
||||||
"moveMessage": "إختر مكان جديد للملفات أو المجلدات المراد نقلها:",
|
"moveMessage": "اختر منزلاً جديداً لملفك (ملفاتك)/مجلدك (مجلداتك):",
|
||||||
"newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.",
|
"newArchetype": "إنشاء منشور من المنشور اﻷصلي. الملف سيتم انشاءه في مجلد المحتويات.",
|
||||||
"newDir": "مجلد جديد",
|
"newDir": "مجلد جديد",
|
||||||
"newDirMessage": "أدخل اسم المجلد الجديد.",
|
"newDirMessage": "أدخل اسم المجلد الجديد.",
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "إنشاء ملفات و مجلدات جديدة",
|
"allowNew": "إنشاء ملفات و مجلدات جديدة",
|
||||||
"allowPublish": "نشر مقالات و صفحات جديدة",
|
"allowPublish": "نشر مقالات و صفحات جديدة",
|
||||||
"allowSignup": "اسمح للمستخدمين بالاشتراك",
|
"allowSignup": "اسمح للمستخدمين بالاشتراك",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(أتركه فارغاً إن لم ترد تغييره)",
|
"avoidChanges": "(أتركه فارغاً إن لم ترد تغييره)",
|
||||||
"branding": "الشعار",
|
"branding": "الشعار",
|
||||||
"brandingDirectoryPath": "مسار مجلد الشعار",
|
"brandingDirectoryPath": "مسار مجلد الشعار",
|
||||||
|
|
@ -174,15 +189,15 @@
|
||||||
"commandRunner": "منفذ اﻷوامر",
|
"commandRunner": "منفذ اﻷوامر",
|
||||||
"commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.",
|
"commandRunnerHelp": "هنا بإمكانك تعيين اﻷوامر التي سيتم تنفيذها في اﻷحداث المسماة. يجب كتابة أمر واحد في كل سطر. ستكون المتغيرات البيئية (env) {0} و {1} متاحة، حيث {0} نسبي لـ {1}. لمزيد من المعلومات حول هذه الميزة و المتغيرات البيئية المتاحة، يرجى قراءة {2}.",
|
||||||
"commandsUpdated": "تم تحديث اﻷوامر",
|
"commandsUpdated": "تم تحديث اﻷوامر",
|
||||||
"createUserDir": "إنشاء مجلد المستخدم (home) تلقائياً عند إنشاء مستخدم جديد",
|
"createUserDir": "إنشاء مجلد المستخدم الرئيسي تلقائياً عند إنشاء مستخدم جديد",
|
||||||
"minimumPasswordLength": "Minimum password length",
|
"minimumPasswordLength": "Minimum password length",
|
||||||
"tusUploads": "التحميلات المتقطعة",
|
"tusUploads": "التحميلات المتقطعة",
|
||||||
"tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.",
|
"tusUploadsHelp": "يدعم متصفح الملفات تحميل الملفات المتقطعة، مما يسمح بتحميلات الملفات بشكل فعال و موثوق و قابلة للمتابغة و متقطعة حتى على الشبكات غير الموثوقة.",
|
||||||
"tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.",
|
"tusUploadsChunkSize": "يشير إلى الحد اﻷقصى لحجم الطلب (سيتم استخدام التحميل المباشر للتحميلات صغيرة الخحم). يمكنك إدخال عدد صحيح عادي يدل على الحجم بوحدة البايت أو نمظ مثل10MB, 1GB, إلخ.",
|
||||||
"tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.",
|
"tusUploadsRetryCount": "عدد مرات إعادة المحاولة إذا فشلت عملية تحميل القطعة.",
|
||||||
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم (home)",
|
"userHomeBasePath": "المسار الرئيسي لمجلد المستخدم الرئيسي",
|
||||||
"userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً",
|
"userScopeGenerationPlaceholder": "سيتم تعيين نطاق المستخدم تلقائياً",
|
||||||
"createUserHomeDirectory": "إنشاء مجلد المستخدم (home)",
|
"createUserHomeDirectory": "إنشاء مجلد المستخدم الرئيسي",
|
||||||
"customStylesheet": "ستايل مخصص",
|
"customStylesheet": "ستايل مخصص",
|
||||||
"defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.",
|
"defaultUserDescription": "هذه اﻹعدادات اﻹفتراضية للمستخدمين الجدد.",
|
||||||
"disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)",
|
"disableExternalLinks": "تعطيل الروابط الخارجية (بإسثناء الوثائق)",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "الصلاحيات",
|
"permissions": "الصلاحيات",
|
||||||
"permissionsHelp": "يمكنك تعيين المستخدم كـ \"مدير\" أو تحديد الصلاحيات بشكل منفرد.\n إذا قمت بتحديد المستخدم كـ \"مدير\"، باقي الخيارات سيتم تحديدها تلقائياً.\n إدارة المستخدمين تبقى صلاحية فريدة للـ \"مدير\" فقط.\n",
|
"permissionsHelp": "يمكنك تعيين المستخدم كـ \"مدير\" أو تحديد الصلاحيات بشكل منفرد.\n إذا قمت بتحديد المستخدم كـ \"مدير\"، باقي الخيارات سيتم تحديدها تلقائياً.\n إدارة المستخدمين تبقى صلاحية فريدة للـ \"مدير\" فقط.\n",
|
||||||
"profileSettings": "إعدادات الحساب",
|
"profileSettings": "إعدادات الحساب",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "منع الوصول إلى الملفات التي تبدأ بنقطة مثل (.git، و .gitignore) في كل مجلد.\n",
|
"ruleExample1": "منع الوصول إلى الملفات التي تبدأ بنقطة مثل (.git، و .gitignore) في كل مجلد.\n",
|
||||||
"ruleExample2": "منع الوصول إلى الملف المسمى Caddyfile في نطاق الجذر.",
|
"ruleExample2": "منع الوصول إلى الملف المسمى Caddyfile في نطاق الجذر.",
|
||||||
"rules": "المجموعات",
|
"rules": "المجموعات",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "إدارة المستخدمين",
|
"userManagement": "إدارة المستخدمين",
|
||||||
"userUpdated": "تم تعديل المستخدم",
|
"userUpdated": "تم تعديل المستخدم",
|
||||||
"username": "إسم المستخدم",
|
"username": "إسم المستخدم",
|
||||||
"users": "المستخدمين"
|
"users": "المستخدمين",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "مساعدة",
|
"help": "مساعدة",
|
||||||
|
|
|
||||||
288
frontend/src/i18n/bg.json
Normal file
288
frontend/src/i18n/bg.json
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
{
|
||||||
|
"buttons": {
|
||||||
|
"cancel": "Отмени",
|
||||||
|
"clear": "Изчисти",
|
||||||
|
"close": "Затвори",
|
||||||
|
"continue": "Продължи",
|
||||||
|
"copy": "Копирай",
|
||||||
|
"copyFile": "Копирай файл",
|
||||||
|
"copyToClipboard": "Копирай в клипборда",
|
||||||
|
"copyDownloadLinkToClipboard": "Копирай линк за сваляне в клипборда",
|
||||||
|
"create": "Създай",
|
||||||
|
"delete": "Изтрий",
|
||||||
|
"download": "Свали",
|
||||||
|
"file": "Файл",
|
||||||
|
"folder": "Папка",
|
||||||
|
"fullScreen": "Превключване на цял екран",
|
||||||
|
"hideDotfiles": "Скрий файлове започващи с точка",
|
||||||
|
"info": "Информация",
|
||||||
|
"more": "Повече",
|
||||||
|
"move": "Премести",
|
||||||
|
"moveFile": "Премести файл",
|
||||||
|
"new": "Нов",
|
||||||
|
"next": "Следващ",
|
||||||
|
"ok": "Потвърди",
|
||||||
|
"permalink": "Вземи постоянен линк",
|
||||||
|
"previous": "Предишен",
|
||||||
|
"preview": "Преглед",
|
||||||
|
"publish": "Публикуване",
|
||||||
|
"rename": "Преименуване",
|
||||||
|
"replace": "Замяна",
|
||||||
|
"reportIssue": "Докладвай проблем",
|
||||||
|
"save": "Запис",
|
||||||
|
"schedule": "График",
|
||||||
|
"search": "Търсене",
|
||||||
|
"select": "Избери",
|
||||||
|
"selectMultiple": "Избери няколко",
|
||||||
|
"share": "Сподели",
|
||||||
|
"shell": "Превключване на терминала",
|
||||||
|
"submit": "Изпрати",
|
||||||
|
"switchView": "Смени изгледа",
|
||||||
|
"toggleSidebar": "Превключване на страничен панел",
|
||||||
|
"update": "Обнови",
|
||||||
|
"upload": "Качи",
|
||||||
|
"openFile": "Отвори файл",
|
||||||
|
"discardChanges": "Изчисти",
|
||||||
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Запиши промените",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"downloadFile": "Свали файл",
|
||||||
|
"downloadFolder": "Свали папка",
|
||||||
|
"downloadSelected": "Свали избраното"
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"abortUpload": "Сигурни ли сте, че искате да прекратите?"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"forbidden": "Нямате право на достъп.",
|
||||||
|
"internal": "Взникна грешка.",
|
||||||
|
"notFound": "Локацията не може да бъде достигната.",
|
||||||
|
"connection": "Сървъра не може да бъде достигнат."
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"body": "Тяло",
|
||||||
|
"closePreview": "Затвори прегледа",
|
||||||
|
"files": "Файлове",
|
||||||
|
"folders": "Папки",
|
||||||
|
"home": "Начало",
|
||||||
|
"lastModified": "Последна промяна",
|
||||||
|
"loading": "Зареждане ...",
|
||||||
|
"lonely": "Тук е самотно ...",
|
||||||
|
"metadata": "Метаданни",
|
||||||
|
"multipleSelectionEnabled": "Множествения избор е разрешен",
|
||||||
|
"name": "Име",
|
||||||
|
"size": "Размер",
|
||||||
|
"sortByLastModified": "Подредба по последна промяна",
|
||||||
|
"sortByName": "Подредба по име",
|
||||||
|
"sortBySize": "Подредба по размер",
|
||||||
|
"noPreview": "За този файл не е наличен преглед.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"click": "избери файл или директория",
|
||||||
|
"ctrl": {
|
||||||
|
"click": "избери файлове или директории",
|
||||||
|
"f": "отваря търсене",
|
||||||
|
"s": "запиши файл или свари директория тук"
|
||||||
|
},
|
||||||
|
"del": "изтрий избраните",
|
||||||
|
"doubleClick": "отвори файл или директория",
|
||||||
|
"esc": "изтрий избраното и/или затвори",
|
||||||
|
"f1": "тази информация",
|
||||||
|
"f2": "преименувай файл",
|
||||||
|
"help": "Помощ"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"createAnAccount": "Създай акаунт",
|
||||||
|
"loginInstead": "Вече имаш акаунт",
|
||||||
|
"password": "Парола",
|
||||||
|
"passwordConfirm": "Парола Потвърждение",
|
||||||
|
"passwordsDontMatch": "Паролите не съвпадат",
|
||||||
|
"signup": "Абониране",
|
||||||
|
"submit": "Вход",
|
||||||
|
"username": "Потребителско име",
|
||||||
|
"usernameTaken": "Потребителското име вече се използва",
|
||||||
|
"wrongCredentials": "Грешни потребителско име и/или парола",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
|
"logout_reasons": {
|
||||||
|
"inactivity": "Бяхте разлогнати поради неактивност"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permanent": "Постоянен",
|
||||||
|
"prompts": {
|
||||||
|
"copy": "Копирай",
|
||||||
|
"copyMessage": "Избери къде да копираш файловете си:",
|
||||||
|
"currentlyNavigating": "В момента навигира към:",
|
||||||
|
"deleteMessageMultiple": "Сигурни ли сте, че искате да изтриете {count} файл(а)?",
|
||||||
|
"deleteMessageSingle": "Сигурни ли сте, че искате да изтриете този файл/папка?",
|
||||||
|
"deleteMessageShare": "Сигурни ли сте, че искате на изтриете това споделяне({path})?",
|
||||||
|
"deleteUser": "Сигурни ли сте, че искате да изтриете този потребител?",
|
||||||
|
"deleteTitle": "Изтрий файлове",
|
||||||
|
"displayName": "Име за показване:",
|
||||||
|
"download": "Свали файлове",
|
||||||
|
"downloadMessage": "Изберете формата, в който искате да свалите.",
|
||||||
|
"error": "Възникна грешка",
|
||||||
|
"fileInfo": "Информация за файла",
|
||||||
|
"filesSelected": "Избрани са {count} файла.",
|
||||||
|
"lastModified": "Последна промяна",
|
||||||
|
"move": "Премести",
|
||||||
|
"moveMessage": "Избери ново място за вашите файл(ове)/папк(а/и):",
|
||||||
|
"newArchetype": "Създай нова публикация базирана на шаблон. Вашия файл ще бъде създаден в папката за съдържание.",
|
||||||
|
"newDir": "Нова директория",
|
||||||
|
"newDirMessage": "Именувайте вашата нова директория.",
|
||||||
|
"newFile": "Нов файл",
|
||||||
|
"newFileMessage": "Именувайте вашия нов файл.",
|
||||||
|
"numberDirs": "Брой на директорийте",
|
||||||
|
"numberFiles": "Брой на файловете",
|
||||||
|
"rename": "Преименувай",
|
||||||
|
"renameMessage": "Вмъкни ново име за",
|
||||||
|
"replace": "Замени",
|
||||||
|
"replaceMessage": "Файл, които се опитвате да качите има конфликтно име. Искате ли да го пропуснете и да продължите качването или да замените съществуващия файл?\n",
|
||||||
|
"schedule": "График",
|
||||||
|
"scheduleMessage": "Изберете дата и час за публикуване на тази публикация.",
|
||||||
|
"show": "Покажи",
|
||||||
|
"size": "Размер",
|
||||||
|
"upload": "Качване",
|
||||||
|
"uploadFiles": "Качване на {files} файла...",
|
||||||
|
"uploadMessage": "Изберете опция за качване.",
|
||||||
|
"optionalPassword": "Опционална парола",
|
||||||
|
"resolution": "Резолюция",
|
||||||
|
"discardEditorChanges": "Сигурни ли сте, че искате да откажете направените промени?"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"images": "Изображения",
|
||||||
|
"music": "Музика",
|
||||||
|
"pdf": "PDF",
|
||||||
|
"pressToSearch": "За търсене, натиснете Enter ...",
|
||||||
|
"search": "Търсене ...",
|
||||||
|
"typeToSearch": "Пишете за търсене ...",
|
||||||
|
"types": "Типове",
|
||||||
|
"video": "Видео"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"aceEditorTheme": "Тема на \"Ace редактор\"",
|
||||||
|
"admin": "Админ",
|
||||||
|
"administrator": "Администратор",
|
||||||
|
"allowCommands": "Изпълни команди",
|
||||||
|
"allowEdit": "Редактира, преименува и изтрива файлове и директории",
|
||||||
|
"allowNew": "Създава нови файлове и директорий",
|
||||||
|
"allowPublish": "Публикува нови публикации и страници",
|
||||||
|
"allowSignup": "Разреши потребителите да се абонират",
|
||||||
|
"hideLoginButton": "Скрий логин бутона от публичните страници",
|
||||||
|
"avoidChanges": "(остави празно за да избегнеш промени)",
|
||||||
|
"branding": "Брандиране",
|
||||||
|
"brandingDirectoryPath": "Брандиране - път до директория",
|
||||||
|
"brandingHelp": "Можете да настроите как изглежда вашия File Browser, като промените името и логото му, да добавите стилове и дори да забраните външни линкове към GitHub.\nЗа повече информация за бандиране се обърнете към {0}",
|
||||||
|
"changePassword": "Промени парола",
|
||||||
|
"commandRunner": "Изпълнение на команди",
|
||||||
|
"commandRunnerHelp": "Тук можете да зададете команди, които да се изпълнят при определени събития. Пишете по една команда на ред. Системните променливите {0} и {1} ще са на разположение, като {0} е релативна на {1}. За повече информация относно тази възможност и наличните системни променливи, моля прочетете {2}.",
|
||||||
|
"commandsUpdated": "Командите са запаметени!",
|
||||||
|
"createUserDir": "Създай автоматично собствена директория на потребителя, когато го добавяш.",
|
||||||
|
"minimumPasswordLength": "Минимална дължина на паролата",
|
||||||
|
"tusUploads": "Качване на части",
|
||||||
|
"tusUploadsHelp": "File Browser поддържа качване на части, което позволява съзадавнето на ефективно, надеждно, и възобновяемо качване на части дори и при ненадеждна мрежа.",
|
||||||
|
"tusUploadsChunkSize": "Максимален размер на заявката (за малки качвания ще бъдат използвано директо качване). Можете да въведете цяло число, което означава размера на данните в байтове, или пък текст от вида на 10MB, 1GB и т.н..",
|
||||||
|
"tusUploadsRetryCount": "Брой повторения, когато част от файл не се качи успешно.",
|
||||||
|
"userHomeBasePath": "Основен път до личните директории на потребителите",
|
||||||
|
"userScopeGenerationPlaceholder": "Обхватът ще бъде автоматично генериран",
|
||||||
|
"createUserHomeDirectory": "Създай лична директория на потребителя",
|
||||||
|
"customStylesheet": "Потребителски Стилове",
|
||||||
|
"defaultUserDescription": "Настройки по подразбиране за нови потребители.",
|
||||||
|
"disableExternalLinks": "Забрани външните връзки (с изключение на документацията)",
|
||||||
|
"disableUsedDiskPercentage": "Забрани графиката за използване на диска",
|
||||||
|
"documentation": "документация",
|
||||||
|
"examples": "Примери",
|
||||||
|
"executeOnShell": "Изпълни в шела",
|
||||||
|
"executeOnShellDescription": "По подразбиране, File Browser изпълнява командите директно. Ако искате да ги изпълните в сесия (като Bash или PowerShell), можете да я дефинирате тук заедно с необходимите аргументи и флагове. Ако това е зададено, командата която изпълните ще бъде добавена като аргумент. Това се отнася както за потребителски команди, така и за обработка на събития.",
|
||||||
|
"globalRules": "Това е общия списък от правила за разрешения или забрани. Те са приложими за всеки потребител. Можете да дефинирате специфични правила в настройките на всеки потребител, които ще имат приоритет над общите.",
|
||||||
|
"globalSettings": "Глобални Настройки",
|
||||||
|
"hideDotfiles": "Скрий фаловете започващи с точка",
|
||||||
|
"insertPath": "Вмъкни пътя",
|
||||||
|
"insertRegex": "Вмъкни регулярен израз",
|
||||||
|
"instanceName": "Име на инстанцията",
|
||||||
|
"language": "Език",
|
||||||
|
"lockPassword": "Забрани на потребителя да променя паролата",
|
||||||
|
"newPassword": "Вашата нова парола",
|
||||||
|
"newPasswordConfirm": "Потвърди вашата нова парола",
|
||||||
|
"newUser": "Нов потребител",
|
||||||
|
"password": "Парола",
|
||||||
|
"passwordUpdated": "Паролата е променена!",
|
||||||
|
"path": "Път",
|
||||||
|
"perm": {
|
||||||
|
"create": "Създаване на файлове и директорий",
|
||||||
|
"delete": "Изтриване на файлове и директорий",
|
||||||
|
"download": "Сваляне",
|
||||||
|
"execute": "Изпълни команди",
|
||||||
|
"modify": "Редактирай файлове",
|
||||||
|
"rename": "Преименувай или премести файлове и директорий",
|
||||||
|
"share": "Сподели файлове"
|
||||||
|
},
|
||||||
|
"permissions": "Разрешения",
|
||||||
|
"permissionsHelp": "Можете да зададете потребител да бъде администратор или да изберете разрешения индивидуално. Ако изберете \"Администратор\" всички други опции ще бъдат автоматично отметнати. Управлението на потребителите е привилегия на администратор.\n",
|
||||||
|
"profileSettings": "Настройки на Профила",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
|
"ruleExample1": "предотвратете достъпа до всеки файл започващ с точка (като .git, .gitignore) във всяка папка.\n",
|
||||||
|
"ruleExample2": "блокира достъпа до файл именуван Caddyfile поставен в началото за обхвата.",
|
||||||
|
"rules": "Правила",
|
||||||
|
"rulesHelp": "Тук можете да дефинирате списък от правила за разрешаване и забрана за точно този потребител. Блокираните файлове няма да се покажат в списъците и няма да са достъпни за потребителя. Поддържаме регулярни изрази и пътища релативни на обхвата.\n",
|
||||||
|
"scope": "Обхват",
|
||||||
|
"setDateFormat": "Задайте точен формат на дата",
|
||||||
|
"settingsUpdated": "Настройките са обновени!",
|
||||||
|
"shareDuration": "Продължителност на споделянето",
|
||||||
|
"shareManagement": "Управление на споделянето",
|
||||||
|
"shareDeleted": "Споделянето е премахнато!",
|
||||||
|
"singleClick": "Използвайте единичен клик за да отворите файлове или директорий",
|
||||||
|
"themes": {
|
||||||
|
"default": "Настройки по подразбиране",
|
||||||
|
"dark": "Тъмна",
|
||||||
|
"light": "Светла",
|
||||||
|
"title": "Тема"
|
||||||
|
},
|
||||||
|
"user": "Потребител",
|
||||||
|
"userCommands": "Команди",
|
||||||
|
"userCommandsHelp": "Списък разделен с интервал от наличните команди за този потребител.\n",
|
||||||
|
"userCreated": "Потребителя е създаден!",
|
||||||
|
"userDefaults": "Настройки по подразбиране на потребителя",
|
||||||
|
"userDeleted": "Потребителя е изтрит!",
|
||||||
|
"userManagement": "Управление на потребители",
|
||||||
|
"userUpdated": "Потребителя е обновен!",
|
||||||
|
"username": "Потребителско име",
|
||||||
|
"users": "Потребители",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"help": "Помощ",
|
||||||
|
"hugoNew": "Hugo New",
|
||||||
|
"login": "Вход",
|
||||||
|
"logout": "Изход",
|
||||||
|
"myFiles": "Моите файлове",
|
||||||
|
"newFile": "Нов файл",
|
||||||
|
"newFolder": "Нова папка",
|
||||||
|
"preview": "Преглед",
|
||||||
|
"settings": "Настройки",
|
||||||
|
"signup": "Абониране",
|
||||||
|
"siteSettings": "Настройки на сървъра"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"linkCopied": "Връзката е копирана!"
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"days": "Дни",
|
||||||
|
"hours": "Часове",
|
||||||
|
"minutes": "Минути",
|
||||||
|
"seconds": "Секунди",
|
||||||
|
"unit": "Единица за време"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Pujar",
|
"upload": "Pujar",
|
||||||
"openFile": "Obrir fitxer",
|
"openFile": "Obrir fitxer",
|
||||||
"discardChanges": "Descartar",
|
"discardChanges": "Descartar",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Descarregar fitxer",
|
"downloadFile": "Descarregar fitxer",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordenar per última modificació",
|
"sortByLastModified": "Ordenar per última modificació",
|
||||||
"sortByName": "Ordenar per nom",
|
"sortByName": "Ordenar per nom",
|
||||||
"sortBySize": "Ordenar per mida",
|
"sortBySize": "Ordenar per mida",
|
||||||
"noPreview": "La vista prèvia no està disponible per a aquest fitxer."
|
"noPreview": "La vista prèvia no està disponible per a aquest fitxer.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "seleccionar fitxer o carpeta",
|
"click": "seleccionar fitxer o carpeta",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Usuari",
|
"username": "Usuari",
|
||||||
"usernameTaken": "Nom d'usuari no disponible",
|
"usernameTaken": "Nom d'usuari no disponible",
|
||||||
"wrongCredentials": "Usuari i/o contrasenya incorrectes",
|
"wrongCredentials": "Usuari i/o contrasenya incorrectes",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Crear nous fitxers i carpetes",
|
"allowNew": "Crear nous fitxers i carpetes",
|
||||||
"allowPublish": "Publicar nous posts i pàgines",
|
"allowPublish": "Publicar nous posts i pàgines",
|
||||||
"allowSignup": "Permetre registre d'usuaris",
|
"allowSignup": "Permetre registre d'usuaris",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(deixar en blanc per evitar canvis)",
|
"avoidChanges": "(deixar en blanc per evitar canvis)",
|
||||||
"branding": "Marca",
|
"branding": "Marca",
|
||||||
"brandingDirectoryPath": "Ruta de la carpeta de personalització de marca",
|
"brandingDirectoryPath": "Ruta de la carpeta de personalització de marca",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permisos",
|
"permissions": "Permisos",
|
||||||
"permissionsHelp": "Pots nomenar l'usuari com a administrador o triar els permisos individualment. Si selecciones \"Administrador\", totes les altres opcions s'activaran automàticament. L'administració d'usuaris és un privilegi d'administrador.\n",
|
"permissionsHelp": "Pots nomenar l'usuari com a administrador o triar els permisos individualment. Si selecciones \"Administrador\", totes les altres opcions s'activaran automàticament. L'administració d'usuaris és un privilegi d'administrador.\n",
|
||||||
"profileSettings": "Ajustos del perfil",
|
"profileSettings": "Ajustos del perfil",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "prevé l'accés a una extensió de fitxer (Com .git) en cada carpeta.\n",
|
"ruleExample1": "prevé l'accés a una extensió de fitxer (Com .git) en cada carpeta.\n",
|
||||||
"ruleExample2": "bloqueja l'accés al fitxer anomenat Caddyfile a la carpeta arrel.",
|
"ruleExample2": "bloqueja l'accés al fitxer anomenat Caddyfile a la carpeta arrel.",
|
||||||
"rules": "Regles",
|
"rules": "Regles",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Administració d'usuaris",
|
"userManagement": "Administració d'usuaris",
|
||||||
"userUpdated": "Usuari actualitzat!",
|
"userUpdated": "Usuari actualitzat!",
|
||||||
"username": "Usuari",
|
"username": "Usuari",
|
||||||
"users": "Usuaris"
|
"users": "Usuaris",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Ajuda",
|
"help": "Ajuda",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Nahrát",
|
"upload": "Nahrát",
|
||||||
"openFile": "Otevřít soubor",
|
"openFile": "Otevřít soubor",
|
||||||
"discardChanges": "Zrušit změny",
|
"discardChanges": "Zrušit změny",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Stáhnout soubor",
|
"downloadFile": "Stáhnout soubor",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Seřadit podle poslední změny",
|
"sortByLastModified": "Seřadit podle poslední změny",
|
||||||
"sortByName": "Seřadit podle názvu",
|
"sortByName": "Seřadit podle názvu",
|
||||||
"sortBySize": "Seřadit podle velikosti",
|
"sortBySize": "Seřadit podle velikosti",
|
||||||
"noPreview": "Náhled pro tento soubor není k dispozici."
|
"noPreview": "Náhled pro tento soubor není k dispozici.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "vyberte soubor nebo adresář",
|
"click": "vyberte soubor nebo adresář",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Uživatelské jméno",
|
"username": "Uživatelské jméno",
|
||||||
"usernameTaken": "Uživatelské jméno již existuje",
|
"usernameTaken": "Uživatelské jméno již existuje",
|
||||||
"wrongCredentials": "Nesprávné přihlašovací údaje",
|
"wrongCredentials": "Nesprávné přihlašovací údaje",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Vytvářet nové soubory a adresáře",
|
"allowNew": "Vytvářet nové soubory a adresáře",
|
||||||
"allowPublish": "Publikovat nové příspěvky a stránky",
|
"allowPublish": "Publikovat nové příspěvky a stránky",
|
||||||
"allowSignup": "Povolit uživatelům registraci",
|
"allowSignup": "Povolit uživatelům registraci",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(ponechte prázdné pro zabránění změnám)",
|
"avoidChanges": "(ponechte prázdné pro zabránění změnám)",
|
||||||
"branding": "Branding",
|
"branding": "Branding",
|
||||||
"brandingDirectoryPath": "Cesta ke složce s brandingem",
|
"brandingDirectoryPath": "Cesta ke složce s brandingem",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Oprávnění",
|
"permissions": "Oprávnění",
|
||||||
"permissionsHelp": "Můžete nastavit uživatele jako administrátora nebo zvolit jednotlivá oprávnění. Pokud vyberete \"Administrátor\", všechny ostatní možnosti budou automaticky zaškrtnuty. Správa uživatelů zůstává výsadou administrátora.\n",
|
"permissionsHelp": "Můžete nastavit uživatele jako administrátora nebo zvolit jednotlivá oprávnění. Pokud vyberete \"Administrátor\", všechny ostatní možnosti budou automaticky zaškrtnuty. Správa uživatelů zůstává výsadou administrátora.\n",
|
||||||
"profileSettings": "Nastavení profilu",
|
"profileSettings": "Nastavení profilu",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "zabraňuje přístupu k jakémukoli skrytému souboru (např. .git, .gitignore) v každé složce.\n",
|
"ruleExample1": "zabraňuje přístupu k jakémukoli skrytému souboru (např. .git, .gitignore) v každé složce.\n",
|
||||||
"ruleExample2": "blokuje přístup k souboru s názvem Caddyfile v kořenovém adresáři.",
|
"ruleExample2": "blokuje přístup k souboru s názvem Caddyfile v kořenovém adresáři.",
|
||||||
"rules": "Pravidla",
|
"rules": "Pravidla",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Správa uživatelů",
|
"userManagement": "Správa uživatelů",
|
||||||
"userUpdated": "Uživatel aktualizován!",
|
"userUpdated": "Uživatel aktualizován!",
|
||||||
"username": "Uživatelské jméno",
|
"username": "Uživatelské jméno",
|
||||||
"users": "Uživatelé"
|
"users": "Uživatelé",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Nápověda",
|
"help": "Nápověda",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"openFile": "Datei öffnen",
|
"openFile": "Datei öffnen",
|
||||||
"discardChanges": "Verwerfen",
|
"discardChanges": "Verwerfen",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Suche abbrechen",
|
||||||
|
"saveChanges": "Änderungen speichern",
|
||||||
|
"editAsText": "Als Text bearbeiten",
|
||||||
|
"increaseFontSize": "Schriftgröße vergrößern",
|
||||||
|
"decreaseFontSize": "Schriftgröße verkleinern"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Download Datei",
|
"downloadFile": "Download Datei",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Nach Änderungsdatum sortieren",
|
"sortByLastModified": "Nach Änderungsdatum sortieren",
|
||||||
"sortByName": "Nach Namen sortieren",
|
"sortByName": "Nach Namen sortieren",
|
||||||
"sortBySize": "Nach Größe sortieren",
|
"sortBySize": "Nach Größe sortieren",
|
||||||
"noPreview": "Für diese Datei ist keine Vorschau verfügbar."
|
"noPreview": "Für diese Datei ist keine Vorschau verfügbar.",
|
||||||
|
"csvTooLarge": "Die CSV-Datei ist zu groß für die Vorschau (>5 MB). Bitte herunterladen, um sie anzuzeigen.",
|
||||||
|
"csvLoadFailed": "Fehler beim Laden der CSV-Datei.",
|
||||||
|
"showingRows": "{count} Zeile(n) werden angezeigt",
|
||||||
|
"columnSeparator": "Spaltentrennzeichen",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Komma (,)",
|
||||||
|
"semicolon": "Semikolon (;)",
|
||||||
|
"both": "Sowohl (,) als auch (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "Wähle Datei oder Ordner",
|
"click": "Wähle Datei oder Ordner",
|
||||||
|
|
@ -102,8 +115,9 @@
|
||||||
"username": "Benutzername",
|
"username": "Benutzername",
|
||||||
"usernameTaken": "Benutzername ist bereits vergeben",
|
"usernameTaken": "Benutzername ist bereits vergeben",
|
||||||
"wrongCredentials": "Falsche Zugangsdaten",
|
"wrongCredentials": "Falsche Zugangsdaten",
|
||||||
|
"passwordTooShort": "Passwort muss mindestens {min} Zeichen lang sein",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "Du wurdest aufgrund von Inaktivität abgemeldet."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permanent": "Permanent",
|
"permanent": "Permanent",
|
||||||
|
|
@ -158,7 +172,7 @@
|
||||||
"video": "Video"
|
"video": "Video"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"aceEditorTheme": "Ace editor theme",
|
"aceEditorTheme": "Ace Editor Theme",
|
||||||
"admin": "Admin",
|
"admin": "Admin",
|
||||||
"administrator": "Administrator",
|
"administrator": "Administrator",
|
||||||
"allowCommands": "Befehle ausführen",
|
"allowCommands": "Befehle ausführen",
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Erstellen neuer Dateien und Ordner",
|
"allowNew": "Erstellen neuer Dateien und Ordner",
|
||||||
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
|
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
|
||||||
"allowSignup": "Erlaube Benutzern sich zu registrieren",
|
"allowSignup": "Erlaube Benutzern sich zu registrieren",
|
||||||
|
"hideLoginButton": "Den Login-Button auf öffentlichen Seiten ausblenden",
|
||||||
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
|
"avoidChanges": "(leer lassen, um Änderungen zu vermeiden)",
|
||||||
"branding": "Design",
|
"branding": "Design",
|
||||||
"brandingDirectoryPath": "Designverzeichnispfad",
|
"brandingDirectoryPath": "Designverzeichnispfad",
|
||||||
|
|
@ -175,7 +190,7 @@
|
||||||
"commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen lesen Sie bitte die {2}.",
|
"commandRunnerHelp": "Hier könne Sie Befehle eintragen, welche bei den benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen Befehl eingeben. Die Umgebungsvariable {0} und {1} sind verfügbar, wobei {0} relative zu {1} ist. Für mehr Informationen über diese Funktion und die verfügbaren Umgebungsvariablen lesen Sie bitte die {2}.",
|
||||||
"commandsUpdated": "Befehle aktualisiert!",
|
"commandsUpdated": "Befehle aktualisiert!",
|
||||||
"createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer",
|
"createUserDir": "Automatisches Erstellen des Home-Verzeichnisses beim Anlegen neuer Benutzer",
|
||||||
"minimumPasswordLength": "Minimum password length",
|
"minimumPasswordLength": "Mindestlänge für Passwörter",
|
||||||
"tusUploads": "Gestückelter Upload",
|
"tusUploads": "Gestückelter Upload",
|
||||||
"tusUploadsHelp": "File Browser unterstützt das Hochladen von gestückelten Dateien und ermöglicht so einen effizienten, zuverlässigen, fortsetzbaren und gestückelten Datei-Upload auch in unzuverlässigen Netzwerken.",
|
"tusUploadsHelp": "File Browser unterstützt das Hochladen von gestückelten Dateien und ermöglicht so einen effizienten, zuverlässigen, fortsetzbaren und gestückelten Datei-Upload auch in unzuverlässigen Netzwerken.",
|
||||||
"tusUploadsChunkSize": "Gibt die maximale Größe pro Anfrage an (direkte Uploads werden für kleinere Uploads verwendet). Bitte geben Sie eine Byte-Angabe oder eine Zeichenfolge wie 10 MB, 1 GB usw. an",
|
"tusUploadsChunkSize": "Gibt die maximale Größe pro Anfrage an (direkte Uploads werden für kleinere Uploads verwendet). Bitte geben Sie eine Byte-Angabe oder eine Zeichenfolge wie 10 MB, 1 GB usw. an",
|
||||||
|
|
@ -199,7 +214,7 @@
|
||||||
"instanceName": "Instanzname",
|
"instanceName": "Instanzname",
|
||||||
"language": "Sprache",
|
"language": "Sprache",
|
||||||
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
|
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
|
||||||
"newPassword": "Ihr neues Passwort.",
|
"newPassword": "Ihr neues Passwort",
|
||||||
"newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort",
|
"newPasswordConfirm": "Bestätigen Sie Ihr neues Passwort",
|
||||||
"newUser": "Neuer Benutzer",
|
"newUser": "Neuer Benutzer",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Berechtigungen",
|
"permissions": "Berechtigungen",
|
||||||
"permissionsHelp": "Sie können einem Benutzer Administratorrechte einräumen oder die Berechtigungen individuell festlegen. Wenn Sie \"Administrator\" auswählen, werden alle anderen Rechte automatisch vergeben. Die Nutzerverwaltung kann nur durch einen Administrator erfolgen.\n",
|
"permissionsHelp": "Sie können einem Benutzer Administratorrechte einräumen oder die Berechtigungen individuell festlegen. Wenn Sie \"Administrator\" auswählen, werden alle anderen Rechte automatisch vergeben. Die Nutzerverwaltung kann nur durch einen Administrator erfolgen.\n",
|
||||||
"profileSettings": "Profileinstellungen",
|
"profileSettings": "Profileinstellungen",
|
||||||
|
"redirectAfterCopyMove": "Nach Kopieren/Verschieben zum Zielverzeichnis wechseln",
|
||||||
"ruleExample1": "Verhindert den Zugang zu versteckten Dateien (dot-Files, wie .git, .gitignore) in allen Ordnern\n",
|
"ruleExample1": "Verhindert den Zugang zu versteckten Dateien (dot-Files, wie .git, .gitignore) in allen Ordnern\n",
|
||||||
"ruleExample2": "blockiert den Zugang auf Dateien mit dem Namen Caddyfile in der Wurzel/Basis des Scopes.",
|
"ruleExample2": "blockiert den Zugang auf Dateien mit dem Namen Caddyfile in der Wurzel/Basis des Scopes.",
|
||||||
"rules": "Regeln",
|
"rules": "Regeln",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Benutzerverwaltung",
|
"userManagement": "Benutzerverwaltung",
|
||||||
"userUpdated": "Benutzer aktualisiert!",
|
"userUpdated": "Benutzer aktualisiert!",
|
||||||
"username": "Nutzername",
|
"username": "Nutzername",
|
||||||
"users": "Nutzer"
|
"users": "Nutzer",
|
||||||
|
"currentPassword": "Ihr aktuelles Passwort"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Hilfe",
|
"help": "Hilfe",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Μεταφόρτωση",
|
"upload": "Μεταφόρτωση",
|
||||||
"openFile": "Άνοιγμα αρχείου",
|
"openFile": "Άνοιγμα αρχείου",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Λήψη αρχείου",
|
"downloadFile": "Λήψη αρχείου",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ταξινόμηση κατά πρόσφατη τροποποίηση",
|
"sortByLastModified": "Ταξινόμηση κατά πρόσφατη τροποποίηση",
|
||||||
"sortByName": "Ταξινόμηση κατά όνομα",
|
"sortByName": "Ταξινόμηση κατά όνομα",
|
||||||
"sortBySize": "Ταξινόμηση κατά μέγεθος",
|
"sortBySize": "Ταξινόμηση κατά μέγεθος",
|
||||||
"noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο."
|
"noPreview": "Η προεπισκόπηση δεν είναι διαθέσιμη για αυτό το αρχείο.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "επιλέξτε αρχείο ή φάκελο",
|
"click": "επιλέξτε αρχείο ή φάκελο",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Όνομα χρήστη",
|
"username": "Όνομα χρήστη",
|
||||||
"usernameTaken": "Το όνομα χρήστη χρησιμοποιείται ήδη",
|
"usernameTaken": "Το όνομα χρήστη χρησιμοποιείται ήδη",
|
||||||
"wrongCredentials": "Λάθος όνομα ή/και κωδικός πρόσβασης",
|
"wrongCredentials": "Λάθος όνομα ή/και κωδικός πρόσβασης",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Δημιουργία νέων αρχείων και φακέλων",
|
"allowNew": "Δημιουργία νέων αρχείων και φακέλων",
|
||||||
"allowPublish": "Δημοσίευση νέων αναρτήσεων και σελίδων",
|
"allowPublish": "Δημοσίευση νέων αναρτήσεων και σελίδων",
|
||||||
"allowSignup": "Να επιτρέπεται η εγγραφή νέων χρηστών",
|
"allowSignup": "Να επιτρέπεται η εγγραφή νέων χρηστών",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(αφήστε το κενό για αποφυγή αλλαγών)",
|
"avoidChanges": "(αφήστε το κενό για αποφυγή αλλαγών)",
|
||||||
"branding": "Εξατομίκευση",
|
"branding": "Εξατομίκευση",
|
||||||
"brandingDirectoryPath": "Διαδρομή φακέλου εξατομίκευσης",
|
"brandingDirectoryPath": "Διαδρομή φακέλου εξατομίκευσης",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Δικαιώματα",
|
"permissions": "Δικαιώματα",
|
||||||
"permissionsHelp": "Μπορείτε να ορίσετε τον χρήστη ως διαχειριστή ή να επιλέξετε τα δικαιώματα μεμονωμένα. Αν επιλέξετε \"Διαχειριστής\", όλες οι υπόλοιπες επιλογές θα είναι αυτόματα επιλεγμένες. Η διαχείριση χρηστών παραμένει προνόμιο ενός χρήστη με τον ρόλο του διαχειριστή.\n",
|
"permissionsHelp": "Μπορείτε να ορίσετε τον χρήστη ως διαχειριστή ή να επιλέξετε τα δικαιώματα μεμονωμένα. Αν επιλέξετε \"Διαχειριστής\", όλες οι υπόλοιπες επιλογές θα είναι αυτόματα επιλεγμένες. Η διαχείριση χρηστών παραμένει προνόμιο ενός χρήστη με τον ρόλο του διαχειριστή.\n",
|
||||||
"profileSettings": "Ρυθμίσεις προφίλ",
|
"profileSettings": "Ρυθμίσεις προφίλ",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "αποκλείει την πρόσβαση σε οποιοδήποτε κρυφό αρχείο (όπως .git, .gitignore) σε κάθε φάκελο.\n",
|
"ruleExample1": "αποκλείει την πρόσβαση σε οποιοδήποτε κρυφό αρχείο (όπως .git, .gitignore) σε κάθε φάκελο.\n",
|
||||||
"ruleExample2": "αποκλείει την πρόσβαση στο αρχείο με το όνομα Caddyfile στον ριζικό φάκελο της εμβέλειας του κανόνα.",
|
"ruleExample2": "αποκλείει την πρόσβαση στο αρχείο με το όνομα Caddyfile στον ριζικό φάκελο της εμβέλειας του κανόνα.",
|
||||||
"rules": "Κανόνες",
|
"rules": "Κανόνες",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Διαχείριση χρηστών",
|
"userManagement": "Διαχείριση χρηστών",
|
||||||
"userUpdated": "Ο χρήστης ενημερώθηκε!",
|
"userUpdated": "Ο χρήστης ενημερώθηκε!",
|
||||||
"username": "Όνομα χρήστη",
|
"username": "Όνομα χρήστη",
|
||||||
"users": "Χρήστες"
|
"users": "Χρήστες",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Βοήθεια",
|
"help": "Βοήθεια",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Upload",
|
"upload": "Upload",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Download File",
|
"downloadFile": "Download File",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sort by last modified",
|
"sortByLastModified": "Sort by last modified",
|
||||||
"sortByName": "Sort by name",
|
"sortByName": "Sort by name",
|
||||||
"sortBySize": "Sort by size",
|
"sortBySize": "Sort by size",
|
||||||
"noPreview": "Preview is not available for this file."
|
"noPreview": "Preview is not available for this file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "select file or directory",
|
"click": "select file or directory",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"usernameTaken": "Username already taken",
|
"usernameTaken": "Username already taken",
|
||||||
"wrongCredentials": "Wrong credentials",
|
"wrongCredentials": "Wrong credentials",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Create new files and directories",
|
"allowNew": "Create new files and directories",
|
||||||
"allowPublish": "Publish new posts and pages",
|
"allowPublish": "Publish new posts and pages",
|
||||||
"allowSignup": "Allow users to signup",
|
"allowSignup": "Allow users to signup",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(leave blank to avoid changes)",
|
"avoidChanges": "(leave blank to avoid changes)",
|
||||||
"branding": "Branding",
|
"branding": "Branding",
|
||||||
"brandingDirectoryPath": "Branding directory path",
|
"brandingDirectoryPath": "Branding directory path",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permissions",
|
"permissions": "Permissions",
|
||||||
"permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n",
|
"permissionsHelp": "You can set the user to be an administrator or choose the permissions individually. If you select \"Administrator\", all of the other options will be automatically checked. The management of users remains a privilege of an administrator.\n",
|
||||||
"profileSettings": "Profile Settings",
|
"profileSettings": "Profile Settings",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "prevents the access to any dotfile (such as .git, .gitignore) in every folder.\n",
|
"ruleExample1": "prevents the access to any dotfile (such as .git, .gitignore) in every folder.\n",
|
||||||
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
|
"ruleExample2": "blocks the access to the file named Caddyfile on the root of the scope.",
|
||||||
"rules": "Rules",
|
"rules": "Rules",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "User Management",
|
"userManagement": "User Management",
|
||||||
"userUpdated": "User updated!",
|
"userUpdated": "User updated!",
|
||||||
"username": "Username",
|
"username": "Username",
|
||||||
"users": "Users"
|
"users": "Users",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Subir",
|
"upload": "Subir",
|
||||||
"openFile": "Abrir archivo",
|
"openFile": "Abrir archivo",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Guardar cambios"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Guardar cambios",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Descargar fichero",
|
"downloadFile": "Descargar fichero",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordenar por última modificación",
|
"sortByLastModified": "Ordenar por última modificación",
|
||||||
"sortByName": "Ordenar por nombre",
|
"sortByName": "Ordenar por nombre",
|
||||||
"sortBySize": "Ordenar por tamaño",
|
"sortBySize": "Ordenar por tamaño",
|
||||||
"noPreview": "La vista previa no está disponible para este archivo."
|
"noPreview": "La vista previa no está disponible para este archivo.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "seleccionar archivo o carpeta",
|
"click": "seleccionar archivo o carpeta",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Usuario",
|
"username": "Usuario",
|
||||||
"usernameTaken": "Nombre usuario no disponible",
|
"usernameTaken": "Nombre usuario no disponible",
|
||||||
"wrongCredentials": "Usuario y/o contraseña incorrectos",
|
"wrongCredentials": "Usuario y/o contraseña incorrectos",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Crear nuevos archivos y carpetas",
|
"allowNew": "Crear nuevos archivos y carpetas",
|
||||||
"allowPublish": "Publicar nuevos posts y páginas",
|
"allowPublish": "Publicar nuevos posts y páginas",
|
||||||
"allowSignup": "Permitir registro de usuarios",
|
"allowSignup": "Permitir registro de usuarios",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(dejar en blanco para evitar cambios)",
|
"avoidChanges": "(dejar en blanco para evitar cambios)",
|
||||||
"branding": "Marca",
|
"branding": "Marca",
|
||||||
"brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca",
|
"brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permisos",
|
"permissions": "Permisos",
|
||||||
"permissionsHelp": "Puedes nombrar al usuario como administrador o elegir los permisos individualmente. Si seleccionas \"Administrador\", todas las otras opciones serán activadas automáticamente. La administración de usuarios es un privilegio de administrador.\n",
|
"permissionsHelp": "Puedes nombrar al usuario como administrador o elegir los permisos individualmente. Si seleccionas \"Administrador\", todas las otras opciones serán activadas automáticamente. La administración de usuarios es un privilegio de administrador.\n",
|
||||||
"profileSettings": "Ajustes del perfil",
|
"profileSettings": "Ajustes del perfil",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "previene el acceso a una extensión de archivo (Como .git) en cada carpeta.\n",
|
"ruleExample1": "previene el acceso a una extensión de archivo (Como .git) en cada carpeta.\n",
|
||||||
"ruleExample2": "bloquea el acceso al archivo llamado Caddyfile en la carpeta raíz.",
|
"ruleExample2": "bloquea el acceso al archivo llamado Caddyfile en la carpeta raíz.",
|
||||||
"rules": "Reglas",
|
"rules": "Reglas",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Administración de usuarios",
|
"userManagement": "Administración de usuarios",
|
||||||
"userUpdated": "¡Usuario actualizado!",
|
"userUpdated": "¡Usuario actualizado!",
|
||||||
"username": "Usuario",
|
"username": "Usuario",
|
||||||
"users": "Usuarios"
|
"users": "Usuarios",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Ayuda",
|
"help": "Ayuda",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "آپلود",
|
"upload": "آپلود",
|
||||||
"openFile": "باز کردن فایل",
|
"openFile": "باز کردن فایل",
|
||||||
"discardChanges": "لغو کردن",
|
"discardChanges": "لغو کردن",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "دانلود فایل",
|
"downloadFile": "دانلود فایل",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "مرتب سازی آخرین ویرایش",
|
"sortByLastModified": "مرتب سازی آخرین ویرایش",
|
||||||
"sortByName": "مرتب سازی نام",
|
"sortByName": "مرتب سازی نام",
|
||||||
"sortBySize": "مرتب سازی اندازه",
|
"sortBySize": "مرتب سازی اندازه",
|
||||||
"noPreview": "این فایل قابل نمایش نیست"
|
"noPreview": "این فایل قابل نمایش نیست",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "انتخاب فایل یا پوشه",
|
"click": "انتخاب فایل یا پوشه",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "نام کاربری",
|
"username": "نام کاربری",
|
||||||
"usernameTaken": "نام کاربری تکراری",
|
"usernameTaken": "نام کاربری تکراری",
|
||||||
"wrongCredentials": "خطا در اعتبارسنجی",
|
"wrongCredentials": "خطا در اعتبارسنجی",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "ایجاد فایلها و پوشه های جدید",
|
"allowNew": "ایجاد فایلها و پوشه های جدید",
|
||||||
"allowPublish": "انتشار پست ها و صفحات جدید",
|
"allowPublish": "انتشار پست ها و صفحات جدید",
|
||||||
"allowSignup": "اجاره دادن به کاربران برای ثبت نام",
|
"allowSignup": "اجاره دادن به کاربران برای ثبت نام",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(خالی بگذارید تا تغییر ایجاد نشود)",
|
"avoidChanges": "(خالی بگذارید تا تغییر ایجاد نشود)",
|
||||||
"branding": "برندسازی",
|
"branding": "برندسازی",
|
||||||
"brandingDirectoryPath": "مسیر پوشه برند",
|
"brandingDirectoryPath": "مسیر پوشه برند",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "دسترسی ها",
|
"permissions": "دسترسی ها",
|
||||||
"permissionsHelp": "شما میتوانید کاربر را به عنوان مدیر تنظیم کنید یا دسترسیها را به صورت جداگانه انتخاب کنید. اگر \"مدیر\" را انتخاب کنید، تمام گزینههای دیگر به طور خودکار اعمال میشوند. مدیریت کاربران همچنان از اختیارات مدیر است.",
|
"permissionsHelp": "شما میتوانید کاربر را به عنوان مدیر تنظیم کنید یا دسترسیها را به صورت جداگانه انتخاب کنید. اگر \"مدیر\" را انتخاب کنید، تمام گزینههای دیگر به طور خودکار اعمال میشوند. مدیریت کاربران همچنان از اختیارات مدیر است.",
|
||||||
"profileSettings": "تنظیمات ناحیه کاربری",
|
"profileSettings": "تنظیمات ناحیه کاربری",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "از دسترسی به هرگونه فایل نقطهای (مانند .git، .gitignore) در هر پوشه جلوگیری میکند.",
|
"ruleExample1": "از دسترسی به هرگونه فایل نقطهای (مانند .git، .gitignore) در هر پوشه جلوگیری میکند.",
|
||||||
"ruleExample2": "دسترسی به فایلی به نام Caddyfile را در ریشه دامنه مسدود میکند.",
|
"ruleExample2": "دسترسی به فایلی به نام Caddyfile را در ریشه دامنه مسدود میکند.",
|
||||||
"rules": "قواعد",
|
"rules": "قواعد",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "مدیریت کاربران",
|
"userManagement": "مدیریت کاربران",
|
||||||
"userUpdated": "کاربر به روز شد!",
|
"userUpdated": "کاربر به روز شد!",
|
||||||
"username": "نام کاربری",
|
"username": "نام کاربری",
|
||||||
"users": "کاربران"
|
"users": "کاربران",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "راهنما",
|
"help": "راهنما",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Importer",
|
"upload": "Importer",
|
||||||
"openFile": "Ouvrir le fichier",
|
"openFile": "Ouvrir le fichier",
|
||||||
"discardChanges": "Annuler",
|
"discardChanges": "Annuler",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Arrêter recherche",
|
||||||
|
"saveChanges": "Enregistrer changements",
|
||||||
|
"editAsText": "Editer comme Texte",
|
||||||
|
"increaseFontSize": "Augmenter taille police",
|
||||||
|
"decreaseFontSize": "Réduire taille police"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Télécharger le fichier",
|
"downloadFile": "Télécharger le fichier",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Trier par date de modification",
|
"sortByLastModified": "Trier par date de modification",
|
||||||
"sortByName": "Trier par nom",
|
"sortByName": "Trier par nom",
|
||||||
"sortBySize": "Trier par taille",
|
"sortBySize": "Trier par taille",
|
||||||
"noPreview": "L'aperçu n'est pas disponible pour ce fichier."
|
"noPreview": "L'aperçu n'est pas disponible pour ce fichier.",
|
||||||
|
"csvTooLarge": "Le fichier CSV est trop volumineux pour être prévisualisé (>5MB). Veuillez le télécharger pour le voir.",
|
||||||
|
"csvLoadFailed": "Impossible de charger le fichier CSV.",
|
||||||
|
"showingRows": "Affichage de {count} ligne(s)",
|
||||||
|
"columnSeparator": "Séparateur de Colonnes",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Virgule (,)",
|
||||||
|
"semicolon": "Point-virgule (;)",
|
||||||
|
"both": "Les (,) et (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "Sélectionner un fichier ou dossier",
|
"click": "Sélectionner un fichier ou dossier",
|
||||||
|
|
@ -102,8 +115,9 @@
|
||||||
"username": "Utilisateur·ice",
|
"username": "Utilisateur·ice",
|
||||||
"usernameTaken": "Le nom d'utilisateur·ice est déjà pris",
|
"usernameTaken": "Le nom d'utilisateur·ice est déjà pris",
|
||||||
"wrongCredentials": "Identifiants incorrects !",
|
"wrongCredentials": "Identifiants incorrects !",
|
||||||
|
"passwordTooShort": "Le mot de passe doit contenir au moins {min} caractères",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "Vous avez été déconnecté(e) en raison d'une inactivité prolongée."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permanent": "Permanent",
|
"permanent": "Permanent",
|
||||||
|
|
@ -158,7 +172,7 @@
|
||||||
"video": "Vidéo"
|
"video": "Vidéo"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"aceEditorTheme": "Ace editor theme",
|
"aceEditorTheme": "Éditeur de Thème Ace",
|
||||||
"admin": "Admin",
|
"admin": "Admin",
|
||||||
"administrator": "Administrateur·ice",
|
"administrator": "Administrateur·ice",
|
||||||
"allowCommands": "Exécuter des commandes",
|
"allowCommands": "Exécuter des commandes",
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Créer de nouveaux fichiers et dossiers",
|
"allowNew": "Créer de nouveaux fichiers et dossiers",
|
||||||
"allowPublish": "Publier de nouveaux posts et pages",
|
"allowPublish": "Publier de nouveaux posts et pages",
|
||||||
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
|
"allowSignup": "Autoriser les utilisateur·ices à s'inscrire",
|
||||||
|
"hideLoginButton": "Cacher le bouton d’identification sur les pages publiques",
|
||||||
"avoidChanges": "(Laisser vide pour conserver l'actuel)",
|
"avoidChanges": "(Laisser vide pour conserver l'actuel)",
|
||||||
"branding": "Image de marque",
|
"branding": "Image de marque",
|
||||||
"brandingDirectoryPath": "Chemin du dossier d'image de marque",
|
"brandingDirectoryPath": "Chemin du dossier d'image de marque",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permissions",
|
"permissions": "Permissions",
|
||||||
"permissionsHelp": "Vous pouvez définir l'utilisateur·ice comme étant administrateur·ice ou encore choisir les permissions individuellement. Si vous sélectionnez \"Administrateur·ice\", toutes les autres options seront automatiquement activées. La gestion des utilisateur·ices est un privilège que seul l'administrateur·ice possède.\n",
|
"permissionsHelp": "Vous pouvez définir l'utilisateur·ice comme étant administrateur·ice ou encore choisir les permissions individuellement. Si vous sélectionnez \"Administrateur·ice\", toutes les autres options seront automatiquement activées. La gestion des utilisateur·ices est un privilège que seul l'administrateur·ice possède.\n",
|
||||||
"profileSettings": "Paramètres du profil",
|
"profileSettings": "Paramètres du profil",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "Bloque l'accès à tous les fichiers commençant par un point (comme par exemple .git, .gitignore) dans tous les dossiers.\n",
|
"ruleExample1": "Bloque l'accès à tous les fichiers commençant par un point (comme par exemple .git, .gitignore) dans tous les dossiers.\n",
|
||||||
"ruleExample2": "Bloque l'accès au fichier nommé \"Caddyfile\" à la racine du dossier utilisateur·ice.",
|
"ruleExample2": "Bloque l'accès au fichier nommé \"Caddyfile\" à la racine du dossier utilisateur·ice.",
|
||||||
"rules": "Règles",
|
"rules": "Règles",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gestion des utilisateur·ices",
|
"userManagement": "Gestion des utilisateur·ices",
|
||||||
"userUpdated": "Utilisateur·ice mis à jour !",
|
"userUpdated": "Utilisateur·ice mis à jour !",
|
||||||
"username": "Nom d'utilisateur·ice",
|
"username": "Nom d'utilisateur·ice",
|
||||||
"users": "Utilisateur·ices"
|
"users": "Utilisateur·ices",
|
||||||
|
"currentPassword": "Mot de Passe Actuel"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Aide",
|
"help": "Aide",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "העלאה",
|
"upload": "העלאה",
|
||||||
"openFile": "פתח קובץ",
|
"openFile": "פתח קובץ",
|
||||||
"discardChanges": "זריקת השינויים",
|
"discardChanges": "זריקת השינויים",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "הורד קובץ",
|
"downloadFile": "הורד קובץ",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "מיין לפי השינוי האחרון",
|
"sortByLastModified": "מיין לפי השינוי האחרון",
|
||||||
"sortByName": "מיין לפי שם",
|
"sortByName": "מיין לפי שם",
|
||||||
"sortBySize": "מיין לפי גודל",
|
"sortBySize": "מיין לפי גודל",
|
||||||
"noPreview": "לא זמינה תצוגה מקדימה לקובץ זה"
|
"noPreview": "לא זמינה תצוגה מקדימה לקובץ זה",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "בחר קובץ או תיקייה",
|
"click": "בחר קובץ או תיקייה",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "שם משתמש",
|
"username": "שם משתמש",
|
||||||
"usernameTaken": "שם המשתמש כבר קיים",
|
"usernameTaken": "שם המשתמש כבר קיים",
|
||||||
"wrongCredentials": "פרטי התחברות שגויים",
|
"wrongCredentials": "פרטי התחברות שגויים",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "יצירת קבצים ותיקיות חדשות",
|
"allowNew": "יצירת קבצים ותיקיות חדשות",
|
||||||
"allowPublish": "פרסום פוסטים ודפים חדשים",
|
"allowPublish": "פרסום פוסטים ודפים חדשים",
|
||||||
"allowSignup": "אפשר למשתמשים חדשים להירשם",
|
"allowSignup": "אפשר למשתמשים חדשים להירשם",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(השאר ריק כדי למנוע שינויים)",
|
"avoidChanges": "(השאר ריק כדי למנוע שינויים)",
|
||||||
"branding": "מיתוג",
|
"branding": "מיתוג",
|
||||||
"brandingDirectoryPath": "נתיב תיקיית מיתוג",
|
"brandingDirectoryPath": "נתיב תיקיית מיתוג",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "הרשאות",
|
"permissions": "הרשאות",
|
||||||
"permissionsHelp": "אתה יכול להגדיר את המשתמש להיות מנהל מערכת או לבחור את ההרשאות בנפרד. אם תבחר \"מנהל מערכת\", כל ההרשאות יינתנו אוטומטית. ניהול המשתמשים נשאר הרשאה של מנהל מערכת.\n",
|
"permissionsHelp": "אתה יכול להגדיר את המשתמש להיות מנהל מערכת או לבחור את ההרשאות בנפרד. אם תבחר \"מנהל מערכת\", כל ההרשאות יינתנו אוטומטית. ניהול המשתמשים נשאר הרשאה של מנהל מערכת.\n",
|
||||||
"profileSettings": "הגדרות פרופיל",
|
"profileSettings": "הגדרות פרופיל",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "מנע גישה לקבצים נסתרים (כל קובץ/תיקייה שמתחיל בנקודה, לדוגמא .git)",
|
"ruleExample1": "מנע גישה לקבצים נסתרים (כל קובץ/תיקייה שמתחיל בנקודה, לדוגמא .git)",
|
||||||
"ruleExample2": "חסימת גישה לקובץ בשם Caddyfile בהיקף הראשי.",
|
"ruleExample2": "חסימת גישה לקובץ בשם Caddyfile בהיקף הראשי.",
|
||||||
"rules": "חוקים",
|
"rules": "חוקים",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "ניהול משתמש",
|
"userManagement": "ניהול משתמש",
|
||||||
"userUpdated": "המשתמש עודכן!",
|
"userUpdated": "המשתמש עודכן!",
|
||||||
"username": "שם משתמש",
|
"username": "שם משתמש",
|
||||||
"users": "משתמשים"
|
"users": "משתמשים",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "עזרה",
|
"help": "עזרה",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Prenesi",
|
"upload": "Prenesi",
|
||||||
"openFile": "Otvori datoteku",
|
"openFile": "Otvori datoteku",
|
||||||
"discardChanges": "Odbaci",
|
"discardChanges": "Odbaci",
|
||||||
"saveChanges": "Spremi promjene"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Spremi promjene",
|
||||||
|
"editAsText": "Uredi kao tekst",
|
||||||
|
"increaseFontSize": "Povećaj veličinu fonta",
|
||||||
|
"decreaseFontSize": "Smanji veličinu fonta"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Preuzmi Datoteku",
|
"downloadFile": "Preuzmi Datoteku",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sortiraj po zadnjoj izmjeni",
|
"sortByLastModified": "Sortiraj po zadnjoj izmjeni",
|
||||||
"sortByName": "Sortiraj po nazivu",
|
"sortByName": "Sortiraj po nazivu",
|
||||||
"sortBySize": "Sortiraj po veličini",
|
"sortBySize": "Sortiraj po veličini",
|
||||||
"noPreview": "Pregled nije dostupan za ovu datoteku."
|
"noPreview": "Pregled nije dostupan za ovu datoteku.",
|
||||||
|
"csvTooLarge": "CSV datoteka je prevelika za pregled (>5MB). Molimo preuzmite da bi ste ju pregledali.",
|
||||||
|
"csvLoadFailed": "Neuspješno učitavanje CSV datoteke.",
|
||||||
|
"showingRows": "Prikazuje se {count} red(ova)",
|
||||||
|
"columnSeparator": "Separator stupaca",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Zarez (,)",
|
||||||
|
"semicolon": "Točka zarez (;)",
|
||||||
|
"both": "I (,) i (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "odaberi datoteku ili mapu",
|
"click": "odaberi datoteku ili mapu",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Korisničko ime",
|
"username": "Korisničko ime",
|
||||||
"usernameTaken": "Korisničko ime zauzeto",
|
"usernameTaken": "Korisničko ime zauzeto",
|
||||||
"wrongCredentials": "Neispravno korisničko ime/lozinka",
|
"wrongCredentials": "Neispravno korisničko ime/lozinka",
|
||||||
|
"passwordTooShort": "Lozinka mora sadržavati minimalno {min} znakova",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "Odjavljeni ste zbog neaktivnosti."
|
"inactivity": "Odjavljeni ste zbog neaktivnosti."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Stvori nove datoteke i mape",
|
"allowNew": "Stvori nove datoteke i mape",
|
||||||
"allowPublish": "Objavi nove objave i stranice",
|
"allowPublish": "Objavi nove objave i stranice",
|
||||||
"allowSignup": "Dopusti registraciju korisnicima",
|
"allowSignup": "Dopusti registraciju korisnicima",
|
||||||
|
"hideLoginButton": "Sakrij tipku za prijavu s javnih stranica",
|
||||||
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
|
"avoidChanges": "(ostavite prazno kako biste izbjegli promjene)",
|
||||||
"branding": "Brendiranje",
|
"branding": "Brendiranje",
|
||||||
"brandingDirectoryPath": "Put brendiranja",
|
"brandingDirectoryPath": "Put brendiranja",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Dopuštenja",
|
"permissions": "Dopuštenja",
|
||||||
"permissionsHelp": "Korisnika možete postaviti administratorom ili odabrati dopuštenja individualno. Odabirom na \"Administrator\", sve druge opcije bit će automatski odabrane. Upravljanje korisnicima ostaje privilegija administratora.\n",
|
"permissionsHelp": "Korisnika možete postaviti administratorom ili odabrati dopuštenja individualno. Odabirom na \"Administrator\", sve druge opcije bit će automatski odabrane. Upravljanje korisnicima ostaje privilegija administratora.\n",
|
||||||
"profileSettings": "Postavke profila",
|
"profileSettings": "Postavke profila",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "onemogućava pristup svakoj datoteci koja započinje točkom (poput .git, .gitignore) u svakoj mapi.\n",
|
"ruleExample1": "onemogućava pristup svakoj datoteci koja započinje točkom (poput .git, .gitignore) u svakoj mapi.\n",
|
||||||
"ruleExample2": "blokira pristup datoteci naziva Caddyfile na korijenu opsega.",
|
"ruleExample2": "blokira pristup datoteci naziva Caddyfile na korijenu opsega.",
|
||||||
"rules": "Pravila",
|
"rules": "Pravila",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Upravljanje Korisnicima",
|
"userManagement": "Upravljanje Korisnicima",
|
||||||
"userUpdated": "Korisnik ažuriran!",
|
"userUpdated": "Korisnik ažuriran!",
|
||||||
"username": "Korisničko ime",
|
"username": "Korisničko ime",
|
||||||
"users": "Korisnici"
|
"users": "Korisnici",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Pomoć",
|
"help": "Pomoć",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Feltöltés",
|
"upload": "Feltöltés",
|
||||||
"openFile": "Fájl megnyitása",
|
"openFile": "Fájl megnyitása",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Fájl letöltése",
|
"downloadFile": "Fájl letöltése",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Rendezés utolsó módosítás szerint",
|
"sortByLastModified": "Rendezés utolsó módosítás szerint",
|
||||||
"sortByName": "Rendezés név szerint",
|
"sortByName": "Rendezés név szerint",
|
||||||
"sortBySize": "Rendezés méret szerint",
|
"sortBySize": "Rendezés méret szerint",
|
||||||
"noPreview": "Ehhez a fájlhoz nincs előnézet."
|
"noPreview": "Ehhez a fájlhoz nincs előnézet.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "mappa vagy fájl kijelölése",
|
"click": "mappa vagy fájl kijelölése",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Felhasználói név",
|
"username": "Felhasználói név",
|
||||||
"usernameTaken": "A felhasználói név már foglalt",
|
"usernameTaken": "A felhasználói név már foglalt",
|
||||||
"wrongCredentials": "Hibás hitelesítő adatok",
|
"wrongCredentials": "Hibás hitelesítő adatok",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Új fájlok és mappák létrehozása",
|
"allowNew": "Új fájlok és mappák létrehozása",
|
||||||
"allowPublish": "Új bejegyzések és oldalak létrehozása",
|
"allowPublish": "Új bejegyzések és oldalak létrehozása",
|
||||||
"allowSignup": "Felhasználók regisztrációjának engedélyezése",
|
"allowSignup": "Felhasználók regisztrációjának engedélyezése",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(üresen hagyva nincs változás)",
|
"avoidChanges": "(üresen hagyva nincs változás)",
|
||||||
"branding": "Márkázás",
|
"branding": "Márkázás",
|
||||||
"brandingDirectoryPath": "Márkázás mappaútvonala",
|
"brandingDirectoryPath": "Márkázás mappaútvonala",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Jogosultságok",
|
"permissions": "Jogosultságok",
|
||||||
"permissionsHelp": "A felhasználót beállíthatja rendszergazdának, vagy egyénileg is kiválaszthatja a jogosultságokat. Ha a \"Rendszergazda\" lehetőséget választja, az összes többi opció automatikusan be lesz jelölve. A felhasználók kezelése továbbra is a rendszergazda kiváltsága marad.\n",
|
"permissionsHelp": "A felhasználót beállíthatja rendszergazdának, vagy egyénileg is kiválaszthatja a jogosultságokat. Ha a \"Rendszergazda\" lehetőséget választja, az összes többi opció automatikusan be lesz jelölve. A felhasználók kezelése továbbra is a rendszergazda kiváltsága marad.\n",
|
||||||
"profileSettings": "Profilbeállítások",
|
"profileSettings": "Profilbeállítások",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "megakadályozza a hozzáférést bármely rejtett fájlhoz (pl. .git, .gitignore) bármely mappában.\n",
|
"ruleExample1": "megakadályozza a hozzáférést bármely rejtett fájlhoz (pl. .git, .gitignore) bármely mappában.\n",
|
||||||
"ruleExample2": "blokkolja a hozzáférést a Caddyfile nevű fájlhoz a hatókör gyökerében.",
|
"ruleExample2": "blokkolja a hozzáférést a Caddyfile nevű fájlhoz a hatókör gyökerében.",
|
||||||
"rules": "Szabályok",
|
"rules": "Szabályok",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Felhasználókezelés",
|
"userManagement": "Felhasználókezelés",
|
||||||
"userUpdated": "Felhasználó frissítve!",
|
"userUpdated": "Felhasználó frissítve!",
|
||||||
"username": "Felhasználói név",
|
"username": "Felhasználói név",
|
||||||
"users": "Felhasználók"
|
"users": "Felhasználók",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Súgó",
|
"help": "Súgó",
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@ import dayjs from "dayjs";
|
||||||
import { createI18n } from "vue-i18n";
|
import { createI18n } from "vue-i18n";
|
||||||
|
|
||||||
import("dayjs/locale/ar");
|
import("dayjs/locale/ar");
|
||||||
|
import("dayjs/locale/bg");
|
||||||
|
import("dayjs/locale/cs");
|
||||||
import("dayjs/locale/de");
|
import("dayjs/locale/de");
|
||||||
import("dayjs/locale/el");
|
import("dayjs/locale/el");
|
||||||
import("dayjs/locale/en");
|
import("dayjs/locale/en");
|
||||||
|
|
@ -14,6 +16,7 @@ import("dayjs/locale/is");
|
||||||
import("dayjs/locale/it");
|
import("dayjs/locale/it");
|
||||||
import("dayjs/locale/ja");
|
import("dayjs/locale/ja");
|
||||||
import("dayjs/locale/ko");
|
import("dayjs/locale/ko");
|
||||||
|
import("dayjs/locale/nb");
|
||||||
import("dayjs/locale/nl-be");
|
import("dayjs/locale/nl-be");
|
||||||
import("dayjs/locale/pl");
|
import("dayjs/locale/pl");
|
||||||
import("dayjs/locale/pt-br");
|
import("dayjs/locale/pt-br");
|
||||||
|
|
@ -27,8 +30,6 @@ import("dayjs/locale/uk");
|
||||||
import("dayjs/locale/vi");
|
import("dayjs/locale/vi");
|
||||||
import("dayjs/locale/zh-cn");
|
import("dayjs/locale/zh-cn");
|
||||||
import("dayjs/locale/zh-tw");
|
import("dayjs/locale/zh-tw");
|
||||||
import("dayjs/locale/cs");
|
|
||||||
import("dayjs/locale/nb");
|
|
||||||
|
|
||||||
// All i18n resources specified in the plugin `include` option can be loaded
|
// All i18n resources specified in the plugin `include` option can be loaded
|
||||||
// at once using the import syntax
|
// at once using the import syntax
|
||||||
|
|
@ -109,6 +110,7 @@ export function detectLocale() {
|
||||||
case /^uk\b/.test(locale):
|
case /^uk\b/.test(locale):
|
||||||
locale = "uk";
|
locale = "uk";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case /^vi\b/.test(locale):
|
case /^vi\b/.test(locale):
|
||||||
locale = "vi";
|
locale = "vi";
|
||||||
break;
|
break;
|
||||||
|
|
@ -123,6 +125,9 @@ export function detectLocale() {
|
||||||
case /^no\b/.test(locale):
|
case /^no\b/.test(locale):
|
||||||
locale = "no";
|
locale = "no";
|
||||||
break;
|
break;
|
||||||
|
case /^bg\b/.test(locale):
|
||||||
|
locale = "bg";
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
locale = "en";
|
locale = "en";
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Hlaða upp",
|
"upload": "Hlaða upp",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Sækja skjal",
|
"downloadFile": "Sækja skjal",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Flokka eftir Seinast breytt",
|
"sortByLastModified": "Flokka eftir Seinast breytt",
|
||||||
"sortByName": "Flokka eftir nafni",
|
"sortByName": "Flokka eftir nafni",
|
||||||
"sortBySize": "Flokka eftir stærð",
|
"sortBySize": "Flokka eftir stærð",
|
||||||
"noPreview": "Preview is not available for this file."
|
"noPreview": "Preview is not available for this file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "velja skjal eða möppu",
|
"click": "velja skjal eða möppu",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Notendanafn",
|
"username": "Notendanafn",
|
||||||
"usernameTaken": "Þetta norendanafn er þegar í notkun",
|
"usernameTaken": "Þetta norendanafn er þegar í notkun",
|
||||||
"wrongCredentials": "Rangar notendaupplýsingar",
|
"wrongCredentials": "Rangar notendaupplýsingar",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Búa til ný skjöl og möppur",
|
"allowNew": "Búa til ný skjöl og möppur",
|
||||||
"allowPublish": "Gefa út nýjar færslur og síður",
|
"allowPublish": "Gefa út nýjar færslur og síður",
|
||||||
"allowSignup": "Leyfa nýjum notendum að skrá sig",
|
"allowSignup": "Leyfa nýjum notendum að skrá sig",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(engar breytingar ef ekkert er skrifað)",
|
"avoidChanges": "(engar breytingar ef ekkert er skrifað)",
|
||||||
"branding": "Útlit",
|
"branding": "Útlit",
|
||||||
"brandingDirectoryPath": "Mappa fyrir branding-skjöl",
|
"brandingDirectoryPath": "Mappa fyrir branding-skjöl",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Heimildir",
|
"permissions": "Heimildir",
|
||||||
"permissionsHelp": "Þú getur stillt notenda sem stjórnanda eða valið einstaklingsbundnar heimildir. Ef þú velur \"Stjórnandi\", þá verða allir aðrir valmöguleikar valdir sjálfrafa. Aðgangstýring notenda er á hendi stjórnenda. \n",
|
"permissionsHelp": "Þú getur stillt notenda sem stjórnanda eða valið einstaklingsbundnar heimildir. Ef þú velur \"Stjórnandi\", þá verða allir aðrir valmöguleikar valdir sjálfrafa. Aðgangstýring notenda er á hendi stjórnenda. \n",
|
||||||
"profileSettings": "Stilla prófíl",
|
"profileSettings": "Stilla prófíl",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "kemur í veg fyrir aðgang að dot-skjali (t.d. .git, .gitignore) í öllum möppum. \n",
|
"ruleExample1": "kemur í veg fyrir aðgang að dot-skjali (t.d. .git, .gitignore) í öllum möppum. \n",
|
||||||
"ruleExample2": "kemur í veg fyrir aðgang að Caddyfile-skjalinu í root-möppu í sýn notandans. ",
|
"ruleExample2": "kemur í veg fyrir aðgang að Caddyfile-skjalinu í root-möppu í sýn notandans. ",
|
||||||
"rules": "Reglur",
|
"rules": "Reglur",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Notendastýring",
|
"userManagement": "Notendastýring",
|
||||||
"userUpdated": "Notandastillingar vistaðar!",
|
"userUpdated": "Notandastillingar vistaðar!",
|
||||||
"username": "Notendanafn",
|
"username": "Notendanafn",
|
||||||
"users": "Notendur"
|
"users": "Notendur",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Hjálp",
|
"help": "Hjálp",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Carica",
|
"upload": "Carica",
|
||||||
"openFile": "Apri file",
|
"openFile": "Apri file",
|
||||||
"discardChanges": "Ignora",
|
"discardChanges": "Ignora",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Scarica file",
|
"downloadFile": "Scarica file",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordina per ultima modifica",
|
"sortByLastModified": "Ordina per ultima modifica",
|
||||||
"sortByName": "Ordina per nome",
|
"sortByName": "Ordina per nome",
|
||||||
"sortBySize": "Ordina per dimensione",
|
"sortBySize": "Ordina per dimensione",
|
||||||
"noPreview": "L'anteprima non è disponibile per questo file."
|
"noPreview": "L'anteprima non è disponibile per questo file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "seleziona un file o una cartella",
|
"click": "seleziona un file o una cartella",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Nome utente",
|
"username": "Nome utente",
|
||||||
"usernameTaken": "Username già usato",
|
"usernameTaken": "Username già usato",
|
||||||
"wrongCredentials": "Credenziali errate",
|
"wrongCredentials": "Credenziali errate",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Crea nuovi files o cartelle",
|
"allowNew": "Crea nuovi files o cartelle",
|
||||||
"allowPublish": "Pubblica nuovi post e pagine",
|
"allowPublish": "Pubblica nuovi post e pagine",
|
||||||
"allowSignup": "Permetti agli utenti di registrarsi",
|
"allowSignup": "Permetti agli utenti di registrarsi",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(lascia vuoto per evitare cambiamenti)",
|
"avoidChanges": "(lascia vuoto per evitare cambiamenti)",
|
||||||
"branding": "Branding",
|
"branding": "Branding",
|
||||||
"brandingDirectoryPath": "Directory del branding",
|
"brandingDirectoryPath": "Directory del branding",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permessi",
|
"permissions": "Permessi",
|
||||||
"permissionsHelp": "È possibile impostare l'utente come amministratore o scegliere i permessi singolarmente. Se si seleziona \"Amministratore\", tutte le altre opzioni saranno automaticamente assegnate. La gestione degli utenti rimane un privilegio di un amministratore.\n",
|
"permissionsHelp": "È possibile impostare l'utente come amministratore o scegliere i permessi singolarmente. Se si seleziona \"Amministratore\", tutte le altre opzioni saranno automaticamente assegnate. La gestione degli utenti rimane un privilegio di un amministratore.\n",
|
||||||
"profileSettings": "Impostazioni del profilo",
|
"profileSettings": "Impostazioni del profilo",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "impedisci l'accesso a qualsiasi file avente come prefisso un punto\n (ad esempio .git, .gitignore) presente in ogni cartella.\n",
|
"ruleExample1": "impedisci l'accesso a qualsiasi file avente come prefisso un punto\n (ad esempio .git, .gitignore) presente in ogni cartella.\n",
|
||||||
"ruleExample2": "blocca l'accesso al file denominato Caddyfile nella radice del campo di applicazione.",
|
"ruleExample2": "blocca l'accesso al file denominato Caddyfile nella radice del campo di applicazione.",
|
||||||
"rules": "Regole",
|
"rules": "Regole",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gestione degli utenti",
|
"userManagement": "Gestione degli utenti",
|
||||||
"userUpdated": "Utente aggiornato!",
|
"userUpdated": "Utente aggiornato!",
|
||||||
"username": "Nome utente",
|
"username": "Nome utente",
|
||||||
"users": "Utenti"
|
"users": "Utenti",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Aiuto",
|
"help": "Aiuto",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "アップロード",
|
"upload": "アップロード",
|
||||||
"openFile": "ファイルを開く",
|
"openFile": "ファイルを開く",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "ファイルのダウンロード",
|
"downloadFile": "ファイルのダウンロード",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "更新日時で並べ替え",
|
"sortByLastModified": "更新日時で並べ替え",
|
||||||
"sortByName": "名前で並べ替え",
|
"sortByName": "名前で並べ替え",
|
||||||
"sortBySize": "サイズで並べ替え",
|
"sortBySize": "サイズで並べ替え",
|
||||||
"noPreview": "プレビューはこのファイルでは利用できません"
|
"noPreview": "プレビューはこのファイルでは利用できません",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "ファイルやフォルダーを選択",
|
"click": "ファイルやフォルダーを選択",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "ユーザー名",
|
"username": "ユーザー名",
|
||||||
"usernameTaken": "ユーザー名はすでに取得されています",
|
"usernameTaken": "ユーザー名はすでに取得されています",
|
||||||
"wrongCredentials": "ユーザー名またはパスワードが間違っています",
|
"wrongCredentials": "ユーザー名またはパスワードが間違っています",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "ファイルやフォルダーの新規作成",
|
"allowNew": "ファイルやフォルダーの新規作成",
|
||||||
"allowPublish": "新しい投稿やページの公開",
|
"allowPublish": "新しい投稿やページの公開",
|
||||||
"allowSignup": "ユーザーの新規登録を許可",
|
"allowSignup": "ユーザーの新規登録を許可",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(変更しない場合は空白のままにしてください)",
|
"avoidChanges": "(変更しない場合は空白のままにしてください)",
|
||||||
"branding": "ブランディング",
|
"branding": "ブランディング",
|
||||||
"brandingDirectoryPath": "ブランディングのディレクトリへのパス",
|
"brandingDirectoryPath": "ブランディングのディレクトリへのパス",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "権限",
|
"permissions": "権限",
|
||||||
"permissionsHelp": "ユーザーを管理者に設定するか、その他の権限を個別に選択することができます。「管理者」を選択すると、他のオプションはすべて自動的にチェックされます。ユーザーを管理するには管理者権限が必要です。\n",
|
"permissionsHelp": "ユーザーを管理者に設定するか、その他の権限を個別に選択することができます。「管理者」を選択すると、他のオプションはすべて自動的にチェックされます。ユーザーを管理するには管理者権限が必要です。\n",
|
||||||
"profileSettings": "プロフィール設定",
|
"profileSettings": "プロフィール設定",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": ".git や .gitignore のようなドットから始まるファイルへのアクセスを禁止します。\n",
|
"ruleExample1": ".git や .gitignore のようなドットから始まるファイルへのアクセスを禁止します。\n",
|
||||||
"ruleExample2": "スコープのルートにある Caddyfile という名前のファイルへのアクセスを禁止します。",
|
"ruleExample2": "スコープのルートにある Caddyfile という名前のファイルへのアクセスを禁止します。",
|
||||||
"rules": "ルール",
|
"rules": "ルール",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "ユーザー管理",
|
"userManagement": "ユーザー管理",
|
||||||
"userUpdated": "ユーザーを更新しました!",
|
"userUpdated": "ユーザーを更新しました!",
|
||||||
"username": "ユーザー名",
|
"username": "ユーザー名",
|
||||||
"users": "ユーザー"
|
"users": "ユーザー",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "ヘルプ",
|
"help": "ヘルプ",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "업로드",
|
"upload": "업로드",
|
||||||
"openFile": "파일 열기",
|
"openFile": "파일 열기",
|
||||||
"discardChanges": "변경 사항 취소",
|
"discardChanges": "변경 사항 취소",
|
||||||
"saveChanges": "변경사항 저장"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "변경사항 저장",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "파일 다운로드",
|
"downloadFile": "파일 다운로드",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "수정시간순 정렬",
|
"sortByLastModified": "수정시간순 정렬",
|
||||||
"sortByName": "이름순",
|
"sortByName": "이름순",
|
||||||
"sortBySize": "크기순",
|
"sortBySize": "크기순",
|
||||||
"noPreview": "미리 보기가 지원되지 않는 파일 유형입니다."
|
"noPreview": "미리 보기가 지원되지 않는 파일 유형입니다.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "파일이나 디렉토리를 선택해주세요.",
|
"click": "파일이나 디렉토리를 선택해주세요.",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "사용자 이름",
|
"username": "사용자 이름",
|
||||||
"usernameTaken": "사용자 이름이 존재합니다",
|
"usernameTaken": "사용자 이름이 존재합니다",
|
||||||
"wrongCredentials": "사용자 이름 또는 비밀번호를 확인하십시오",
|
"wrongCredentials": "사용자 이름 또는 비밀번호를 확인하십시오",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "파일/디렉토리 생성 허용",
|
"allowNew": "파일/디렉토리 생성 허용",
|
||||||
"allowPublish": "새 포스트/페이지 생성 허용",
|
"allowPublish": "새 포스트/페이지 생성 허용",
|
||||||
"allowSignup": "사용자 가입 허용",
|
"allowSignup": "사용자 가입 허용",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(수정하지 않으면 비워두세요)",
|
"avoidChanges": "(수정하지 않으면 비워두세요)",
|
||||||
"branding": "브랜딩",
|
"branding": "브랜딩",
|
||||||
"brandingDirectoryPath": "브랜드 디렉토리 경로",
|
"brandingDirectoryPath": "브랜드 디렉토리 경로",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "권한",
|
"permissions": "권한",
|
||||||
"permissionsHelp": "사용자를 관리자로 만들거나 권한을 부여할 수 있습니다. 관리자를 선택하면, 모든 옵션이 자동으로 선택됩니다. 사용자 관리는 현재 관리자만 할 수 있습니다.\n",
|
"permissionsHelp": "사용자를 관리자로 만들거나 권한을 부여할 수 있습니다. 관리자를 선택하면, 모든 옵션이 자동으로 선택됩니다. 사용자 관리는 현재 관리자만 할 수 있습니다.\n",
|
||||||
"profileSettings": "프로필 설정",
|
"profileSettings": "프로필 설정",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "점(.)으로 시작하는 모든 파일의 접근을 방지합니다.(예 .git, .gitignore)\n",
|
"ruleExample1": "점(.)으로 시작하는 모든 파일의 접근을 방지합니다.(예 .git, .gitignore)\n",
|
||||||
"ruleExample2": "Caddyfile파일의 접근을 방지합니다.",
|
"ruleExample2": "Caddyfile파일의 접근을 방지합니다.",
|
||||||
"rules": "룰",
|
"rules": "룰",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "사용자 관리",
|
"userManagement": "사용자 관리",
|
||||||
"userUpdated": "사용자 수정됨!",
|
"userUpdated": "사용자 수정됨!",
|
||||||
"username": "사용자 이름",
|
"username": "사용자 이름",
|
||||||
"users": "사용자"
|
"users": "사용자",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "도움말",
|
"help": "도움말",
|
||||||
|
|
|
||||||
288
frontend/src/i18n/lv.json
Normal file
288
frontend/src/i18n/lv.json
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
{
|
||||||
|
"buttons": {
|
||||||
|
"cancel": "Atcelt",
|
||||||
|
"clear": "Tīrs",
|
||||||
|
"close": "Aizvērt",
|
||||||
|
"continue": "Turpināt",
|
||||||
|
"copy": "Kopēt",
|
||||||
|
"copyFile": "Kopēt failu",
|
||||||
|
"copyToClipboard": "Kopēt starpliktuvē",
|
||||||
|
"copyDownloadLinkToClipboard": "Kopēt lejupielādes saiti starpliktuvē",
|
||||||
|
"create": "Izveidot",
|
||||||
|
"delete": "Dzēst",
|
||||||
|
"download": "Lejupielādēt",
|
||||||
|
"file": "Fails",
|
||||||
|
"folder": "Mape",
|
||||||
|
"fullScreen": "Pārslēgt pilnekrāna režīmu",
|
||||||
|
"hideDotfiles": "Slēpt punktfailus",
|
||||||
|
"info": "Informācija",
|
||||||
|
"more": "Vairāk",
|
||||||
|
"move": "Pārvietot",
|
||||||
|
"moveFile": "Pārvietot failu",
|
||||||
|
"new": "Jauns",
|
||||||
|
"next": "Nākamais",
|
||||||
|
"ok": "Labi",
|
||||||
|
"permalink": "Iegūt pastāvīgo saiti",
|
||||||
|
"previous": "Iepriekšējais",
|
||||||
|
"preview": "Priekšskatījums",
|
||||||
|
"publish": "Publicēt",
|
||||||
|
"rename": "Pārdēvēt",
|
||||||
|
"replace": "Aizstāt",
|
||||||
|
"reportIssue": "Ziņot par problēmu",
|
||||||
|
"save": "Saglabāt",
|
||||||
|
"schedule": "Grafiks",
|
||||||
|
"search": "Meklēt",
|
||||||
|
"select": "Izvēlieties",
|
||||||
|
"selectMultiple": "Izvēlieties vairākus",
|
||||||
|
"share": "Dalīties",
|
||||||
|
"shell": "Pārslēgt apvalku",
|
||||||
|
"submit": "Iesniegt",
|
||||||
|
"switchView": "Pārslēgt skatu",
|
||||||
|
"toggleSidebar": "Pārslēgt sānjoslu",
|
||||||
|
"update": "Atjaunināt",
|
||||||
|
"upload": "Augšupielādēt",
|
||||||
|
"openFile": "Atvērt failu",
|
||||||
|
"discardChanges": "Izmest",
|
||||||
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Saglabāt izmaiņas",
|
||||||
|
"editAsText": "Rediģēt kā tekstu",
|
||||||
|
"increaseFontSize": "Palieliniet fonta lielumu",
|
||||||
|
"decreaseFontSize": "Samaziniet fonta lielumu"
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"downloadFile": "Lejupielādēt failu",
|
||||||
|
"downloadFolder": "Lejupielādēt mapi",
|
||||||
|
"downloadSelected": "Lejupielādēt atlasīto"
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"abortUpload": "Vai tiešām vēlaties pārtraukt?"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"forbidden": "Jums nav atļaujas piekļūt šim.",
|
||||||
|
"internal": "Kaut kas tiešām nogāja greizi.",
|
||||||
|
"notFound": "Šo atrašanās vietu nevar sasniegt.",
|
||||||
|
"connection": "Ar serveri nevar sazināties."
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"body": "Ķermenis",
|
||||||
|
"closePreview": "Aizvērt priekšskatījumu",
|
||||||
|
"files": "Faili",
|
||||||
|
"folders": "Mapes",
|
||||||
|
"home": "Sākums",
|
||||||
|
"lastModified": "Pēdējoreiz modificēts",
|
||||||
|
"loading": "Notiek ielāde...",
|
||||||
|
"lonely": "Šeit ir tukša vieta...",
|
||||||
|
"metadata": "Metadati",
|
||||||
|
"multipleSelectionEnabled": "Vairākas atlases ir iespējotas",
|
||||||
|
"name": "Vārds",
|
||||||
|
"size": "Izmērs",
|
||||||
|
"sortByLastModified": "Kārtot pēc pēdējās modifikācijas",
|
||||||
|
"sortByName": "Kārtot pēc nosaukuma",
|
||||||
|
"sortBySize": "Kārtot pēc izmēra",
|
||||||
|
"noPreview": "Šim failam nav pieejams priekšskatījums.",
|
||||||
|
"csvTooLarge": "CSV fails ir pārāk liels priekšskatīšanai (>5 MB). Lūdzu, lejupielādējiet to, lai skatītu",
|
||||||
|
"csvLoadFailed": "Neizdevās ielādēt CSV failu.",
|
||||||
|
"showingRows": "Rāda {count} rindu(as)",
|
||||||
|
"columnSeparator": "Kolonnu atdalītājs",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Komats (,)",
|
||||||
|
"semicolon": "Semikols (;)",
|
||||||
|
"both": "Gan (,) gan (;)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"click": "atlasiet failu vai direktoriju",
|
||||||
|
"ctrl": {
|
||||||
|
"click": "atlasīt vairākus failus vai direktorijus",
|
||||||
|
"f": "atver meklēšanu",
|
||||||
|
"s": "saglabājiet failu vai lejupielādējiet direktoriju, kurā atrodaties"
|
||||||
|
},
|
||||||
|
"del": "dzēst atlasītos vienumus",
|
||||||
|
"doubleClick": "atvērt failu vai direktoriju",
|
||||||
|
"esc": "notīrīt atlasi un/vai aizvērt uzvedni",
|
||||||
|
"f1": "šo informāciju",
|
||||||
|
"f2": "pārdēvēt failu",
|
||||||
|
"help": "Palīdzība"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"createAnAccount": "Izveidot kontu",
|
||||||
|
"loginInstead": "Jau ir konts",
|
||||||
|
"password": "Parole",
|
||||||
|
"passwordConfirm": "Paroles apstiprināšana",
|
||||||
|
"passwordsDontMatch": "Paroles nesakrīt",
|
||||||
|
"signup": "Reģistrēšanās",
|
||||||
|
"submit": "Pieteikties",
|
||||||
|
"username": "Lietotājvārds",
|
||||||
|
"usernameTaken": "Lietotājvārds jau aizņemts",
|
||||||
|
"wrongCredentials": "Nepareizi akreditācijas dati",
|
||||||
|
"passwordTooShort": "Parolei jābūt vismaz {min} rakstzīmju garai",
|
||||||
|
"logout_reasons": {
|
||||||
|
"inactivity": "Jūs esat atteicies no sistēmas neaktivitātes dēļ."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permanent": "Pastāvīgs",
|
||||||
|
"prompts": {
|
||||||
|
"copy": "Kopēt",
|
||||||
|
"copyMessage": "Izvēlieties atrašanās vietu, uz kuru kopēt failus:",
|
||||||
|
"currentlyNavigating": "Pašlaik navigācija:",
|
||||||
|
"deleteMessageMultiple": "Vai tiešām vēlaties dzēst {count} failu(s)?",
|
||||||
|
"deleteMessageSingle": "Vai tiešām vēlaties dzēst šo failu/mapi?",
|
||||||
|
"deleteMessageShare": "Vai tiešām vēlaties dzēst šo koplietojumu({path})?",
|
||||||
|
"deleteUser": "Vai tiešām vēlaties dzēst šo lietotāju?",
|
||||||
|
"deleteTitle": "Dzēst failus",
|
||||||
|
"displayName": "Displeja nosaukums:",
|
||||||
|
"download": "Lejupielādēt failus",
|
||||||
|
"downloadMessage": "Izvēlieties formātu, kuru vēlaties lejupielādēt.",
|
||||||
|
"error": "Kaut kas nogāja greizi",
|
||||||
|
"fileInfo": "Informācija par failu",
|
||||||
|
"filesSelected": "{count} atlasīti faili",
|
||||||
|
"lastModified": "Pēdējās izmaiņas",
|
||||||
|
"move": "Pārvietot",
|
||||||
|
"moveMessage": "Izvēlieties jaunu mājvietu failam(iem)/mapei(ēm):",
|
||||||
|
"newArchetype": "Izveidojiet jaunu ierakstu, pamatojoties uz arhtipu. Jūsu fails tiks izveidots satura mapē.",
|
||||||
|
"newDir": "Jauna direktorija",
|
||||||
|
"newDirMessage": "Nosaukums savai jaunajai direktorijai.",
|
||||||
|
"newFile": "Jauns fails",
|
||||||
|
"newFileMessage": "Nosauciet savu jauno failu.",
|
||||||
|
"numberDirs": "Katalogu skaits",
|
||||||
|
"numberFiles": "Failu skaits",
|
||||||
|
"rename": "Pārdēvēt",
|
||||||
|
"renameMessage": "Ievietojiet jaunu nosaukumu",
|
||||||
|
"replace": "Aizstāt",
|
||||||
|
"replaceMessage": "Vienam no failiem, kurus mēģināt augšupielādēt, ir konfliktējošs nosaukums. Vai vēlaties izlaist šo failu un turpināt augšupielādi vai aizstāt esošo?\n",
|
||||||
|
"schedule": "Grafiks",
|
||||||
|
"scheduleMessage": "Izvēlieties datumu un laiku, lai ieplānotu šī ieraksta publicēšanu.",
|
||||||
|
"show": "Rādīt",
|
||||||
|
"size": "Izmērs",
|
||||||
|
"upload": "Augšupielādēt",
|
||||||
|
"uploadFiles": "Notiek {files} failu augšupielāde...",
|
||||||
|
"uploadMessage": "Atlasiet augšupielādes opciju.",
|
||||||
|
"optionalPassword": "Izvēles parole",
|
||||||
|
"resolution": "Izšķirtspēja",
|
||||||
|
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"images": "Attēli",
|
||||||
|
"music": "Mūzika",
|
||||||
|
"pdf": "PDF",
|
||||||
|
"pressToSearch": "Nospiediet taustiņu Enter, lai meklētu...",
|
||||||
|
"search": "Meklē...",
|
||||||
|
"typeToSearch": "Ierakstiet, lai meklētu...",
|
||||||
|
"types": "Veidi",
|
||||||
|
"video": "Video"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"aceEditorTheme": "Ace redaktora tēma",
|
||||||
|
"admin": "Admin",
|
||||||
|
"administrator": "Administrator",
|
||||||
|
"allowCommands": "Izpildīt komandas",
|
||||||
|
"allowEdit": "Rediģēt, pārdēvēt un dzēst failus vai direktorijus",
|
||||||
|
"allowNew": "Izveidojiet jaunus failus un direktorijus",
|
||||||
|
"allowPublish": "Publicēt jaunus ierakstus un lapas",
|
||||||
|
"allowSignup": "Atļaut lietotājiem reģistrēties",
|
||||||
|
"hideLoginButton": "Paslēpt pieteikšanās pogu publiskajās lapās",
|
||||||
|
"avoidChanges": "(atstājiet tukšu, lai izvairītos no izmaiņām)",
|
||||||
|
"branding": "Zīmols",
|
||||||
|
"brandingDirectoryPath": "Zīmola direktorijas ceļš",
|
||||||
|
"brandingHelp": "Jūs varat pielāgot sava failu pārlūka instances izskatu un darbību, mainot tās nosaukumu, aizstājot logotipu, pievienojot pielāgotus stilus un pat atspējojot ārējās saites uz GitHub.\nLai iegūtu plašāku informāciju par pielāgotu zīmola veidošanu, lūdzu, skatiet {0}.",
|
||||||
|
"changePassword": "Mainīt paroli",
|
||||||
|
"commandRunner": "Komandu skrējējs",
|
||||||
|
"commandRunnerHelp": "Šeit varat iestatīt komandas, kas tiek izpildītas nosauktajos notikumos. Katrā rindā jāraksta pa vienai. Būs pieejami vides mainīgie {0} un {1}, kas ir {0} relatīvi pret {1}. Lai iegūtu plašāku informāciju par šo funkciju un pieejamajiem vides mainīgajiem, lūdzu, izlasiet {2}.",
|
||||||
|
"commandsUpdated": "Komandas atjauninātas!",
|
||||||
|
"createUserDir": "Automātiski izveidot lietotāja mājas direktoriju, pievienojot jaunu lietotāju",
|
||||||
|
"minimumPasswordLength": "Minimālais paroles garums",
|
||||||
|
"tusUploads": "Sadalītas augšupielādes",
|
||||||
|
"tusUploadsHelp": "Failu pārlūks atbalsta failu augšupielādi fragmentos, ļaujot izveidot efektīvu, uzticamu, atsākamu un fragmentos sadalītu failu augšupielādi pat neuzticamos tīklos.",
|
||||||
|
"tusUploadsChunkSize": "Norāda pieprasījuma maksimālo izmēru (mazākiem augšupielādes apjomiem tiks izmantota tieša augšupielāde). Varat ievadīt vienkāršu veselu skaitli, kas apzīmē baitu izmēru, vai virkni, piemēram, 10 MB, 1 GB utt.",
|
||||||
|
"tusUploadsRetryCount": "Atkārtotu mēģinājumu skaits, kas jāveic, ja fragmenta augšupielāde neizdodas.",
|
||||||
|
"userHomeBasePath": "Lietotāja mājas direktoriju bāzes ceļš",
|
||||||
|
"userScopeGenerationPlaceholder": "Darbības joma tiks ģenerēta automātiski",
|
||||||
|
"createUserHomeDirectory": "Izveidojiet lietotāja mājas direktoriju",
|
||||||
|
"customStylesheet": "Pielāgota stila lapa",
|
||||||
|
"defaultUserDescription": "Šie ir noklusējuma iestatījumi jaunajiem lietotājiem.",
|
||||||
|
"disableExternalLinks": "Atspējot ārējās saites (izņemot dokumentāciju)",
|
||||||
|
"disableUsedDiskPercentage": "Atspējot izmantotā diska procentuālās daļas grafiku",
|
||||||
|
"documentation": "dokumentācija",
|
||||||
|
"examples": "Piemēri",
|
||||||
|
"executeOnShell": "Izpildīt uz čaulas",
|
||||||
|
"executeOnShellDescription": "Pēc noklusējuma failu pārlūks izpilda komandas, tieši izsaucot to bināros failus. Ja vēlaties tās palaist čaulā (piemēram, Bash vai PowerShell), varat to definēt šeit ar nepieciešamajiem argumentiem un karodziņiem. Ja tas ir iestatīts, izpildītā komanda tiks pievienota kā arguments. Tas attiecas gan uz lietotāja komandām, gan notikumu piesaistes rīkiem.",
|
||||||
|
"globalRules": "Šis ir globāls atļaušanas un aizliegšanas noteikumu kopums. Tie attiecas uz katru lietotāju. Katra lietotāja iestatījumos varat definēt konkrētus noteikumus, lai tos ignorētu.",
|
||||||
|
"globalSettings": "Globālie iestatījumi",
|
||||||
|
"hideDotfiles": "Slēpt punktfailus",
|
||||||
|
"insertPath": "Ievietojiet ceļu",
|
||||||
|
"insertRegex": "Ievietojiet regex izteiksmi",
|
||||||
|
"instanceName": "Gadījuma nosaukums",
|
||||||
|
"language": "Valoda",
|
||||||
|
"lockPassword": "Neļaut lietotājam mainīt paroli",
|
||||||
|
"newPassword": "Jūsu jaunā parole",
|
||||||
|
"newPasswordConfirm": "Apstipriniet savu jauno paroli",
|
||||||
|
"newUser": "Jauns lietotājs",
|
||||||
|
"password": "Parole",
|
||||||
|
"passwordUpdated": "Parole atjaunināta!",
|
||||||
|
"path": "Ceļš",
|
||||||
|
"perm": {
|
||||||
|
"create": "Izveidojiet failus un direktorijus",
|
||||||
|
"delete": "Dzēst failus un direktorijus",
|
||||||
|
"download": "Lejupielādēt",
|
||||||
|
"execute": "Izpildīt komandas",
|
||||||
|
"modify": "Rediģēt failus",
|
||||||
|
"rename": "Pārdēvēt vai pārvietot failus un direktorijus",
|
||||||
|
"share": "Kopīgojiet failus"
|
||||||
|
},
|
||||||
|
"permissions": "Atļaujas",
|
||||||
|
"permissionsHelp": "Varat iestatīt lietotāju kā administratoru vai izvēlēties atļaujas individuāli. Ja atlasīsiet “Administrators”, visas pārējās opcijas tiks automātiski atzīmētas. Lietotāju pārvaldība joprojām ir administratora privilēģija.\n",
|
||||||
|
"profileSettings": "Profila iestatījumi",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
|
"ruleExample1": "neļauj piekļūt jebkuram dotfile failam (piemēram, .git, .gitignore) katrā mapē.\n",
|
||||||
|
"ruleExample2": "bloķē piekļuvi failam ar nosaukumu Caddyfile darbības jomas saknē.",
|
||||||
|
"rules": "Noteikumi",
|
||||||
|
"rulesHelp": "Šeit varat definēt atļaušanas un aizliegšanas noteikumu kopu šim konkrētajam lietotājam. Bloķētie faili netiks rādīti sarakstos, un lietotājs tiem nevarēs piekļūt. Mēs atbalstām regulārās izteiksmes un ceļus attiecībā pret lietotāja darbības jomu.\n",
|
||||||
|
"scope": "Darbības joma",
|
||||||
|
"setDateFormat": "Iestatiet precīzu datuma formātu",
|
||||||
|
"settingsUpdated": "Iestatījumi atjaunināti!",
|
||||||
|
"shareDuration": "Kopīgošanas ilgums",
|
||||||
|
"shareManagement": "Kopīgošanas pārvaldība",
|
||||||
|
"shareDeleted": "Kopīgošana ir izdzēsta!",
|
||||||
|
"singleClick": "Failu un direktoriju atvēršanai izmantojiet vienus klikšķi",
|
||||||
|
"themes": {
|
||||||
|
"default": "Sistēmas noklusējums",
|
||||||
|
"dark": "Tumša",
|
||||||
|
"light": "Gaiša",
|
||||||
|
"title": "Tēma"
|
||||||
|
},
|
||||||
|
"user": "Lietotājs",
|
||||||
|
"userCommands": "Komandas",
|
||||||
|
"userCommandsHelp": "Ar atstarpi atdalīts saraksts ar šim lietotājam pieejamajām komandām. Piemērs:\n",
|
||||||
|
"userCreated": "Lietotājs izveidots!",
|
||||||
|
"userDefaults": "Lietotāja noklusējuma iestatījumi",
|
||||||
|
"userDeleted": "Lietotājs izdzēsts!",
|
||||||
|
"userManagement": "Lietotāju pārvaldība",
|
||||||
|
"userUpdated": "Lietotājs atjaunināts!",
|
||||||
|
"username": "Lietotājvārds",
|
||||||
|
"users": "Lietotāji",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"help": "Palīdzība",
|
||||||
|
"hugoNew": "Hugo Jauns",
|
||||||
|
"login": "Pieteikties",
|
||||||
|
"logout": "Atteikties",
|
||||||
|
"myFiles": "Mani faili",
|
||||||
|
"newFile": "Jauns fails",
|
||||||
|
"newFolder": "Jauna mape",
|
||||||
|
"preview": "Priekšskatījums",
|
||||||
|
"settings": "Iestatījumi",
|
||||||
|
"signup": "Reģistrēties",
|
||||||
|
"siteSettings": "Vietnes iestatījumi"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"linkCopied": "Saite nokopēta!"
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"days": "Dienas",
|
||||||
|
"hours": "Stundas",
|
||||||
|
"minutes": "Minūtes",
|
||||||
|
"seconds": "Sekundes",
|
||||||
|
"unit": "Laika vienība"
|
||||||
|
}
|
||||||
|
}
|
||||||
288
frontend/src/i18n/lv_LV.json
Normal file
288
frontend/src/i18n/lv_LV.json
Normal file
|
|
@ -0,0 +1,288 @@
|
||||||
|
{
|
||||||
|
"buttons": {
|
||||||
|
"cancel": "Atcelt",
|
||||||
|
"clear": "Tīrs",
|
||||||
|
"close": "Aizvērt",
|
||||||
|
"continue": "Turpināt",
|
||||||
|
"copy": "Kopēt",
|
||||||
|
"copyFile": "Kopēt failu",
|
||||||
|
"copyToClipboard": "Kopēt starpliktuvē",
|
||||||
|
"copyDownloadLinkToClipboard": "Kopēt lejupielādes saiti starpliktuvē",
|
||||||
|
"create": "Izveidot",
|
||||||
|
"delete": "Dzēst",
|
||||||
|
"download": "Lejupielādēt",
|
||||||
|
"file": "Fails",
|
||||||
|
"folder": "Mape",
|
||||||
|
"fullScreen": "Pārslēgt pilnekrāna režīmu",
|
||||||
|
"hideDotfiles": "Slēpt punktfailus",
|
||||||
|
"info": "Informācija",
|
||||||
|
"more": "Vairāk",
|
||||||
|
"move": "Pārvietot",
|
||||||
|
"moveFile": "Pārvietot failu",
|
||||||
|
"new": "Jauns",
|
||||||
|
"next": "Nākamais",
|
||||||
|
"ok": "Labi",
|
||||||
|
"permalink": "Iegūt pastāvīgo saiti",
|
||||||
|
"previous": "Iepriekšējais",
|
||||||
|
"preview": "Priekšskatījums",
|
||||||
|
"publish": "Publicēt",
|
||||||
|
"rename": "Pārdēvēt",
|
||||||
|
"replace": "Aizstāt",
|
||||||
|
"reportIssue": "Ziņot par problēmu",
|
||||||
|
"save": "Saglabāt",
|
||||||
|
"schedule": "Grafiks",
|
||||||
|
"search": "Meklēt",
|
||||||
|
"select": "Izvēlieties",
|
||||||
|
"selectMultiple": "Izvēlieties vairākus",
|
||||||
|
"share": "Dalīties",
|
||||||
|
"shell": "Pārslēgt apvalku",
|
||||||
|
"submit": "Iesniegt",
|
||||||
|
"switchView": "Pārslēgt skatu",
|
||||||
|
"toggleSidebar": "Pārslēgt sānjoslu",
|
||||||
|
"update": "Atjaunināt",
|
||||||
|
"upload": "Augšupielādēt",
|
||||||
|
"openFile": "Atvērt failu",
|
||||||
|
"discardChanges": "Izmest",
|
||||||
|
"stopSearch": "Beigt meklēšanu",
|
||||||
|
"saveChanges": "Saglabāt izmaiņas",
|
||||||
|
"editAsText": "Rediģēt kā tekstu",
|
||||||
|
"increaseFontSize": "Palieliniet fonta lielumu",
|
||||||
|
"decreaseFontSize": "Samaziniet fonta lielumu"
|
||||||
|
},
|
||||||
|
"download": {
|
||||||
|
"downloadFile": "Lejupielādēt failu",
|
||||||
|
"downloadFolder": "Lejupielādēt mapi",
|
||||||
|
"downloadSelected": "Lejupielādēt atlasīto"
|
||||||
|
},
|
||||||
|
"upload": {
|
||||||
|
"abortUpload": "Vai tiešām vēlaties pārtraukt?"
|
||||||
|
},
|
||||||
|
"errors": {
|
||||||
|
"forbidden": "Jums nav atļaujas piekļūt šim.",
|
||||||
|
"internal": "Kaut kas tiešām nogāja greizi.",
|
||||||
|
"notFound": "Šo atrašanās vietu nevar sasniegt.",
|
||||||
|
"connection": "Ar serveri nevar sazināties."
|
||||||
|
},
|
||||||
|
"files": {
|
||||||
|
"body": "Ķermenis",
|
||||||
|
"closePreview": "Aizvērt priekšskatījumu",
|
||||||
|
"files": "Faili",
|
||||||
|
"folders": "Mapes",
|
||||||
|
"home": "Sākums",
|
||||||
|
"lastModified": "Pēdējoreiz modificēts",
|
||||||
|
"loading": "Notiek ielāde...",
|
||||||
|
"lonely": "Šeit ir tukša vieta...",
|
||||||
|
"metadata": "Metadati",
|
||||||
|
"multipleSelectionEnabled": "Vairākas atlases ir iespējotas",
|
||||||
|
"name": "Vārds",
|
||||||
|
"size": "Izmērs",
|
||||||
|
"sortByLastModified": "Kārtot pēc pēdējās modifikācijas",
|
||||||
|
"sortByName": "Kārtot pēc nosaukuma",
|
||||||
|
"sortBySize": "Kārtot pēc izmēra",
|
||||||
|
"noPreview": "Šim failam nav pieejams priekšskatījums.",
|
||||||
|
"csvTooLarge": "CSV fails ir pārāk liels priekšskatīšanai (>5 MB). Lūdzu, lejupielādējiet to, lai skatītu",
|
||||||
|
"csvLoadFailed": "Neizdevās ielādēt CSV failu.",
|
||||||
|
"showingRows": "Rāda {count} rindu(as)",
|
||||||
|
"columnSeparator": "Kolonnu atdalītājs",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Komats (,)",
|
||||||
|
"semicolon": "Semikols (;)",
|
||||||
|
"both": "Gan (,) gan (;)"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"help": {
|
||||||
|
"click": "atlasiet failu vai direktoriju",
|
||||||
|
"ctrl": {
|
||||||
|
"click": "atlasīt vairākus failus vai direktorijus",
|
||||||
|
"f": "atver meklēšanu",
|
||||||
|
"s": "saglabājiet failu vai lejupielādējiet direktoriju, kurā atrodaties"
|
||||||
|
},
|
||||||
|
"del": "dzēst atlasītos vienumus",
|
||||||
|
"doubleClick": "atvērt failu vai direktoriju",
|
||||||
|
"esc": "notīrīt atlasi un/vai aizvērt uzvedni",
|
||||||
|
"f1": "šo informāciju",
|
||||||
|
"f2": "pārdēvēt failu",
|
||||||
|
"help": "Palīdzība"
|
||||||
|
},
|
||||||
|
"login": {
|
||||||
|
"createAnAccount": "Izveidot kontu",
|
||||||
|
"loginInstead": "Jau ir konts",
|
||||||
|
"password": "Parole",
|
||||||
|
"passwordConfirm": "Paroles apstiprināšana",
|
||||||
|
"passwordsDontMatch": "Paroles nesakrīt",
|
||||||
|
"signup": "Reģistrēšanās",
|
||||||
|
"submit": "Pieteikties",
|
||||||
|
"username": "Lietotājvārds",
|
||||||
|
"usernameTaken": "Lietotājvārds jau aizņemts",
|
||||||
|
"wrongCredentials": "Nepareizi akreditācijas dati",
|
||||||
|
"passwordTooShort": "Parolei jābūt vismaz {min} rakstzīmju garai",
|
||||||
|
"logout_reasons": {
|
||||||
|
"inactivity": "Jūs esat atteicies no sistēmas neaktivitātes dēļ."
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"permanent": "Pastāvīgs",
|
||||||
|
"prompts": {
|
||||||
|
"copy": "Kopēt",
|
||||||
|
"copyMessage": "Izvēlieties atrašanās vietu, uz kuru kopēt failus:",
|
||||||
|
"currentlyNavigating": "Pašlaik navigācija:",
|
||||||
|
"deleteMessageMultiple": "Vai tiešām vēlaties dzēst {count} failu(s)?",
|
||||||
|
"deleteMessageSingle": "Vai tiešām vēlaties dzēst šo failu/mapi?",
|
||||||
|
"deleteMessageShare": "Vai tiešām vēlaties dzēst šo koplietojumu({path})?",
|
||||||
|
"deleteUser": "Vai tiešām vēlaties dzēst šo lietotāju?",
|
||||||
|
"deleteTitle": "Dzēst failus",
|
||||||
|
"displayName": "Displeja nosaukums:",
|
||||||
|
"download": "Lejupielādēt failus",
|
||||||
|
"downloadMessage": "Izvēlieties formātu, kuru vēlaties lejupielādēt.",
|
||||||
|
"error": "Kaut kas nogāja greizi",
|
||||||
|
"fileInfo": "Informācija par failu",
|
||||||
|
"filesSelected": "{count} atlasīti faili",
|
||||||
|
"lastModified": "Pēdējās izmaiņas",
|
||||||
|
"move": "Pārvietot",
|
||||||
|
"moveMessage": "Izvēlieties jaunu mājvietu failam(iem)/mapei(ēm):",
|
||||||
|
"newArchetype": "Izveidojiet jaunu ierakstu, pamatojoties uz arhtipu. Jūsu fails tiks izveidots satura mapē.",
|
||||||
|
"newDir": "Jauna direktorija",
|
||||||
|
"newDirMessage": "Nosaukums savai jaunajai direktorijai.",
|
||||||
|
"newFile": "Jauns fails",
|
||||||
|
"newFileMessage": "Nosauciet savu jauno failu.",
|
||||||
|
"numberDirs": "Katalogu skaits",
|
||||||
|
"numberFiles": "Failu skaits",
|
||||||
|
"rename": "Pārdēvēt",
|
||||||
|
"renameMessage": "Ievietojiet jaunu nosaukumu",
|
||||||
|
"replace": "Aizstāt",
|
||||||
|
"replaceMessage": "Vienam no failiem, kurus mēģināt augšupielādēt, ir konfliktējošs nosaukums. Vai vēlaties izlaist šo failu un turpināt augšupielādi vai aizstāt esošo?\n",
|
||||||
|
"schedule": "Grafiks",
|
||||||
|
"scheduleMessage": "Izvēlieties datumu un laiku, lai ieplānotu šī ieraksta publicēšanu.",
|
||||||
|
"show": "Rādīt",
|
||||||
|
"size": "Izmērs",
|
||||||
|
"upload": "Augšupielādēt",
|
||||||
|
"uploadFiles": "Notiek {files} failu augšupielāde...",
|
||||||
|
"uploadMessage": "Atlasiet augšupielādes opciju.",
|
||||||
|
"optionalPassword": "Izvēles parole",
|
||||||
|
"resolution": "Izšķirtspēja",
|
||||||
|
"discardEditorChanges": "Vai tiešām vēlaties atmest veiktās izmaiņas?"
|
||||||
|
},
|
||||||
|
"search": {
|
||||||
|
"images": "Attēli",
|
||||||
|
"music": "Mūzika",
|
||||||
|
"pdf": "PDF",
|
||||||
|
"pressToSearch": "Nospiediet taustiņu Enter, lai meklētu...",
|
||||||
|
"search": "Meklē...",
|
||||||
|
"typeToSearch": "Ierakstiet, lai meklētu...",
|
||||||
|
"types": "Veidi",
|
||||||
|
"video": "Video"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"aceEditorTheme": "Ace redaktora tēma",
|
||||||
|
"admin": "Admin",
|
||||||
|
"administrator": "Administrator",
|
||||||
|
"allowCommands": "Izpildīt komandas",
|
||||||
|
"allowEdit": "Rediģēt, pārdēvēt un dzēst failus vai direktorijus",
|
||||||
|
"allowNew": "Izveidojiet jaunus failus un direktorijus",
|
||||||
|
"allowPublish": "Publicēt jaunus ierakstus un lapas",
|
||||||
|
"allowSignup": "Atļaut lietotājiem reģistrēties",
|
||||||
|
"hideLoginButton": "Paslēpt pieteikšanās pogu publiskajās lapās",
|
||||||
|
"avoidChanges": "(atstājiet tukšu, lai izvairītos no izmaiņām)",
|
||||||
|
"branding": "Zīmols",
|
||||||
|
"brandingDirectoryPath": "Zīmola direktorijas ceļš",
|
||||||
|
"brandingHelp": "Jūs varat pielāgot sava failu pārlūka instances izskatu un darbību, mainot tās nosaukumu, aizstājot logotipu, pievienojot pielāgotus stilus un pat atspējojot ārējās saites uz GitHub.\nLai iegūtu plašāku informāciju par pielāgotu zīmola veidošanu, lūdzu, skatiet {0}.",
|
||||||
|
"changePassword": "Mainīt paroli",
|
||||||
|
"commandRunner": "Komandu skrējējs",
|
||||||
|
"commandRunnerHelp": "Šeit varat iestatīt komandas, kas tiek izpildītas nosauktajos notikumos. Katrā rindā jāraksta pa vienai. Būs pieejami vides mainīgie {0} un {1}, kas ir {0} relatīvi pret {1}. Lai iegūtu plašāku informāciju par šo funkciju un pieejamajiem vides mainīgajiem, lūdzu, izlasiet {2}.",
|
||||||
|
"commandsUpdated": "Komandas atjauninātas!",
|
||||||
|
"createUserDir": "Automātiski izveidot lietotāja mājas direktoriju, pievienojot jaunu lietotāju",
|
||||||
|
"minimumPasswordLength": "Minimālais paroles garums",
|
||||||
|
"tusUploads": "Sadalītas augšupielādes",
|
||||||
|
"tusUploadsHelp": "Failu pārlūks atbalsta failu augšupielādi fragmentos, ļaujot izveidot efektīvu, uzticamu, atsākamu un fragmentos sadalītu failu augšupielādi pat neuzticamos tīklos.",
|
||||||
|
"tusUploadsChunkSize": "Norāda pieprasījuma maksimālo izmēru (mazākiem augšupielādes apjomiem tiks izmantota tieša augšupielāde). Varat ievadīt vienkāršu veselu skaitli, kas apzīmē baitu izmēru, vai virkni, piemēram, 10 MB, 1 GB utt.",
|
||||||
|
"tusUploadsRetryCount": "Atkārtotu mēģinājumu skaits, kas jāveic, ja fragmenta augšupielāde neizdodas.",
|
||||||
|
"userHomeBasePath": "Lietotāja mājas direktoriju bāzes ceļš",
|
||||||
|
"userScopeGenerationPlaceholder": "Darbības joma tiks ģenerēta automātiski",
|
||||||
|
"createUserHomeDirectory": "Izveidojiet lietotāja mājas direktoriju",
|
||||||
|
"customStylesheet": "Pielāgota stila lapa",
|
||||||
|
"defaultUserDescription": "Šie ir noklusējuma iestatījumi jaunajiem lietotājiem.",
|
||||||
|
"disableExternalLinks": "Atspējot ārējās saites (izņemot dokumentāciju)",
|
||||||
|
"disableUsedDiskPercentage": "Atspējot izmantotā diska procentuālās daļas grafiku",
|
||||||
|
"documentation": "dokumentācija",
|
||||||
|
"examples": "Piemēri",
|
||||||
|
"executeOnShell": "Izpildīt uz čaulas",
|
||||||
|
"executeOnShellDescription": "Pēc noklusējuma failu pārlūks izpilda komandas, tieši izsaucot to bināros failus. Ja vēlaties tās palaist čaulā (piemēram, Bash vai PowerShell), varat to definēt šeit ar nepieciešamajiem argumentiem un karodziņiem. Ja tas ir iestatīts, izpildītā komanda tiks pievienota kā arguments. Tas attiecas gan uz lietotāja komandām, gan notikumu piesaistes rīkiem.",
|
||||||
|
"globalRules": "Šis ir globāls atļaušanas un aizliegšanas noteikumu kopums. Tie attiecas uz katru lietotāju. Katra lietotāja iestatījumos varat definēt konkrētus noteikumus, lai tos ignorētu.",
|
||||||
|
"globalSettings": "Globālie iestatījumi",
|
||||||
|
"hideDotfiles": "Slēpt punktfailus",
|
||||||
|
"insertPath": "Ievietojiet ceļu",
|
||||||
|
"insertRegex": "Ievietojiet regex izteiksmi",
|
||||||
|
"instanceName": "Gadījuma nosaukums",
|
||||||
|
"language": "Valoda",
|
||||||
|
"lockPassword": "Neļaut lietotājam mainīt paroli",
|
||||||
|
"newPassword": "Jūsu jaunā parole",
|
||||||
|
"newPasswordConfirm": "Apstipriniet savu jauno paroli",
|
||||||
|
"newUser": "Jauns lietotājs",
|
||||||
|
"password": "Parole",
|
||||||
|
"passwordUpdated": "Parole atjaunināta!",
|
||||||
|
"path": "Ceļš",
|
||||||
|
"perm": {
|
||||||
|
"create": "Izveidojiet failus un direktorijus",
|
||||||
|
"delete": "Dzēst failus un direktorijus",
|
||||||
|
"download": "Lejupielādēt",
|
||||||
|
"execute": "Izpildīt komandas",
|
||||||
|
"modify": "Rediģēt failus",
|
||||||
|
"rename": "Pārdēvēt vai pārvietot failus un direktorijus",
|
||||||
|
"share": "Kopīgojiet failus"
|
||||||
|
},
|
||||||
|
"permissions": "Atļaujas",
|
||||||
|
"permissionsHelp": "Varat iestatīt lietotāju kā administratoru vai izvēlēties atļaujas individuāli. Ja atlasīsiet “Administrators”, visas pārējās opcijas tiks automātiski atzīmētas. Lietotāju pārvaldība joprojām ir administratora privilēģija.\n",
|
||||||
|
"profileSettings": "Profila iestatījumi",
|
||||||
|
"redirectAfterCopyMove": "Pārvirzīt uz galapunktu pēc kopēšanas/pārvietošanas",
|
||||||
|
"ruleExample1": "neļauj piekļūt jebkuram dotfile failam (piemēram, .git, .gitignore) katrā mapē.\n",
|
||||||
|
"ruleExample2": "bloķē piekļuvi failam ar nosaukumu Caddyfile darbības jomas saknē.",
|
||||||
|
"rules": "Noteikumi",
|
||||||
|
"rulesHelp": "Šeit varat definēt atļaušanas un aizliegšanas noteikumu kopu šim konkrētajam lietotājam. Bloķētie faili netiks rādīti sarakstos, un lietotājs tiem nevarēs piekļūt. Mēs atbalstām regulārās izteiksmes un ceļus attiecībā pret lietotāja darbības jomu.\n",
|
||||||
|
"scope": "Darbības joma",
|
||||||
|
"setDateFormat": "Iestatiet precīzu datuma formātu",
|
||||||
|
"settingsUpdated": "Iestatījumi atjaunināti!",
|
||||||
|
"shareDuration": "Kopīgošanas ilgums",
|
||||||
|
"shareManagement": "Kopīgošanas pārvaldība",
|
||||||
|
"shareDeleted": "Kopīgojums izdzēsts!",
|
||||||
|
"singleClick": "Failu un direktoriju atvēršanai izmantojiet vienus klikšķi",
|
||||||
|
"themes": {
|
||||||
|
"default": "Sistēmas noklusējums",
|
||||||
|
"dark": "Tumša",
|
||||||
|
"light": "Gaiša",
|
||||||
|
"title": "Tēma"
|
||||||
|
},
|
||||||
|
"user": "Lietotājs",
|
||||||
|
"userCommands": "Komandas",
|
||||||
|
"userCommandsHelp": "Ar atstarpi atdalīts saraksts ar šim lietotājam pieejamajām komandām. Piemērs:\n",
|
||||||
|
"userCreated": "Lietotājs izveidots!",
|
||||||
|
"userDefaults": "Lietotāja noklusējuma iestatījumi",
|
||||||
|
"userDeleted": "Lietotājs izdzēsts!",
|
||||||
|
"userManagement": "Lietotāju pārvaldība",
|
||||||
|
"userUpdated": "Lietotājs atjaunināts!",
|
||||||
|
"username": "Lietotājvārds",
|
||||||
|
"users": "Lietotāji",
|
||||||
|
"currentPassword": "Esošā Parole"
|
||||||
|
},
|
||||||
|
"sidebar": {
|
||||||
|
"help": "Palīdzība",
|
||||||
|
"hugoNew": "Hugo Jauns",
|
||||||
|
"login": "Pieteikties",
|
||||||
|
"logout": "Atteikties",
|
||||||
|
"myFiles": "Mani faili",
|
||||||
|
"newFile": "Jauns fails",
|
||||||
|
"newFolder": "Jauna mape",
|
||||||
|
"preview": "Priekšskatījums",
|
||||||
|
"settings": "Iestatījumi",
|
||||||
|
"signup": "Reģistrēties",
|
||||||
|
"siteSettings": "Vietnes iestatījumi"
|
||||||
|
},
|
||||||
|
"success": {
|
||||||
|
"linkCopied": "Saite nokopēta!"
|
||||||
|
},
|
||||||
|
"time": {
|
||||||
|
"days": "Dienas",
|
||||||
|
"hours": "Stundas",
|
||||||
|
"minutes": "Minūtes",
|
||||||
|
"seconds": "Sekundes",
|
||||||
|
"unit": "Laika vienība"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Uploaden",
|
"upload": "Uploaden",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Bestand downloaden",
|
"downloadFile": "Bestand downloaden",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sorteren op laatst bewerkt",
|
"sortByLastModified": "Sorteren op laatst bewerkt",
|
||||||
"sortByName": "Sorteren op naam",
|
"sortByName": "Sorteren op naam",
|
||||||
"sortBySize": "Sorteren op grootte",
|
"sortBySize": "Sorteren op grootte",
|
||||||
"noPreview": "Preview is not available for this file."
|
"noPreview": "Preview is not available for this file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "selecteer bestand of map",
|
"click": "selecteer bestand of map",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Gebruikersnaam",
|
"username": "Gebruikersnaam",
|
||||||
"usernameTaken": "Gebruikersnaam reeds in gebruik",
|
"usernameTaken": "Gebruikersnaam reeds in gebruik",
|
||||||
"wrongCredentials": "Verkeerde inloggegevens",
|
"wrongCredentials": "Verkeerde inloggegevens",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Nieuwe bestanden of mappen aanmaken",
|
"allowNew": "Nieuwe bestanden of mappen aanmaken",
|
||||||
"allowPublish": "Publiceer nieuwe berichten en pagina's",
|
"allowPublish": "Publiceer nieuwe berichten en pagina's",
|
||||||
"allowSignup": "Sta gebruikers toe om zich te registreren",
|
"allowSignup": "Sta gebruikers toe om zich te registreren",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(laat leeg om wijzigingen te voorkomen)",
|
"avoidChanges": "(laat leeg om wijzigingen te voorkomen)",
|
||||||
"branding": "Branding",
|
"branding": "Branding",
|
||||||
"brandingDirectoryPath": "Branding directory path",
|
"brandingDirectoryPath": "Branding directory path",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permissies",
|
"permissions": "Permissies",
|
||||||
"permissionsHelp": "U kunt de gebruiker instellen als beheerder of de machtigingen afzonderlijk kiezen. Als u \"Beheerder\" selecteert, worden alle andere opties automatisch gecontroleerd. Het beheer van gebruikers blijft een privilege van een beheerder.\n",
|
"permissionsHelp": "U kunt de gebruiker instellen als beheerder of de machtigingen afzonderlijk kiezen. Als u \"Beheerder\" selecteert, worden alle andere opties automatisch gecontroleerd. Het beheer van gebruikers blijft een privilege van een beheerder.\n",
|
||||||
"profileSettings": "Profielinstellingen",
|
"profileSettings": "Profielinstellingen",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "voorkomt de toegang tot elk puntbestand (zoals .git, .gitignore) in elke map.\n",
|
"ruleExample1": "voorkomt de toegang tot elk puntbestand (zoals .git, .gitignore) in elke map.\n",
|
||||||
"ruleExample2": "blokkeert de toegang tot het bestand met de naam Caddyfile in de hoofdmap van het bereik.",
|
"ruleExample2": "blokkeert de toegang tot het bestand met de naam Caddyfile in de hoofdmap van het bereik.",
|
||||||
"rules": "Regels",
|
"rules": "Regels",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gebruikersbeheer",
|
"userManagement": "Gebruikersbeheer",
|
||||||
"userUpdated": "Gebruiker bijgewerkt!",
|
"userUpdated": "Gebruiker bijgewerkt!",
|
||||||
"username": "Gebruikersnaam",
|
"username": "Gebruikersnaam",
|
||||||
"users": "Gebruikers"
|
"users": "Gebruikers",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Help",
|
"help": "Help",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Last opp",
|
"upload": "Last opp",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Slett",
|
"discardChanges": "Slett",
|
||||||
"saveChanges": "Lagre Endringane "
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Lagre Endringane ",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Nedlast filen",
|
"downloadFile": "Nedlast filen",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sorter etter sist endret",
|
"sortByLastModified": "Sorter etter sist endret",
|
||||||
"sortByName": "Sorter etter navn",
|
"sortByName": "Sorter etter navn",
|
||||||
"sortBySize": "Sorter etter størrelse",
|
"sortBySize": "Sorter etter størrelse",
|
||||||
"noPreview": "Forhåndsvisning er ikkje tilgjengeleg for denne filen."
|
"noPreview": "Forhåndsvisning er ikkje tilgjengeleg for denne filen.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "velg fil eller katalog",
|
"click": "velg fil eller katalog",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Brukernavn",
|
"username": "Brukernavn",
|
||||||
"usernameTaken": "Brukernavn er allerede i bruk",
|
"usernameTaken": "Brukernavn er allerede i bruk",
|
||||||
"wrongCredentials": "Feil legitimasjon",
|
"wrongCredentials": "Feil legitimasjon",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "Du har blitt logget ut på grunn av inaktivitet"
|
"inactivity": "Du har blitt logget ut på grunn av inaktivitet"
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Opprett nye filer og direktorater",
|
"allowNew": "Opprett nye filer og direktorater",
|
||||||
"allowPublish": "Publiser nye innlegg og sider",
|
"allowPublish": "Publiser nye innlegg og sider",
|
||||||
"allowSignup": "Tilat brukere å registrere seg",
|
"allowSignup": "Tilat brukere å registrere seg",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(la stå tomt for å unngå endringer)",
|
"avoidChanges": "(la stå tomt for å unngå endringer)",
|
||||||
"branding": "Merkevarebygging",
|
"branding": "Merkevarebygging",
|
||||||
"brandingDirectoryPath": "Bane for merkevarekatalog",
|
"brandingDirectoryPath": "Bane for merkevarekatalog",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Tilaterser",
|
"permissions": "Tilaterser",
|
||||||
"permissionsHelp": "Du kan angi brukeren som administrator eller velge tillatelsene individuelt. Hvis du velger «Administrator», vil alle de andre alternativene bli automatisk avkrysset. Administrasjon av brukere er fortsatt et privilegium for en administrator.\n",
|
"permissionsHelp": "Du kan angi brukeren som administrator eller velge tillatelsene individuelt. Hvis du velger «Administrator», vil alle de andre alternativene bli automatisk avkrysset. Administrasjon av brukere er fortsatt et privilegium for en administrator.\n",
|
||||||
"profileSettings": "Profil Innstilinger",
|
"profileSettings": "Profil Innstilinger",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "forhindrer tilgang til noen dotfiler (som .git, .gitignore) i alle mapper.\n",
|
"ruleExample1": "forhindrer tilgang til noen dotfiler (som .git, .gitignore) i alle mapper.\n",
|
||||||
"ruleExample2": "blokkerer tilgangen til filen med navnet Caddyfile på roten av omfanget.",
|
"ruleExample2": "blokkerer tilgangen til filen med navnet Caddyfile på roten av omfanget.",
|
||||||
"rules": "Regler",
|
"rules": "Regler",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Brukeradministrasjon",
|
"userManagement": "Brukeradministrasjon",
|
||||||
"userUpdated": "Bruker opprettet!",
|
"userUpdated": "Bruker opprettet!",
|
||||||
"username": "Brukernavn",
|
"username": "Brukernavn",
|
||||||
"users": "Bruker"
|
"users": "Bruker",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Hjelp",
|
"help": "Hjelp",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Wyślij",
|
"upload": "Wyślij",
|
||||||
"openFile": "Otwórz plik",
|
"openFile": "Otwórz plik",
|
||||||
"discardChanges": "Odrzuć",
|
"discardChanges": "Odrzuć",
|
||||||
"saveChanges": "Zapisz zmiany"
|
"stopSearch": "Zatrzymaj wyszukiwanie",
|
||||||
|
"saveChanges": "Zapisz zmiany",
|
||||||
|
"editAsText": "Edytuj jako tekst",
|
||||||
|
"increaseFontSize": "Zwiększ rozmiar czcionki",
|
||||||
|
"decreaseFontSize": "Zmniejsz rozmiar czcionki"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Pobierz plik",
|
"downloadFile": "Pobierz plik",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sortuj wg ostatniej modyfikacji",
|
"sortByLastModified": "Sortuj wg ostatniej modyfikacji",
|
||||||
"sortByName": "Sortuj wg nazwy",
|
"sortByName": "Sortuj wg nazwy",
|
||||||
"sortBySize": "Sortuj wg rozmiaru",
|
"sortBySize": "Sortuj wg rozmiaru",
|
||||||
"noPreview": "Podgląd tego pliku jest niedostępny."
|
"noPreview": "Podgląd tego pliku jest niedostępny.",
|
||||||
|
"csvTooLarge": "Plik CSV jest za duży do podglądu (>5 MB). Pobierz, aby wyświetlić.",
|
||||||
|
"csvLoadFailed": "Nie udało się załadować pliku CSV.",
|
||||||
|
"showingRows": "Wyświetlanie wierszy: {count}",
|
||||||
|
"columnSeparator": "Separator kolumn",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Przecinek (,)",
|
||||||
|
"semicolon": "Średnik (;)",
|
||||||
|
"both": "Zarówno (,), jak i (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "zaznacz plik lub folder",
|
"click": "zaznacz plik lub folder",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Nazwa użytkownika",
|
"username": "Nazwa użytkownika",
|
||||||
"usernameTaken": "Ta nazwa użytkownika jest zajęta",
|
"usernameTaken": "Ta nazwa użytkownika jest zajęta",
|
||||||
"wrongCredentials": "Błędne dane logowania",
|
"wrongCredentials": "Błędne dane logowania",
|
||||||
|
"passwordTooShort": "Wymagana minimalna liczba znaków hasła: {min}",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "Wylogowano z powodu braku aktywności."
|
"inactivity": "Wylogowano z powodu braku aktywności."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Tworzenie nowych plików lub folderów",
|
"allowNew": "Tworzenie nowych plików lub folderów",
|
||||||
"allowPublish": "Tworzenie nowych wpisów i stron",
|
"allowPublish": "Tworzenie nowych wpisów i stron",
|
||||||
"allowSignup": "Pozwól użytkownikom na rejestrację",
|
"allowSignup": "Pozwól użytkownikom na rejestrację",
|
||||||
|
"hideLoginButton": "Ukryj przycisk logowania na stronach publicznych",
|
||||||
"avoidChanges": "(pozostaw puste, aby uniknąć zmian)",
|
"avoidChanges": "(pozostaw puste, aby uniknąć zmian)",
|
||||||
"branding": "Personalizacja",
|
"branding": "Personalizacja",
|
||||||
"brandingDirectoryPath": "Ścieżka do folderu personalizacji",
|
"brandingDirectoryPath": "Ścieżka do folderu personalizacji",
|
||||||
|
|
@ -216,7 +231,8 @@
|
||||||
},
|
},
|
||||||
"permissions": "Uprawnienia",
|
"permissions": "Uprawnienia",
|
||||||
"permissionsHelp": "Możesz ustawić użytkownika jako administratora lub wybrać uprawnienia indywidualnie. Jeśli wybierzesz „Administrator”, wszystkie pozostałe opcje zostaną automatycznie zaznaczone. Zarządzanie użytkownikami pozostaje przywilejem administratora.\n",
|
"permissionsHelp": "Możesz ustawić użytkownika jako administratora lub wybrać uprawnienia indywidualnie. Jeśli wybierzesz „Administrator”, wszystkie pozostałe opcje zostaną automatycznie zaznaczone. Zarządzanie użytkownikami pozostaje przywilejem administratora.\n",
|
||||||
"profileSettings": "Twój profil",
|
"profileSettings": "Ustawienia profilu",
|
||||||
|
"redirectAfterCopyMove": "Przekieruj do miejsca docelowego po skopiowaniu lub przeniesieniu",
|
||||||
"ruleExample1": "uniemożliwia dostęp do plików poprzedzonych kropką (takich jak .git, .gitignore) we wszystkich folderach.\n",
|
"ruleExample1": "uniemożliwia dostęp do plików poprzedzonych kropką (takich jak .git, .gitignore) we wszystkich folderach.\n",
|
||||||
"ruleExample2": "blokuje dostęp do pliku o nazwie Caddyfile w katalogu głównym zakresu.",
|
"ruleExample2": "blokuje dostęp do pliku o nazwie Caddyfile w katalogu głównym zakresu.",
|
||||||
"rules": "Uprawnienia",
|
"rules": "Uprawnienia",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Zarządzanie użytkownikami",
|
"userManagement": "Zarządzanie użytkownikami",
|
||||||
"userUpdated": "Użytkownik zapisany!",
|
"userUpdated": "Użytkownik zapisany!",
|
||||||
"username": "Nazwa użytkownika",
|
"username": "Nazwa użytkownika",
|
||||||
"users": "Użytkownicy"
|
"users": "Użytkownicy",
|
||||||
|
"currentPassword": "Twoje aktualne hasło"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Pomoc",
|
"help": "Pomoc",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Enviar",
|
"upload": "Enviar",
|
||||||
"openFile": "Abrir",
|
"openFile": "Abrir",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Baixar arquivo",
|
"downloadFile": "Baixar arquivo",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordenar pela última modificação",
|
"sortByLastModified": "Ordenar pela última modificação",
|
||||||
"sortByName": "Ordenar pelo nome",
|
"sortByName": "Ordenar pelo nome",
|
||||||
"sortBySize": "Ordenar pelo tamanho",
|
"sortBySize": "Ordenar pelo tamanho",
|
||||||
"noPreview": "Pré-visualização não disponível para este arquivo."
|
"noPreview": "Pré-visualização não disponível para este arquivo.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "selecionar pasta ou arquivo",
|
"click": "selecionar pasta ou arquivo",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Nome do usuário",
|
"username": "Nome do usuário",
|
||||||
"usernameTaken": "Nome de usuário já existe",
|
"usernameTaken": "Nome de usuário já existe",
|
||||||
"wrongCredentials": "Ops! Dados incorretos.",
|
"wrongCredentials": "Ops! Dados incorretos.",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Criar novos arquivos e pastas",
|
"allowNew": "Criar novos arquivos e pastas",
|
||||||
"allowPublish": "Publicar novas páginas e conteúdos",
|
"allowPublish": "Publicar novas páginas e conteúdos",
|
||||||
"allowSignup": "Permitir cadastro de usuários",
|
"allowSignup": "Permitir cadastro de usuários",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(deixe em branco para manter)",
|
"avoidChanges": "(deixe em branco para manter)",
|
||||||
"branding": "Customização",
|
"branding": "Customização",
|
||||||
"brandingDirectoryPath": "Diretório de customização",
|
"brandingDirectoryPath": "Diretório de customização",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permissões",
|
"permissions": "Permissões",
|
||||||
"permissionsHelp": "Pode definir o usuário como administrador ou escolher as permissões manualmente. Se selecionar a opção \"Administrador\", todas as outras opções serão automaticamente selecionadas. A gestão dos usuários é um privilégio restringido aos administradores.\n",
|
"permissionsHelp": "Pode definir o usuário como administrador ou escolher as permissões manualmente. Se selecionar a opção \"Administrador\", todas as outras opções serão automaticamente selecionadas. A gestão dos usuários é um privilégio restringido aos administradores.\n",
|
||||||
"profileSettings": "Configurações do usuário",
|
"profileSettings": "Configurações do usuário",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "previne o acesso a qualquer \"dotfile\" (como .git, .gitignore) em qualquer pasta\n",
|
"ruleExample1": "previne o acesso a qualquer \"dotfile\" (como .git, .gitignore) em qualquer pasta\n",
|
||||||
"ruleExample2": "bloqueia o acesso ao arquivo chamado Caddyfile.",
|
"ruleExample2": "bloqueia o acesso ao arquivo chamado Caddyfile.",
|
||||||
"rules": "Regras",
|
"rules": "Regras",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gerenciamento de usuários",
|
"userManagement": "Gerenciamento de usuários",
|
||||||
"userUpdated": "Usuário atualizado!",
|
"userUpdated": "Usuário atualizado!",
|
||||||
"username": "Nome do usuário",
|
"username": "Nome do usuário",
|
||||||
"users": "Usuários"
|
"users": "Usuários",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Ajuda",
|
"help": "Ajuda",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Enviar",
|
"upload": "Enviar",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Descarregar ficheiro",
|
"downloadFile": "Descarregar ficheiro",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordenar pela última alteração",
|
"sortByLastModified": "Ordenar pela última alteração",
|
||||||
"sortByName": "Ordenar pelo nome",
|
"sortByName": "Ordenar pelo nome",
|
||||||
"sortBySize": "Ordenar pelo tamanho",
|
"sortBySize": "Ordenar pelo tamanho",
|
||||||
"noPreview": "Preview is not available for this file."
|
"noPreview": "Preview is not available for this file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "selecionar pasta ou ficheiro",
|
"click": "selecionar pasta ou ficheiro",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Nome de utilizador",
|
"username": "Nome de utilizador",
|
||||||
"usernameTaken": "O nome de utilizador já está registado",
|
"usernameTaken": "O nome de utilizador já está registado",
|
||||||
"wrongCredentials": "Dados errados",
|
"wrongCredentials": "Dados errados",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Criar novos ficheiros e pastas",
|
"allowNew": "Criar novos ficheiros e pastas",
|
||||||
"allowPublish": "Publicar novas páginas e conteúdos",
|
"allowPublish": "Publicar novas páginas e conteúdos",
|
||||||
"allowSignup": "Permitir que os utilizadores criem contas",
|
"allowSignup": "Permitir que os utilizadores criem contas",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(deixe em branco para manter)",
|
"avoidChanges": "(deixe em branco para manter)",
|
||||||
"branding": "Marca",
|
"branding": "Marca",
|
||||||
"brandingDirectoryPath": "Caminho da pasta de marca",
|
"brandingDirectoryPath": "Caminho da pasta de marca",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permissões",
|
"permissions": "Permissões",
|
||||||
"permissionsHelp": "Pode definir o utilizador como administrador ou escolher as permissões manualmente. Se selecionar a opção \"Administrador\", todas as outras opções serão automaticamente selecionadas. A gestão dos utilizadores é um privilégio restringido aos administradores.\n",
|
"permissionsHelp": "Pode definir o utilizador como administrador ou escolher as permissões manualmente. Se selecionar a opção \"Administrador\", todas as outras opções serão automaticamente selecionadas. A gestão dos utilizadores é um privilégio restringido aos administradores.\n",
|
||||||
"profileSettings": "Configurações do utilizador",
|
"profileSettings": "Configurações do utilizador",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "previne o acesso a qualquer \"dotfile\" (como .git, .gitignore) em qualquer pasta\n",
|
"ruleExample1": "previne o acesso a qualquer \"dotfile\" (como .git, .gitignore) em qualquer pasta\n",
|
||||||
"ruleExample2": "bloqueia o acesso ao ficheiro chamado Caddyfile na raiz.",
|
"ruleExample2": "bloqueia o acesso ao ficheiro chamado Caddyfile na raiz.",
|
||||||
"rules": "Regras",
|
"rules": "Regras",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gestão de utilizadores",
|
"userManagement": "Gestão de utilizadores",
|
||||||
"userUpdated": "Utilizador atualizado!",
|
"userUpdated": "Utilizador atualizado!",
|
||||||
"username": "Nome de utilizador",
|
"username": "Nome de utilizador",
|
||||||
"users": "Utilizadores"
|
"users": "Utilizadores",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Ajuda",
|
"help": "Ajuda",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Încarcă",
|
"upload": "Încarcă",
|
||||||
"openFile": "Open file",
|
"openFile": "Open file",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Descarcă fișier",
|
"downloadFile": "Descarcă fișier",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Ordonează dup ultima modificare",
|
"sortByLastModified": "Ordonează dup ultima modificare",
|
||||||
"sortByName": "Ordonează după nume",
|
"sortByName": "Ordonează după nume",
|
||||||
"sortBySize": "Ordonează după dimensiune",
|
"sortBySize": "Ordonează după dimensiune",
|
||||||
"noPreview": "Preview is not available for this file."
|
"noPreview": "Preview is not available for this file.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "alege fișier sau director",
|
"click": "alege fișier sau director",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Utilizator",
|
"username": "Utilizator",
|
||||||
"usernameTaken": "Utilizatorul există",
|
"usernameTaken": "Utilizatorul există",
|
||||||
"wrongCredentials": "Informații greșite",
|
"wrongCredentials": "Informații greșite",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Crează noi fișiere sau directoare",
|
"allowNew": "Crează noi fișiere sau directoare",
|
||||||
"allowPublish": "Publică noi pagini și postări",
|
"allowPublish": "Publică noi pagini și postări",
|
||||||
"allowSignup": "Permite utilizatorilor să se înregistreze",
|
"allowSignup": "Permite utilizatorilor să se înregistreze",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(lasă gol pentru a nu schimba)",
|
"avoidChanges": "(lasă gol pentru a nu schimba)",
|
||||||
"branding": "Branding",
|
"branding": "Branding",
|
||||||
"brandingDirectoryPath": "Calea către directorul de branding",
|
"brandingDirectoryPath": "Calea către directorul de branding",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Permisiuni",
|
"permissions": "Permisiuni",
|
||||||
"permissionsHelp": "Poți alege ca un utilizator să fie administrator sau să-i alegi permisiunile individual. Dacă alegi \"Administrator\", toate celelalte opțiuni vor fi bifate automat. Gestionarea utilizatorilor rămâne un privilegiu exclusiv al administratorilor.\n",
|
"permissionsHelp": "Poți alege ca un utilizator să fie administrator sau să-i alegi permisiunile individual. Dacă alegi \"Administrator\", toate celelalte opțiuni vor fi bifate automat. Gestionarea utilizatorilor rămâne un privilegiu exclusiv al administratorilor.\n",
|
||||||
"profileSettings": "Setări profil",
|
"profileSettings": "Setări profil",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "împiedică accesul la fisiere cu punct in față (.), cum ar fi .git, .gitignore în orice director.\n",
|
"ruleExample1": "împiedică accesul la fisiere cu punct in față (.), cum ar fi .git, .gitignore în orice director.\n",
|
||||||
"ruleExample2": "împiedică accesul la fișierul Caddyfile din rădăcina domeniului.",
|
"ruleExample2": "împiedică accesul la fișierul Caddyfile din rădăcina domeniului.",
|
||||||
"rules": "Reguli",
|
"rules": "Reguli",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Gestionare utilizatori",
|
"userManagement": "Gestionare utilizatori",
|
||||||
"userUpdated": "Utilizator actualizat!",
|
"userUpdated": "Utilizator actualizat!",
|
||||||
"username": "Utilizator",
|
"username": "Utilizator",
|
||||||
"users": "Utilizatori"
|
"users": "Utilizatori",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Ajutor",
|
"help": "Ajutor",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Загрузить",
|
"upload": "Загрузить",
|
||||||
"openFile": "Открыть файл",
|
"openFile": "Открыть файл",
|
||||||
"discardChanges": "Отказаться",
|
"discardChanges": "Отказаться",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Сохранить",
|
||||||
|
"editAsText": "Редактировать как текст",
|
||||||
|
"increaseFontSize": "Увеличить размер шрифта",
|
||||||
|
"decreaseFontSize": "Уменьшить размер шрифта"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Скачать файл",
|
"downloadFile": "Скачать файл",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Сортировка по дате изменения",
|
"sortByLastModified": "Сортировка по дате изменения",
|
||||||
"sortByName": "Сортировка по имени",
|
"sortByName": "Сортировка по имени",
|
||||||
"sortBySize": "Сортировка по размеру",
|
"sortBySize": "Сортировка по размеру",
|
||||||
"noPreview": "Предварительный просмотр для этого файла недоступен."
|
"noPreview": "Предварительный просмотр для этого файла недоступен.",
|
||||||
|
"csvTooLarge": "Этот CSV файл слишком большой для предпросмотра (>5 МБ). Скачайте и откройте его локально.",
|
||||||
|
"csvLoadFailed": "Не удалось загрузить этот CSV.",
|
||||||
|
"showingRows": "Отображается {count} строк(а)",
|
||||||
|
"columnSeparator": "Разделитель столбцов",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Запятая (,)",
|
||||||
|
"semicolon": "Точка с запятой (;)",
|
||||||
|
"both": "Оба варианта — (,) и (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "выбрать файл или каталог",
|
"click": "выбрать файл или каталог",
|
||||||
|
|
@ -102,8 +115,9 @@
|
||||||
"username": "Имя пользователя",
|
"username": "Имя пользователя",
|
||||||
"usernameTaken": "Данное имя пользователя уже занято",
|
"usernameTaken": "Данное имя пользователя уже занято",
|
||||||
"wrongCredentials": "Неверные данные",
|
"wrongCredentials": "Неверные данные",
|
||||||
|
"passwordTooShort": "Пароль должен состоять как минимум из {min} символов",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "Сессия завершена после долгого отсутствия."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permanent": "Постоянный",
|
"permanent": "Постоянный",
|
||||||
|
|
@ -158,7 +172,7 @@
|
||||||
"video": "Видео"
|
"video": "Видео"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"aceEditorTheme": "Ace editor theme",
|
"aceEditorTheme": "Тема редактора Ace",
|
||||||
"admin": "Админ",
|
"admin": "Админ",
|
||||||
"administrator": "Администратор",
|
"administrator": "Администратор",
|
||||||
"allowCommands": "Запуск команд",
|
"allowCommands": "Запуск команд",
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Создание новых файлов или каталогов",
|
"allowNew": "Создание новых файлов или каталогов",
|
||||||
"allowPublish": "Публикация новых записей и страниц",
|
"allowPublish": "Публикация новых записей и страниц",
|
||||||
"allowSignup": "Разрешить пользователям регистрироваться",
|
"allowSignup": "Разрешить пользователям регистрироваться",
|
||||||
|
"hideLoginButton": "Спрятать кнопку входа с публичных страниц",
|
||||||
"avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)",
|
"avoidChanges": "(оставьте поле пустым, чтобы избежать изменений)",
|
||||||
"branding": "Брендинг",
|
"branding": "Брендинг",
|
||||||
"brandingDirectoryPath": "Путь к каталогу брендов",
|
"brandingDirectoryPath": "Путь к каталогу брендов",
|
||||||
|
|
@ -175,7 +190,7 @@
|
||||||
"commandRunnerHelp": "Здесь вы можете установить команды, которые будут выполняться в указанных событиях. Вы должны указать по одной команде в каждой строке. Переменные среды {0} и {1} будут доступны, будучи {0} относительно {1}. Дополнительные сведения об этой функции и доступных переменных среды см. В {2}.",
|
"commandRunnerHelp": "Здесь вы можете установить команды, которые будут выполняться в указанных событиях. Вы должны указать по одной команде в каждой строке. Переменные среды {0} и {1} будут доступны, будучи {0} относительно {1}. Дополнительные сведения об этой функции и доступных переменных среды см. В {2}.",
|
||||||
"commandsUpdated": "Команды обновлены!",
|
"commandsUpdated": "Команды обновлены!",
|
||||||
"createUserDir": "Автоматическое создание домашнего каталога пользователя при добавлении нового пользователя",
|
"createUserDir": "Автоматическое создание домашнего каталога пользователя при добавлении нового пользователя",
|
||||||
"minimumPasswordLength": "Minimum password length",
|
"minimumPasswordLength": "Минимальная длина пароля",
|
||||||
"tusUploads": "Загруженные файлы",
|
"tusUploads": "Загруженные файлы",
|
||||||
"tusUploadsHelp": " File Browser поддерживает загрузку файлов по частям, что позволяет работать в сетях низкого качества.",
|
"tusUploadsHelp": " File Browser поддерживает загрузку файлов по частям, что позволяет работать в сетях низкого качества.",
|
||||||
"tusUploadsChunkSize": "Указывает максимальный размер запроса (мелкие загрузки пойдут напрямую). Вы можете ввести простое целое число, обозначающее размер ввода в байтах, или строку, например 10MB, 1GB и т. д.",
|
"tusUploadsChunkSize": "Указывает максимальный размер запроса (мелкие загрузки пойдут напрямую). Вы можете ввести простое целое число, обозначающее размер ввода в байтах, или строку, например 10MB, 1GB и т. д.",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Права доступа",
|
"permissions": "Права доступа",
|
||||||
"permissionsHelp": "Можно настроить пользователя как администратора или выбрать разрешения индивидуально. При выборе \"Администратор\", все остальные параметры будут автоматически выбраны. Управление пользователями - привилегия администратора.\n",
|
"permissionsHelp": "Можно настроить пользователя как администратора или выбрать разрешения индивидуально. При выборе \"Администратор\", все остальные параметры будут автоматически выбраны. Управление пользователями - привилегия администратора.\n",
|
||||||
"profileSettings": "Настройки профиля",
|
"profileSettings": "Настройки профиля",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "предотвратить доступ к любому скрытому файлу (например: .git, .gitignore) в каждой папке.\n",
|
"ruleExample1": "предотвратить доступ к любому скрытому файлу (например: .git, .gitignore) в каждой папке.\n",
|
||||||
"ruleExample2": "блокирует доступ к файлу с именем Caddyfile в корневой области.",
|
"ruleExample2": "блокирует доступ к файлу с именем Caddyfile в корневой области.",
|
||||||
"rules": "Права",
|
"rules": "Права",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Управление пользователями",
|
"userManagement": "Управление пользователями",
|
||||||
"userUpdated": "Пользователь изменен!",
|
"userUpdated": "Пользователь изменен!",
|
||||||
"username": "Имя пользователя",
|
"username": "Имя пользователя",
|
||||||
"users": "Пользователи"
|
"users": "Пользователи",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Помощь",
|
"help": "Помощь",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Nahrať",
|
"upload": "Nahrať",
|
||||||
"openFile": "Otvoriť súbor",
|
"openFile": "Otvoriť súbor",
|
||||||
"discardChanges": "Zahodiť",
|
"discardChanges": "Zahodiť",
|
||||||
"saveChanges": "Uložiť zmeny"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Uložiť zmeny",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Stiahnuť súbor",
|
"downloadFile": "Stiahnuť súbor",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Zoradiť podľa dátumu",
|
"sortByLastModified": "Zoradiť podľa dátumu",
|
||||||
"sortByName": "Zoradiť podľa názvu",
|
"sortByName": "Zoradiť podľa názvu",
|
||||||
"sortBySize": "Zoradiť podľa veľkosti",
|
"sortBySize": "Zoradiť podľa veľkosti",
|
||||||
"noPreview": "Pre tento súbor nie je dostupný náhľad."
|
"noPreview": "Pre tento súbor nie je dostupný náhľad.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "vyberie súbor alebo priečinok",
|
"click": "vyberie súbor alebo priečinok",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Používateľské meno",
|
"username": "Používateľské meno",
|
||||||
"usernameTaken": "Meno je už obsadené",
|
"usernameTaken": "Meno je už obsadené",
|
||||||
"wrongCredentials": "Nesprávne prihlasovacie údaje",
|
"wrongCredentials": "Nesprávne prihlasovacie údaje",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "Boli ste odhlásení z dôvodu nečinnosti."
|
"inactivity": "Boli ste odhlásení z dôvodu nečinnosti."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Vytvárať nové súbory a priečinky",
|
"allowNew": "Vytvárať nové súbory a priečinky",
|
||||||
"allowPublish": "Zverejňovať nové príspevky a stránky",
|
"allowPublish": "Zverejňovať nové príspevky a stránky",
|
||||||
"allowSignup": "Povoliť registráciu používateľov",
|
"allowSignup": "Povoliť registráciu používateľov",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(nechajte prázdne, aby sa nezmenilo)",
|
"avoidChanges": "(nechajte prázdne, aby sa nezmenilo)",
|
||||||
"branding": "Vlastný vzhľad",
|
"branding": "Vlastný vzhľad",
|
||||||
"brandingDirectoryPath": "Cesta k priečinku s vlastným vzhľadom",
|
"brandingDirectoryPath": "Cesta k priečinku s vlastným vzhľadom",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Práva",
|
"permissions": "Práva",
|
||||||
"permissionsHelp": "Môžete nastaviť používateľa, aby bol administrátorom alebo vybrať práva jednotlivo. Ak zvolíte \"Administrator\", všetky ďalšie budú automaticky zaškrtnuté. Manažment používateľov ostáva v správe administrátora.\n",
|
"permissionsHelp": "Môžete nastaviť používateľa, aby bol administrátorom alebo vybrať práva jednotlivo. Ak zvolíte \"Administrator\", všetky ďalšie budú automaticky zaškrtnuté. Manažment používateľov ostáva v správe administrátora.\n",
|
||||||
"profileSettings": "Nastavenia profilu",
|
"profileSettings": "Nastavenia profilu",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "blokuje prístup ku všetkým súborom začínajúcim bodkou (napríklad .git, .gitignore) v každom priečinku.\n",
|
"ruleExample1": "blokuje prístup ku všetkým súborom začínajúcim bodkou (napríklad .git, .gitignore) v každom priečinku.\n",
|
||||||
"ruleExample2": "blokuje prístup k súborom s názvom Caddyfile v koreňovom priečinku.",
|
"ruleExample2": "blokuje prístup k súborom s názvom Caddyfile v koreňovom priečinku.",
|
||||||
"rules": "Pravidlá",
|
"rules": "Pravidlá",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Správa používateľov",
|
"userManagement": "Správa používateľov",
|
||||||
"userUpdated": "Používateľ upravený!",
|
"userUpdated": "Používateľ upravený!",
|
||||||
"username": "Meno používateľa",
|
"username": "Meno používateľa",
|
||||||
"users": "Používatelia"
|
"users": "Používatelia",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Pomoc",
|
"help": "Pomoc",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Ladda upp",
|
"upload": "Ladda upp",
|
||||||
"openFile": "Öppna fil",
|
"openFile": "Öppna fil",
|
||||||
"discardChanges": "Förkasta",
|
"discardChanges": "Förkasta",
|
||||||
"saveChanges": "Spara ändringar"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Spara ändringar",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Ladda ner fil",
|
"downloadFile": "Ladda ner fil",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sortera på senast ändrad",
|
"sortByLastModified": "Sortera på senast ändrad",
|
||||||
"sortByName": "Sortera på namn",
|
"sortByName": "Sortera på namn",
|
||||||
"sortBySize": "Sortera på storlek",
|
"sortBySize": "Sortera på storlek",
|
||||||
"noPreview": "Förhandsvisning är inte tillgänglig för denna fil."
|
"noPreview": "Förhandsvisning är inte tillgänglig för denna fil.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "välj fil eller mapp",
|
"click": "välj fil eller mapp",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Användarnamn",
|
"username": "Användarnamn",
|
||||||
"usernameTaken": "Användarnamn upptaget",
|
"usernameTaken": "Användarnamn upptaget",
|
||||||
"wrongCredentials": "Fel inloggning",
|
"wrongCredentials": "Fel inloggning",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "Du har blivit utloggad på grund av inaktivitet."
|
"inactivity": "Du har blivit utloggad på grund av inaktivitet."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Skapa nya filer eller mappar",
|
"allowNew": "Skapa nya filer eller mappar",
|
||||||
"allowPublish": "Publicera nya inlägg och sidor",
|
"allowPublish": "Publicera nya inlägg och sidor",
|
||||||
"allowSignup": "Tillåt användare att registrera sig",
|
"allowSignup": "Tillåt användare att registrera sig",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(lämna blankt för att undvika ändringar)",
|
"avoidChanges": "(lämna blankt för att undvika ändringar)",
|
||||||
"branding": "Varumärke",
|
"branding": "Varumärke",
|
||||||
"brandingDirectoryPath": "Sökväg till varumärkes katalog",
|
"brandingDirectoryPath": "Sökväg till varumärkes katalog",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Rättigheter",
|
"permissions": "Rättigheter",
|
||||||
"permissionsHelp": "Du kan ange att användaren ska vara administratör eller välja behörigheterna individuellt. Om du väljer \"administratör \" kommer alla andra alternativ att kontrolleras automatiskt. Hanteringen av användare är fortfarande ett privilegium för en administratör.\n",
|
"permissionsHelp": "Du kan ange att användaren ska vara administratör eller välja behörigheterna individuellt. Om du väljer \"administratör \" kommer alla andra alternativ att kontrolleras automatiskt. Hanteringen av användare är fortfarande ett privilegium för en administratör.\n",
|
||||||
"profileSettings": "Profil inställningar",
|
"profileSettings": "Profil inställningar",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "förhindrar åtkomst till en dot-fil (till exempel. git,. gitignore) i varje mapp.\n",
|
"ruleExample1": "förhindrar åtkomst till en dot-fil (till exempel. git,. gitignore) i varje mapp.\n",
|
||||||
"ruleExample2": "blockerar åtkomsten till filen som heter Caddyfilen i roten av scopet.",
|
"ruleExample2": "blockerar åtkomsten till filen som heter Caddyfilen i roten av scopet.",
|
||||||
"rules": "Regler",
|
"rules": "Regler",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Användarehantering",
|
"userManagement": "Användarehantering",
|
||||||
"userUpdated": "Användare uppdaterad!",
|
"userUpdated": "Användare uppdaterad!",
|
||||||
"username": "Användarnamn",
|
"username": "Användarnamn",
|
||||||
"users": "Användare"
|
"users": "Användare",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Hjälp",
|
"help": "Hjälp",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Yükle",
|
"upload": "Yükle",
|
||||||
"openFile": "Dosyayı aç",
|
"openFile": "Dosyayı aç",
|
||||||
"discardChanges": "Discard",
|
"discardChanges": "Discard",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Dosyayı indir",
|
"downloadFile": "Dosyayı indir",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Güncelleme tarihine göre sırala",
|
"sortByLastModified": "Güncelleme tarihine göre sırala",
|
||||||
"sortByName": "İsme göre sırala",
|
"sortByName": "İsme göre sırala",
|
||||||
"sortBySize": "Boyuta göre sırala",
|
"sortBySize": "Boyuta göre sırala",
|
||||||
"noPreview": "Bu dosya için önizleme aktif değil"
|
"noPreview": "Bu dosya için önizleme aktif değil",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "dosya veya klasör seçin",
|
"click": "dosya veya klasör seçin",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Kullanıcı adı",
|
"username": "Kullanıcı adı",
|
||||||
"usernameTaken": "Kullanıcı adı mevcut",
|
"usernameTaken": "Kullanıcı adı mevcut",
|
||||||
"wrongCredentials": "Yanlış hesap bilgileri",
|
"wrongCredentials": "Yanlış hesap bilgileri",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Yeni dosyalar ve dizinler oluşturun",
|
"allowNew": "Yeni dosyalar ve dizinler oluşturun",
|
||||||
"allowPublish": "Yeni linkler ve sayfaları yayınlayın",
|
"allowPublish": "Yeni linkler ve sayfaları yayınlayın",
|
||||||
"allowSignup": "Kullanıcıların kaydolmasına izin ver",
|
"allowSignup": "Kullanıcıların kaydolmasına izin ver",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(değişiklikleri önlemek için boş bırakın)",
|
"avoidChanges": "(değişiklikleri önlemek için boş bırakın)",
|
||||||
"branding": "Marka",
|
"branding": "Marka",
|
||||||
"brandingDirectoryPath": "Marka dizin yolu",
|
"brandingDirectoryPath": "Marka dizin yolu",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "İzinler",
|
"permissions": "İzinler",
|
||||||
"permissionsHelp": "Kullanıcıyı yönetici olarak ayarlayabilir veya izinleri ayrı ayrı seçebilirsiniz. \"Yönetici\"yi seçerseniz, diğer tüm seçenekler otomatik olarak kontrol edilecektir. Kullanıcıların yönetimi, bir yöneticinin yetkisi olarak kalır.\n",
|
"permissionsHelp": "Kullanıcıyı yönetici olarak ayarlayabilir veya izinleri ayrı ayrı seçebilirsiniz. \"Yönetici\"yi seçerseniz, diğer tüm seçenekler otomatik olarak kontrol edilecektir. Kullanıcıların yönetimi, bir yöneticinin yetkisi olarak kalır.\n",
|
||||||
"profileSettings": "Profil ayarları",
|
"profileSettings": "Profil ayarları",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "her klasördeki herhangi bir noktalı dosyaya (.git, .gitignore gibi) erişimi engeller.\n",
|
"ruleExample1": "her klasördeki herhangi bir noktalı dosyaya (.git, .gitignore gibi) erişimi engeller.\n",
|
||||||
"ruleExample2": "Root erişimidenki CaddyFile dosyalarına erişimi engelle.",
|
"ruleExample2": "Root erişimidenki CaddyFile dosyalarına erişimi engelle.",
|
||||||
"rules": "Kurallar",
|
"rules": "Kurallar",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Kullanıcı yönetimi",
|
"userManagement": "Kullanıcı yönetimi",
|
||||||
"userUpdated": "Kullanıcı güncellendi!",
|
"userUpdated": "Kullanıcı güncellendi!",
|
||||||
"username": "Kullanıcı adı",
|
"username": "Kullanıcı adı",
|
||||||
"users": "Kullanıcılar"
|
"users": "Kullanıcılar",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Yardım",
|
"help": "Yardım",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Вивантажити",
|
"upload": "Вивантажити",
|
||||||
"openFile": "Відкрити файл",
|
"openFile": "Відкрити файл",
|
||||||
"discardChanges": "Скасувати",
|
"discardChanges": "Скасувати",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Завантажити файл",
|
"downloadFile": "Завантажити файл",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Сортувати за останнім зміненням",
|
"sortByLastModified": "Сортувати за останнім зміненням",
|
||||||
"sortByName": "Сортувати за іменем",
|
"sortByName": "Сортувати за іменем",
|
||||||
"sortBySize": "Сортувати за розміром",
|
"sortBySize": "Сортувати за розміром",
|
||||||
"noPreview": "Попередній перегляд для цього файлу недоступний."
|
"noPreview": "Попередній перегляд для цього файлу недоступний.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "вибрати файл чи каталог",
|
"click": "вибрати файл чи каталог",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Ім'я користувача",
|
"username": "Ім'я користувача",
|
||||||
"usernameTaken": "Ім'я користувача вже використовується",
|
"usernameTaken": "Ім'я користувача вже використовується",
|
||||||
"wrongCredentials": "Неправильне ім'я користувача або пароль",
|
"wrongCredentials": "Неправильне ім'я користувача або пароль",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Створення нових файлів або каталогів",
|
"allowNew": "Створення нових файлів або каталогів",
|
||||||
"allowPublish": "Публікація нових записів та сторінок",
|
"allowPublish": "Публікація нових записів та сторінок",
|
||||||
"allowSignup": "Дозволити користувачам реєструватися",
|
"allowSignup": "Дозволити користувачам реєструватися",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(залишіть поле порожнім, щоб уникнути змін)",
|
"avoidChanges": "(залишіть поле порожнім, щоб уникнути змін)",
|
||||||
"branding": "Брендинг",
|
"branding": "Брендинг",
|
||||||
"brandingDirectoryPath": "Шлях до каталогу брендів",
|
"brandingDirectoryPath": "Шлях до каталогу брендів",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Дозволи",
|
"permissions": "Дозволи",
|
||||||
"permissionsHelp": "Можна налаштувати користувача як адміністратора чи вибрати індивідуальні дозволи. При виборі \"Адміністратор\" всі інші параметри будуть автоматично вибрані. Керування користувачами - привілей адміністратора.\n",
|
"permissionsHelp": "Можна налаштувати користувача як адміністратора чи вибрати індивідуальні дозволи. При виборі \"Адміністратор\" всі інші параметри будуть автоматично вибрані. Керування користувачами - привілей адміністратора.\n",
|
||||||
"profileSettings": "Налаштування профілю",
|
"profileSettings": "Налаштування профілю",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "запобігти доступу до будь-якого прихованого файлу (наприклад: .git, .gitignore) у кожній папці.\n",
|
"ruleExample1": "запобігти доступу до будь-якого прихованого файлу (наприклад: .git, .gitignore) у кожній папці.\n",
|
||||||
"ruleExample2": "блокує доступ до файлу з ім'ям Caddyfile у кореневій області.",
|
"ruleExample2": "блокує доступ до файлу з ім'ям Caddyfile у кореневій області.",
|
||||||
"rules": "Права",
|
"rules": "Права",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Керування користувачами",
|
"userManagement": "Керування користувачами",
|
||||||
"userUpdated": "Користувача змінено!",
|
"userUpdated": "Користувача змінено!",
|
||||||
"username": "Ім'я користувача",
|
"username": "Ім'я користувача",
|
||||||
"users": "Користувачі"
|
"users": "Користувачі",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Допомога",
|
"help": "Допомога",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "Tải lên",
|
"upload": "Tải lên",
|
||||||
"openFile": "Mở tệp",
|
"openFile": "Mở tệp",
|
||||||
"discardChanges": "Hủy bỏ thay đổi",
|
"discardChanges": "Hủy bỏ thay đổi",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "Tải xuống tệp tin",
|
"downloadFile": "Tải xuống tệp tin",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "Sắp xếp theo ngày sửa đổi",
|
"sortByLastModified": "Sắp xếp theo ngày sửa đổi",
|
||||||
"sortByName": "Sắp xếp theo tên",
|
"sortByName": "Sắp xếp theo tên",
|
||||||
"sortBySize": "Sắp xếp theo kích thước",
|
"sortBySize": "Sắp xếp theo kích thước",
|
||||||
"noPreview": "Không có bản xem trước cho tập tin này."
|
"noPreview": "Không có bản xem trước cho tập tin này.",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "chọn tập tin hoặc thư mục",
|
"click": "chọn tập tin hoặc thư mục",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "Tên người dùng",
|
"username": "Tên người dùng",
|
||||||
"usernameTaken": "Tên người dùng đã tồn tại",
|
"usernameTaken": "Tên người dùng đã tồn tại",
|
||||||
"wrongCredentials": "Thông tin đăng nhập không đúng",
|
"wrongCredentials": "Thông tin đăng nhập không đúng",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "Tạo tệp và thư mục mới",
|
"allowNew": "Tạo tệp và thư mục mới",
|
||||||
"allowPublish": "Xuất bản bài viết và trang mới",
|
"allowPublish": "Xuất bản bài viết và trang mới",
|
||||||
"allowSignup": "Cho phép người dùng đăng ký",
|
"allowSignup": "Cho phép người dùng đăng ký",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(để trống để tránh thay đổi)",
|
"avoidChanges": "(để trống để tránh thay đổi)",
|
||||||
"branding": "Thương hiệu",
|
"branding": "Thương hiệu",
|
||||||
"brandingDirectoryPath": "Đường dẫn thư mục thương hiệu",
|
"brandingDirectoryPath": "Đường dẫn thư mục thương hiệu",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "Quyền",
|
"permissions": "Quyền",
|
||||||
"permissionsHelp": "Bạn có thể đặt người dùng làm quản trị viên hoặc chọn quyền riêng lẻ. Nếu chọn \"Người quản trị\", tất cả các tùy chọn khác sẽ tự động được chọn. Việc quản lý người dùng vẫn là đặc quyền của quản trị viên.\n",
|
"permissionsHelp": "Bạn có thể đặt người dùng làm quản trị viên hoặc chọn quyền riêng lẻ. Nếu chọn \"Người quản trị\", tất cả các tùy chọn khác sẽ tự động được chọn. Việc quản lý người dùng vẫn là đặc quyền của quản trị viên.\n",
|
||||||
"profileSettings": "Cài đặt hồ sơ",
|
"profileSettings": "Cài đặt hồ sơ",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "ngăn truy cập vào bất kỳ tệp ẩn nào (chẳng hạn như .git, .gitignore) trong mọi thư mục.\n",
|
"ruleExample1": "ngăn truy cập vào bất kỳ tệp ẩn nào (chẳng hạn như .git, .gitignore) trong mọi thư mục.\n",
|
||||||
"ruleExample2": "chặn truy cập vào tệp có tên Caddyfile trong thư mục gốc của phạm vi.",
|
"ruleExample2": "chặn truy cập vào tệp có tên Caddyfile trong thư mục gốc của phạm vi.",
|
||||||
"rules": "Quy tắc",
|
"rules": "Quy tắc",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "Quản lý người dùng",
|
"userManagement": "Quản lý người dùng",
|
||||||
"userUpdated": "Người dùng đã được cập nhật!",
|
"userUpdated": "Người dùng đã được cập nhật!",
|
||||||
"username": "Tên người dùng",
|
"username": "Tên người dùng",
|
||||||
"users": "Người dùng"
|
"users": "Người dùng",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "Trợ giúp",
|
"help": "Trợ giúp",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "上传",
|
"upload": "上传",
|
||||||
"openFile": "打开文件",
|
"openFile": "打开文件",
|
||||||
"discardChanges": "放弃更改",
|
"discardChanges": "放弃更改",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "停止搜索",
|
||||||
|
"saveChanges": "保存更改",
|
||||||
|
"editAsText": "以文本形式编辑",
|
||||||
|
"increaseFontSize": "增大字体大小",
|
||||||
|
"decreaseFontSize": "减小字体大小"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "下载文件",
|
"downloadFile": "下载文件",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "按最后修改时间排序",
|
"sortByLastModified": "按最后修改时间排序",
|
||||||
"sortByName": "按名称排序",
|
"sortByName": "按名称排序",
|
||||||
"sortBySize": "按大小排序",
|
"sortBySize": "按大小排序",
|
||||||
"noPreview": "此文件无法预览。"
|
"noPreview": "此文件无法预览。",
|
||||||
|
"csvTooLarge": "CSV文件大到无法预览(>5MB)。请下载查看。",
|
||||||
|
"csvLoadFailed": "加载 CSV 文件失败。",
|
||||||
|
"showingRows": "正在显示 {count} 行",
|
||||||
|
"columnSeparator": "列分隔符",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "逗号 (,)",
|
||||||
|
"semicolon": "分号 (;)",
|
||||||
|
"both": "逗号 (,) 和分号 (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "选择文件或文件夹",
|
"click": "选择文件或文件夹",
|
||||||
|
|
@ -102,8 +115,9 @@
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"usernameTaken": "用户名已经被使用",
|
"usernameTaken": "用户名已经被使用",
|
||||||
"wrongCredentials": "用户名或密码错误",
|
"wrongCredentials": "用户名或密码错误",
|
||||||
|
"passwordTooShort": "密码必须至少包含 {min} 个字符",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "由于未活动,您已登出。"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"permanent": "永久",
|
"permanent": "永久",
|
||||||
|
|
@ -158,7 +172,7 @@
|
||||||
"video": "视频"
|
"video": "视频"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"aceEditorTheme": "Ace editor theme",
|
"aceEditorTheme": "Ace编辑器主题",
|
||||||
"admin": "管理员",
|
"admin": "管理员",
|
||||||
"administrator": "管理员",
|
"administrator": "管理员",
|
||||||
"allowCommands": "执行命令(Shell 命令)",
|
"allowCommands": "执行命令(Shell 命令)",
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "创建新文件和文件夹",
|
"allowNew": "创建新文件和文件夹",
|
||||||
"allowPublish": "发布新的帖子与页面",
|
"allowPublish": "发布新的帖子与页面",
|
||||||
"allowSignup": "允许用户注册",
|
"allowSignup": "允许用户注册",
|
||||||
|
"hideLoginButton": "从公开页面隐藏登录按钮",
|
||||||
"avoidChanges": "(留空以避免更改)",
|
"avoidChanges": "(留空以避免更改)",
|
||||||
"branding": "品牌",
|
"branding": "品牌",
|
||||||
"brandingDirectoryPath": "品牌信息文件夹路径",
|
"brandingDirectoryPath": "品牌信息文件夹路径",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "权限",
|
"permissions": "权限",
|
||||||
"permissionsHelp": "你可以将该用户设置为管理员或单独选择各项权限。如果你选择了“管理员”,则其他的选项会被自动选中,同时该用户可以管理其他用户。\n",
|
"permissionsHelp": "你可以将该用户设置为管理员或单独选择各项权限。如果你选择了“管理员”,则其他的选项会被自动选中,同时该用户可以管理其他用户。\n",
|
||||||
"profileSettings": "个人设置",
|
"profileSettings": "个人设置",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "阻止用户访问所有文件夹下任何以 . 开头的文件(隐藏文件, 例如: .git, .gitignore)。\n",
|
"ruleExample1": "阻止用户访问所有文件夹下任何以 . 开头的文件(隐藏文件, 例如: .git, .gitignore)。\n",
|
||||||
"ruleExample2": "阻止用户访问其目录范围的根目录下名为 Caddyfile 的文件。",
|
"ruleExample2": "阻止用户访问其目录范围的根目录下名为 Caddyfile 的文件。",
|
||||||
"rules": "规则",
|
"rules": "规则",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "用户管理",
|
"userManagement": "用户管理",
|
||||||
"userUpdated": "用户已更新!",
|
"userUpdated": "用户已更新!",
|
||||||
"username": "用户名",
|
"username": "用户名",
|
||||||
"users": "用户"
|
"users": "用户",
|
||||||
|
"currentPassword": "您当前的密码"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "帮助",
|
"help": "帮助",
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@
|
||||||
"upload": "上傳",
|
"upload": "上傳",
|
||||||
"openFile": "開啟檔案",
|
"openFile": "開啟檔案",
|
||||||
"discardChanges": "放棄變更",
|
"discardChanges": "放棄變更",
|
||||||
"saveChanges": "Save changes"
|
"stopSearch": "Stop searching",
|
||||||
|
"saveChanges": "Save changes",
|
||||||
|
"editAsText": "Edit as Text",
|
||||||
|
"increaseFontSize": "Increase font size",
|
||||||
|
"decreaseFontSize": "Decrease font size"
|
||||||
},
|
},
|
||||||
"download": {
|
"download": {
|
||||||
"downloadFile": "下載檔案",
|
"downloadFile": "下載檔案",
|
||||||
|
|
@ -75,7 +79,16 @@
|
||||||
"sortByLastModified": "按最後修改時間排序",
|
"sortByLastModified": "按最後修改時間排序",
|
||||||
"sortByName": "按名稱排序",
|
"sortByName": "按名稱排序",
|
||||||
"sortBySize": "按大小排序",
|
"sortBySize": "按大小排序",
|
||||||
"noPreview": "此檔案無法預覽。"
|
"noPreview": "此檔案無法預覽。",
|
||||||
|
"csvTooLarge": "CSV file is too large for preview (>5MB). Please download to view.",
|
||||||
|
"csvLoadFailed": "Failed to load CSV file.",
|
||||||
|
"showingRows": "Showing {count} row(s)",
|
||||||
|
"columnSeparator": "Column Separator",
|
||||||
|
"csvSeparators": {
|
||||||
|
"comma": "Comma (,)",
|
||||||
|
"semicolon": "Semicolon (;)",
|
||||||
|
"both": "Both (,) and (;)"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"help": {
|
"help": {
|
||||||
"click": "選擇檔案或目錄",
|
"click": "選擇檔案或目錄",
|
||||||
|
|
@ -102,6 +115,7 @@
|
||||||
"username": "帳號",
|
"username": "帳號",
|
||||||
"usernameTaken": "用戶名已存在",
|
"usernameTaken": "用戶名已存在",
|
||||||
"wrongCredentials": "帳號或密碼錯誤",
|
"wrongCredentials": "帳號或密碼錯誤",
|
||||||
|
"passwordTooShort": "Password must be at least {min} characters",
|
||||||
"logout_reasons": {
|
"logout_reasons": {
|
||||||
"inactivity": "You have been logged out due to inactivity."
|
"inactivity": "You have been logged out due to inactivity."
|
||||||
}
|
}
|
||||||
|
|
@ -166,6 +180,7 @@
|
||||||
"allowNew": "建立新檔案和目錄",
|
"allowNew": "建立新檔案和目錄",
|
||||||
"allowPublish": "發佈新的貼文與頁面",
|
"allowPublish": "發佈新的貼文與頁面",
|
||||||
"allowSignup": "允許使用者註冊",
|
"allowSignup": "允許使用者註冊",
|
||||||
|
"hideLoginButton": "Hide the login button from public pages",
|
||||||
"avoidChanges": "(留空以避免更改)",
|
"avoidChanges": "(留空以避免更改)",
|
||||||
"branding": "品牌",
|
"branding": "品牌",
|
||||||
"brandingDirectoryPath": "品牌資訊資料夾路徑",
|
"brandingDirectoryPath": "品牌資訊資料夾路徑",
|
||||||
|
|
@ -217,6 +232,7 @@
|
||||||
"permissions": "權限",
|
"permissions": "權限",
|
||||||
"permissionsHelp": "您可以將該使用者設置為管理員,也可以單獨選擇各項權限。如果選擇了“管理員”,則其他的選項會被自動勾上,同時該使用者可以管理其他使用者。",
|
"permissionsHelp": "您可以將該使用者設置為管理員,也可以單獨選擇各項權限。如果選擇了“管理員”,則其他的選項會被自動勾上,同時該使用者可以管理其他使用者。",
|
||||||
"profileSettings": "個人設定",
|
"profileSettings": "個人設定",
|
||||||
|
"redirectAfterCopyMove": "Redirect to destination after copy/move",
|
||||||
"ruleExample1": "封鎖使用者存取所有資料夾下任何以 . 開頭的檔案(隱藏文件, 例如: .git, .gitignore)。",
|
"ruleExample1": "封鎖使用者存取所有資料夾下任何以 . 開頭的檔案(隱藏文件, 例如: .git, .gitignore)。",
|
||||||
"ruleExample2": "封鎖使用者存取其目錄範圍的根目錄下名為 Caddyfile 的檔案。",
|
"ruleExample2": "封鎖使用者存取其目錄範圍的根目錄下名為 Caddyfile 的檔案。",
|
||||||
"rules": "規則",
|
"rules": "規則",
|
||||||
|
|
@ -243,7 +259,8 @@
|
||||||
"userManagement": "使用者管理",
|
"userManagement": "使用者管理",
|
||||||
"userUpdated": "使用者已更新!",
|
"userUpdated": "使用者已更新!",
|
||||||
"username": "使用者名稱",
|
"username": "使用者名稱",
|
||||||
"users": "使用者"
|
"users": "使用者",
|
||||||
|
"currentPassword": "Your Current Password"
|
||||||
},
|
},
|
||||||
"sidebar": {
|
"sidebar": {
|
||||||
"help": "幫助",
|
"help": "幫助",
|
||||||
|
|
|
||||||
3
frontend/src/types/settings.d.ts
vendored
3
frontend/src/types/settings.d.ts
vendored
|
|
@ -1,9 +1,11 @@
|
||||||
interface ISettings {
|
interface ISettings {
|
||||||
signup: boolean;
|
signup: boolean;
|
||||||
createUserDir: boolean;
|
createUserDir: boolean;
|
||||||
|
hideLoginButton: boolean;
|
||||||
minimumPasswordLength: number;
|
minimumPasswordLength: number;
|
||||||
userHomeBasePath: string;
|
userHomeBasePath: string;
|
||||||
defaults: SettingsDefaults;
|
defaults: SettingsDefaults;
|
||||||
|
authMethod: string;
|
||||||
rules: any[];
|
rules: any[];
|
||||||
branding: SettingsBranding;
|
branding: SettingsBranding;
|
||||||
tus: SettingsTus;
|
tus: SettingsTus;
|
||||||
|
|
@ -16,6 +18,7 @@ interface SettingsDefaults {
|
||||||
locale: string;
|
locale: string;
|
||||||
viewMode: ViewModeType;
|
viewMode: ViewModeType;
|
||||||
singleClick: boolean;
|
singleClick: boolean;
|
||||||
|
redirectAfterCopyMove: boolean;
|
||||||
sorting: Sorting;
|
sorting: Sorting;
|
||||||
perm: Permissions;
|
perm: Permissions;
|
||||||
commands: any[];
|
commands: any[];
|
||||||
|
|
|
||||||
2
frontend/src/types/user.d.ts
vendored
2
frontend/src/types/user.d.ts
vendored
|
|
@ -10,6 +10,7 @@ interface IUser {
|
||||||
lockPassword: boolean;
|
lockPassword: boolean;
|
||||||
hideDotfiles: boolean;
|
hideDotfiles: boolean;
|
||||||
singleClick: boolean;
|
singleClick: boolean;
|
||||||
|
redirectAfterCopyMove: boolean;
|
||||||
dateFormat: boolean;
|
dateFormat: boolean;
|
||||||
viewMode: ViewModeType;
|
viewMode: ViewModeType;
|
||||||
sorting?: Sorting;
|
sorting?: Sorting;
|
||||||
|
|
@ -30,6 +31,7 @@ interface IUserForm {
|
||||||
lockPassword?: boolean;
|
lockPassword?: boolean;
|
||||||
hideDotfiles?: boolean;
|
hideDotfiles?: boolean;
|
||||||
singleClick?: boolean;
|
singleClick?: boolean;
|
||||||
|
redirectAfterCopyMove?: boolean;
|
||||||
dateFormat?: boolean;
|
dateFormat?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue