Compare commits
134 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e1f658633d | ||
|
|
9c79105c02 | ||
|
|
6d5ceae8b4 | ||
|
|
381f09087a | ||
|
|
426b38bb33 | ||
|
|
488d98045e | ||
|
|
7955e0720b | ||
|
|
e017a19985 | ||
|
|
f8df76f526 | ||
|
|
11ebaec5f0 | ||
|
|
326b35a7ac | ||
|
|
5bf15548d0 | ||
|
|
6a734c0139 | ||
|
|
81b6f4d6f6 | ||
|
|
0b92d94570 | ||
|
|
fc5506179a | ||
|
|
0fe34ad224 | ||
|
|
54f35701a2 | ||
|
|
a809404ce1 | ||
|
|
fb32e44b47 | ||
|
|
e9c0369062 | ||
|
|
7358b3fe31 | ||
|
|
2a1f759e9e | ||
|
|
2fccb8c367 | ||
|
|
e039d95192 | ||
|
|
0f96031d6f | ||
|
|
6214fc84fa | ||
|
|
47578e02e3 | ||
|
|
35a4379b67 | ||
|
|
23f84642e6 | ||
|
|
edb9e85efd | ||
|
|
2d2c598fa6 | ||
|
|
cf4836dc75 | ||
|
|
d8306559fd | ||
|
|
e8c9d1c539 | ||
|
|
d8f415f8ab | ||
|
|
7b6579ac8a | ||
|
|
057307181e | ||
|
|
4fb832c042 | ||
|
|
e503cb69f2 | ||
|
|
95811e99bc | ||
|
|
62fff5ca60 | ||
|
|
5b28aa0848 | ||
|
|
db5aad8eb6 | ||
|
|
977ec33918 | ||
|
|
1819377897 | ||
|
|
f1b7bd59f6 | ||
|
|
f3afd5cb79 | ||
|
|
e6a5bf116e | ||
|
|
21b5a76fa7 | ||
|
|
b6263eb607 | ||
|
|
c8257e848e | ||
|
|
05bb7c8553 | ||
|
|
b600b11415 | ||
|
|
019ce80fc5 | ||
|
|
8cea2f75b3 | ||
|
|
6914063853 | ||
|
|
43e0d4a856 | ||
|
|
066d8e8d6c | ||
|
|
948e05c083 | ||
|
|
fb5b28d9cb | ||
|
|
677bce376b | ||
|
|
8faa96f5e6 | ||
|
|
f62806f6c9 | ||
|
|
58835b7e53 | ||
|
|
7a5298a755 | ||
|
|
bc4a6462ce | ||
|
|
ac3673e111 | ||
|
|
c746c1931d | ||
|
|
586d198d47 | ||
|
|
9515ceeb42 | ||
|
|
e8b4e9af46 | ||
|
|
10e399b3c3 | ||
|
|
dcbc3286e2 | ||
|
|
b185f9b56e | ||
|
|
7096b3dab9 | ||
|
|
36cacdf598 | ||
|
|
4e48ffc14d | ||
|
|
e119bc55ea | ||
|
|
1ce3068a99 | ||
|
|
d562d1a60d | ||
|
|
9f858398ab | ||
|
|
0ac80e8387 | ||
|
|
0dca0b92d1 | ||
|
|
c9b36ba32e | ||
|
|
f2c4e78381 | ||
|
|
05bff54b71 | ||
|
|
2bd163d92a | ||
|
|
5e27ba5c8c | ||
|
|
5aaeb3b76d | ||
|
|
36fb9f562a | ||
|
|
ad99bf1801 | ||
|
|
4c2a094255 | ||
|
|
97693cc611 | ||
|
|
c6d4fcd08f | ||
|
|
dd7b9ddd85 | ||
|
|
26d62e4117 | ||
|
|
babd7783af | ||
|
|
1529e796df | ||
|
|
d4b904b92b | ||
|
|
12d4177823 | ||
|
|
8142b32f38 | ||
|
|
c5abbb4e1c | ||
|
|
65ac73414f | ||
|
|
ede4213c8e | ||
|
|
b60d291490 | ||
|
|
b9ede79888 | ||
|
|
3d2cb838d1 | ||
|
|
778734419d | ||
|
|
be8683f556 | ||
|
|
c3450f4614 | ||
|
|
5881bc9ab0 | ||
|
|
a2fb499a20 | ||
|
|
411a928fea | ||
|
|
f5d02cdde9 | ||
|
|
c9340af8d0 | ||
|
|
a722bcc13f | ||
|
|
77fe3cfc60 | ||
|
|
470f93cefc | ||
|
|
92fde4dd12 | ||
|
|
95bc92955f | ||
|
|
f2f914221c | ||
|
|
c2d8038c63 | ||
|
|
cb8ac5ebf1 | ||
|
|
aa78e3ab1f | ||
|
|
bc00165094 | ||
|
|
94ef59602f | ||
|
|
14e2f84ceb | ||
|
|
f228fa5540 | ||
|
|
f2d2c1cbf8 | ||
|
|
d9be370e24 | ||
|
|
727c63b98e | ||
|
|
34dfb49b71 | ||
|
|
0b0a704d44 |
@@ -1,79 +0,0 @@
|
||||
version: 2
|
||||
jobs:
|
||||
lint:
|
||||
docker:
|
||||
- image: golangci/golangci-lint:v1.27.0
|
||||
steps:
|
||||
- checkout
|
||||
- run: golangci-lint run -v
|
||||
build-node:
|
||||
docker:
|
||||
- image: circleci/node
|
||||
steps:
|
||||
- checkout
|
||||
- run:
|
||||
name: "Build"
|
||||
command: ./wizard.sh -a
|
||||
- run:
|
||||
name: "Cleanup"
|
||||
command: rm -rf frontend/node_modules
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- '*'
|
||||
build-go:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.3
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: '~/project'
|
||||
- run:
|
||||
name: "Compile"
|
||||
command: GOOS=linux GOARCH=amd64 ./wizard.sh -c
|
||||
- run:
|
||||
name: "Cleanup"
|
||||
command: |
|
||||
rm -rf frontend/build
|
||||
git checkout -- go.sum # TODO: why is it being changed?
|
||||
- persist_to_workspace:
|
||||
root: .
|
||||
paths:
|
||||
- '*'
|
||||
release:
|
||||
docker:
|
||||
- image: circleci/golang:1.14.3
|
||||
steps:
|
||||
- attach_workspace:
|
||||
at: '~/project'
|
||||
- setup_remote_docker
|
||||
- run: docker login -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
|
||||
- run: curl -sL https://git.io/goreleaser | bash
|
||||
- run: docker logout
|
||||
workflows:
|
||||
version: 2
|
||||
build-workflow:
|
||||
jobs:
|
||||
- lint:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- build-node:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
- build-go:
|
||||
filters:
|
||||
tags:
|
||||
only: /.*/
|
||||
requires:
|
||||
- build-node
|
||||
- lint
|
||||
- release:
|
||||
context: deploy
|
||||
requires:
|
||||
- build-go
|
||||
filters:
|
||||
tags:
|
||||
only: /^v.*/
|
||||
branches:
|
||||
ignore: /.*/
|
||||
@@ -5,4 +5,4 @@
|
||||
"log": "stdout",
|
||||
"database": "/database.db",
|
||||
"root": "/srv"
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,2 @@
|
||||
testdata/
|
||||
.github/
|
||||
**.git
|
||||
*
|
||||
!filebrowser
|
||||
5
.github/CODEOWNERS
vendored
Normal file
5
.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
# These owners will be the default owners for everything in the repo.
|
||||
# Unless a later match takes precedence, @o1egl will be requested for
|
||||
# review when someone opens a pull request.
|
||||
|
||||
* @o1egl
|
||||
66
.github/workflows/main.yaml
vendored
Normal file
66
.github/workflows/main.yaml
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
name: main
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
tags:
|
||||
- 'v*'
|
||||
pull_request:
|
||||
|
||||
jobs:
|
||||
lint:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: npm i -g commitlint
|
||||
- run: make lint
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- run: make test
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
needs: [lint, test]
|
||||
if: startsWith(github.event.ref, 'refs/tags/v')
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-go@v2
|
||||
with:
|
||||
go-version: 1.16
|
||||
- uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: '14'
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Build fronetend
|
||||
run: make build-frontend
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v2
|
||||
with:
|
||||
version: latest
|
||||
args: release --rm-dist
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GH_PAT }}
|
||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -5,11 +5,9 @@ _old
|
||||
rice-box.go
|
||||
.idea/
|
||||
filebrowser
|
||||
dist/
|
||||
|
||||
.DS_Store
|
||||
node_modules
|
||||
/frontend/dist
|
||||
|
||||
# local env files
|
||||
.env.local
|
||||
@@ -28,3 +26,5 @@ yarn-error.log*
|
||||
*.njsproj
|
||||
*.sln
|
||||
*.sw*
|
||||
bin/
|
||||
build/
|
||||
|
||||
@@ -63,7 +63,6 @@ linters:
|
||||
- goconst
|
||||
- gocritic
|
||||
- gocyclo
|
||||
- gofmt
|
||||
- goimports
|
||||
- golint
|
||||
- gomnd
|
||||
|
||||
131
.goreleaser.yml
131
.goreleaser.yml
@@ -3,10 +3,6 @@ project_name: filebrowser
|
||||
env:
|
||||
- GO111MODULE=on
|
||||
|
||||
before:
|
||||
hooks:
|
||||
- go mod download
|
||||
|
||||
build:
|
||||
env:
|
||||
- CGO_ENABLED=0
|
||||
@@ -19,10 +15,6 @@ build:
|
||||
- linux
|
||||
- windows
|
||||
- freebsd
|
||||
- netbsd
|
||||
- openbsd
|
||||
- dragonfly
|
||||
- solaris
|
||||
goarch:
|
||||
- amd64
|
||||
- 386
|
||||
@@ -35,14 +27,8 @@ build:
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: 386
|
||||
- goos: openbsd
|
||||
goarch: arm
|
||||
- goos: freebsd
|
||||
goarch: arm
|
||||
- goos: netbsd
|
||||
goarch: arm
|
||||
- goos: solaris
|
||||
goarch: arm
|
||||
|
||||
archives:
|
||||
-
|
||||
@@ -55,53 +41,106 @@ archives:
|
||||
dockers:
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
binaries:
|
||||
- filebrowser
|
||||
use_buildx: true
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/amd64"
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
goarm: ''
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:latest"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
|
||||
extra_files:
|
||||
- .docker.json
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
binaries:
|
||||
- filebrowser
|
||||
use_buildx: true
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm64"
|
||||
goos: linux
|
||||
goarch: arm64
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
|
||||
extra_files:
|
||||
- .docker.json
|
||||
-
|
||||
dockerfile: Dockerfile
|
||||
use_buildx: true
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm/v6"
|
||||
goos: linux
|
||||
goarch: arm
|
||||
goarm: '5'
|
||||
goarm: '6'
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:pi"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-pi"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-pi"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv6"
|
||||
extra_files:
|
||||
- .docker.json
|
||||
-
|
||||
dockerfile: Dockerfile.alpine
|
||||
binaries:
|
||||
- filebrowser
|
||||
dockerfile: Dockerfile
|
||||
use_buildx: true
|
||||
build_flag_templates:
|
||||
- "--pull"
|
||||
- "--label=org.opencontainers.image.created={{.Date}}"
|
||||
- "--label=org.opencontainers.image.name={{.ProjectName}}"
|
||||
- "--label=org.opencontainers.image.revision={{.FullCommit}}"
|
||||
- "--label=org.opencontainers.image.version={{.Version}}"
|
||||
- "--label=org.opencontainers.image.source={{.GitURL}}"
|
||||
- "--platform=linux/arm/v7"
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
goarm: ''
|
||||
goarch: arm
|
||||
goarm: '7'
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:alpine"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-alpine"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-alpine"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
|
||||
extra_files:
|
||||
- .docker.json
|
||||
-
|
||||
dockerfile: Dockerfile.debian
|
||||
binaries:
|
||||
- filebrowser
|
||||
goos: linux
|
||||
goarch: amd64
|
||||
goarm: ''
|
||||
docker_manifests:
|
||||
- name_template: "filebrowser/filebrowser:latest"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:debian"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-debian"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-debian"
|
||||
extra_files:
|
||||
- .docker.json
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv6"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- name_template: "filebrowser/filebrowser:{{ .Tag }}"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-amd64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-arm64"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv6"
|
||||
- "filebrowser/filebrowser:{{ .Tag }}-armv7"
|
||||
- name_template: "filebrowser/filebrowser:v{{ .Major }}"
|
||||
image_templates:
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-amd64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-arm64"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv6"
|
||||
- "filebrowser/filebrowser:v{{ .Major }}-armv7"
|
||||
brews:
|
||||
- name: filebrowser
|
||||
tap:
|
||||
owner: filebrowser
|
||||
name: homebrew-tap
|
||||
folder: Formula
|
||||
homepage: https://filebrowser.org
|
||||
commit_author:
|
||||
name: FileBrowser Robot
|
||||
email: robot@filebrowser.org
|
||||
description: File Browser is a create-your-own-cloud-kind of software where you can install it on a server, direct it to a path and then access your files through a nice web interface
|
||||
license: "MIT"
|
||||
14
.versionrc
Normal file
14
.versionrc
Normal file
@@ -0,0 +1,14 @@
|
||||
{
|
||||
"types": [
|
||||
{ "type": "feat", "section": "Features" },
|
||||
{ "type": "fix", "section": "Bug Fixes" },
|
||||
{ "type": "perf", "section": "Performance improvements" },
|
||||
{ "type": "revert", "section": "Reverts" },
|
||||
{ "type": "refactor", "section": "Refactorings" },
|
||||
{ "type": "build", "section": "Build" },
|
||||
{ "type": "ci", "hidden": true },
|
||||
{ "type": "test", "hidden": true },
|
||||
{ "type": "chore", "hidden": true },
|
||||
{ "type": "docs", "hidden": true }
|
||||
]
|
||||
}
|
||||
170
CHANGELOG.md
170
CHANGELOG.md
@@ -2,6 +2,176 @@
|
||||
|
||||
All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
|
||||
|
||||
## [2.13.0](https://github.com/filebrowser/filebrowser/compare/v2.12.1...v2.13.0) (2021-03-14)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* dual pane settings view ([db5aad8](https://github.com/filebrowser/filebrowser/commit/db5aad8eb679cfe1b1ace5142cf342951217f0f7))
|
||||
* improved settings navbar ([5b28aa0](https://github.com/filebrowser/filebrowser/commit/5b28aa0848710b9d3ee02a2aa912856395f48bd2))
|
||||
* improved sharing prompt ([1819377](https://github.com/filebrowser/filebrowser/commit/18193778971e27d18b5a35df8c2d0e2953b48111))
|
||||
* increased header button counter size ([4fb832c](https://github.com/filebrowser/filebrowser/commit/4fb832c0422107e16f22b7aa928224f36de4978f))
|
||||
* larger previewer content ([62fff5c](https://github.com/filebrowser/filebrowser/commit/62fff5ca60da1f887c1f95fa4808d3753596dab2))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* archive contains parent path on Windows ([54f3570](https://github.com/filebrowser/filebrowser/commit/54f35701a2bd5cb7ec0628ca9789047072c073db))
|
||||
* check rules on http resource handlers ([5bf1554](https://github.com/filebrowser/filebrowser/commit/5bf15548d0ad147acfad5000277531be2671f7ce))
|
||||
* download current dir on file listing ([488d980](https://github.com/filebrowser/filebrowser/commit/488d98045e7476ed11e53c13d9498a9db3165bbc))
|
||||
* encoded file path on share ([7955e07](https://github.com/filebrowser/filebrowser/commit/7955e0720baef3710106c7e69bbbf078d5489220))
|
||||
* full file path on share ([e017a19](https://github.com/filebrowser/filebrowser/commit/e017a199850e19dd51b960ba59402c215fd8f1af))
|
||||
* header dropdown icon color on previewer ([f8df76f](https://github.com/filebrowser/filebrowser/commit/f8df76f52684f10722ce123fec2c90e321ddf103))
|
||||
* item dragging on file listing ([326b35a](https://github.com/filebrowser/filebrowser/commit/326b35a7ac7871afcdf892ca150349665b7f6379))
|
||||
* modified time on info prompt ([11ebaec](https://github.com/filebrowser/filebrowser/commit/11ebaec5f0671ec02ebe55d4a73a514bce3a6713))
|
||||
* root path name on archive ([426b38b](https://github.com/filebrowser/filebrowser/commit/426b38bb3362d2d477d0d8aa27d880664d537431))
|
||||
* stuck icon on header button ([6a734c0](https://github.com/filebrowser/filebrowser/commit/6a734c01391b437c2842f5d97fb63f29a0017510))
|
||||
* update image cache when replacing ([81b6f4d](https://github.com/filebrowser/filebrowser/commit/81b6f4d6f6a01886583016f61f4f1951a59f244d))
|
||||
* wait for async command exit ([#1326](https://github.com/filebrowser/filebrowser/issues/1326)) ([6d5ceae](https://github.com/filebrowser/filebrowser/commit/6d5ceae8b454edd749b3b65c88aacc0a31ce9215))
|
||||
|
||||
|
||||
### Refactorings
|
||||
|
||||
* migrate from rice to embed.FS ([fc55061](https://github.com/filebrowser/filebrowser/commit/fc5506179a64e9e2f57f7b6d6cce4b95f5ebc235))
|
||||
|
||||
### [2.12.1](https://github.com/filebrowser/filebrowser/compare/v2.12.0...v2.12.1) (2021-03-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* add missing default config into the docker image ([7358b3f](https://github.com/filebrowser/filebrowser/commit/7358b3fe3178c20007b4b5ef5c03705badd538c4))
|
||||
|
||||
## [2.12.0](https://github.com/filebrowser/filebrowser/compare/v2.11.0...v2.12.0) (2021-03-04)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add homebrew tap ([2d2c598](https://github.com/filebrowser/filebrowser/commit/2d2c598fa6bd1ecaf39c542182890c8dd9b1cad0))
|
||||
* added tiff files preview support ([#1222](https://github.com/filebrowser/filebrowser/issues/1222)) ([e8c9d1c](https://github.com/filebrowser/filebrowser/commit/e8c9d1c53989b4b52f6fba2a8ac41ae612c03a7c))
|
||||
* allow disabling file detections by reading header ([#1175](https://github.com/filebrowser/filebrowser/issues/1175)) ([6914063](https://github.com/filebrowser/filebrowser/commit/6914063853a8a3f3cecfa4b21f223820c2a0b7df))
|
||||
* allow to password protect shares ([#1252](https://github.com/filebrowser/filebrowser/issues/1252)) ([d8f415f](https://github.com/filebrowser/filebrowser/commit/d8f415f8abd0c4301803bd968c54429dd3fe4b59))
|
||||
* build multi-arch docker images ([cf4836d](https://github.com/filebrowser/filebrowser/commit/cf4836dc757ef79ad615179bb7a6c7bbd3b09c2c))
|
||||
* share management delete confirm ([#1212](https://github.com/filebrowser/filebrowser/issues/1212)) ([b600b11](https://github.com/filebrowser/filebrowser/commit/b600b11415fd1fb90ff2f5136be95a9c737ae1cb))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* don't allow to remove root user ([019ce80](https://github.com/filebrowser/filebrowser/commit/019ce80fc529a0437984fdc3d1ab6916f34dd594))
|
||||
* double click to zoom pics in phone's browser ([#1274](https://github.com/filebrowser/filebrowser/issues/1274)) ([f1b7bd5](https://github.com/filebrowser/filebrowser/commit/f1b7bd59f67e719b7bfd203b0d7ec016fd21ab49))
|
||||
* environmental variables not expanded in command ([#1241](https://github.com/filebrowser/filebrowser/issues/1241)) ([f3afd5c](https://github.com/filebrowser/filebrowser/commit/f3afd5cb79d6ad8b9cc8d54cb8fc2344b7c07d3d))
|
||||
* fetch resource api once when sorting (closes [#1172](https://github.com/filebrowser/filebrowser/issues/1172)) ([#1202](https://github.com/filebrowser/filebrowser/issues/1202)) ([05bb7c8](https://github.com/filebrowser/filebrowser/commit/05bb7c85531349f3e9d1d8a523bb1243587b2ebc))
|
||||
|
||||
|
||||
### Build
|
||||
|
||||
* use make for building the project ([#1304](https://github.com/filebrowser/filebrowser/issues/1304)) ([23f8464](https://github.com/filebrowser/filebrowser/commit/23f84642e6c1e07f89f98d2c1bb6fc9da36cc71c))
|
||||
|
||||
## [2.11.0](https://github.com/filebrowser/filebrowser/compare/v2.10.0...v2.11.0) (2020-12-28)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add sharing management ([#1178](https://github.com/filebrowser/filebrowser/issues/1178)) (closes [#1000](https://github.com/filebrowser/filebrowser/issues/1000)) ([677bce3](https://github.com/filebrowser/filebrowser/commit/677bce376b024d9ff38f34e74243034fe5a1ec3c))
|
||||
* download shared subdirectory ([#1184](https://github.com/filebrowser/filebrowser/issues/1184)) ([fb5b28d](https://github.com/filebrowser/filebrowser/commit/fb5b28d9cbdee10d38fcd719b9fd832121be58ef))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* check user input to prevent permission elevation ([#1196](https://github.com/filebrowser/filebrowser/issues/1196)) (closes [#1195](https://github.com/filebrowser/filebrowser/issues/1195)) ([f62806f](https://github.com/filebrowser/filebrowser/commit/f62806f6c9e9c7f392d1b747d65b8fe40b313e89))
|
||||
* delete extra remove prefix ([#1186](https://github.com/filebrowser/filebrowser/issues/1186)) ([7a5298a](https://github.com/filebrowser/filebrowser/commit/7a5298a7556f7dcc52f59b8ea76d040d3ddc3d12))
|
||||
* move files between different volumes (closes [#1177](https://github.com/filebrowser/filebrowser/issues/1177)) ([58835b7](https://github.com/filebrowser/filebrowser/commit/58835b7e535cc96e1c8a5d85821c1545743ca757))
|
||||
* recaptcha race condition ([#1176](https://github.com/filebrowser/filebrowser/issues/1176)) ([ac3673e](https://github.com/filebrowser/filebrowser/commit/ac3673e111afac6616af9650ca07028b6c27e6cd))
|
||||
|
||||
## [2.10.0](https://github.com/filebrowser/filebrowser/compare/v2.9.0...v2.10.0) (2020-11-24)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add hide dotfiles param ([#1148](https://github.com/filebrowser/filebrowser/issues/1148)) ([10e399b](https://github.com/filebrowser/filebrowser/commit/10e399b3c3dbdcfb4465a9d4138e1da6bae0873d))
|
||||
* add single click mode ([#1139](https://github.com/filebrowser/filebrowser/issues/1139)) ([e8b4e9a](https://github.com/filebrowser/filebrowser/commit/e8b4e9af46d6e99dbeb965dd9727d9ed017d52a2))
|
||||
* automatically jump to the next photo when deleting while previewing ([#1143](https://github.com/filebrowser/filebrowser/issues/1143)) ([9515cee](https://github.com/filebrowser/filebrowser/commit/9515ceeb42e5ef5267400220a2082dec775e843d))
|
||||
* shared folder file listing ([e119bc5](https://github.com/filebrowser/filebrowser/commit/e119bc55ea82cefcbcc0571650107dfd5d73f570))
|
||||
* shared item information ([36cacdf](https://github.com/filebrowser/filebrowser/commit/36cacdf598e4e09f064c8ace0ca7a6c24b23028e))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty folder in archive ([7096b3d](https://github.com/filebrowser/filebrowser/commit/7096b3dab92441981c9964e4a6175af0a255d2be))
|
||||
* fix hanging when reading a named pipe file (closes [#1155](https://github.com/filebrowser/filebrowser/issues/1155)) ([586d198](https://github.com/filebrowser/filebrowser/commit/586d198d47b525eeccc6fe587573a3ad83adb4f6))
|
||||
* previewer title overflow ([4e48ffc](https://github.com/filebrowser/filebrowser/commit/4e48ffc14d09dabeea12dc495144277db62b5b7d))
|
||||
* resource rename action invalid path ([1ce3068](https://github.com/filebrowser/filebrowser/commit/1ce3068a99c80c153fd41359255d173bce6e79e8))
|
||||
|
||||
## [2.9.0](https://github.com/filebrowser/filebrowser/compare/v2.8.0...v2.9.0) (2020-10-21)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* support WKWebview custom protocol ([#1113](https://github.com/filebrowser/filebrowser/issues/1113)) ([0ac80e8](https://github.com/filebrowser/filebrowser/commit/0ac80e8387a69924284259bde448af2813d84ed1))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* allow start from Windows explorer ([f2c4e78](https://github.com/filebrowser/filebrowser/commit/f2c4e78381610879eda5316d38a999c89df6c14a))
|
||||
* file upload missing path slash ([5e27ba5](https://github.com/filebrowser/filebrowser/commit/5e27ba5c8c1be603c6ae7fec8de48e3532dea1f7))
|
||||
* preview case sensitive file extension ([05bff54](https://github.com/filebrowser/filebrowser/commit/05bff54b71543fd232f1089c40504d0cbfd106be))
|
||||
* search missing path slash ([2bd163d](https://github.com/filebrowser/filebrowser/commit/2bd163d92a856d65c8d4615e37898470c1edf2f4))
|
||||
|
||||
## [2.8.0](https://github.com/filebrowser/filebrowser/compare/v2.7.0...v2.8.0) (2020-10-05)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add disable exec flag ([#1090](https://github.com/filebrowser/filebrowser/issues/1090)) ([97693cc](https://github.com/filebrowser/filebrowser/commit/97693cc6117ce1c956baede91de5dd48b904e175))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* empty commands setting ([c6d4fcd](https://github.com/filebrowser/filebrowser/commit/c6d4fcd08f5f1531c2cef514dc86019e23e7289f))
|
||||
* file upload path encoding ([babd778](https://github.com/filebrowser/filebrowser/commit/babd7783afe85b790e1c558375d7b5013b2d366f))
|
||||
* fix empty command name ([#1106](https://github.com/filebrowser/filebrowser/issues/1106)) ([36fb9f5](https://github.com/filebrowser/filebrowser/commit/36fb9f562a2c005ca4390fdebde0b4690201dff9))
|
||||
* fix panic when accessing nonexistent .js file in static path ([#1105](https://github.com/filebrowser/filebrowser/issues/1105)) ([ad99bf1](https://github.com/filebrowser/filebrowser/commit/ad99bf180197e0e6d82231a86457585de16366a8))
|
||||
* preview key shortcut conflict ([dd7b9dd](https://github.com/filebrowser/filebrowser/commit/dd7b9ddd8546361060ef99e838a691b2fc6c495a))
|
||||
* search results absolute url ([26d62e4](https://github.com/filebrowser/filebrowser/commit/26d62e411716a5eb9a5a703e47484cfb3fbf3bd0))
|
||||
|
||||
## [2.7.0](https://github.com/filebrowser/filebrowser/compare/v2.6.2...v2.7.0) (2020-09-11)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add --socket-perm flag to control unix socket file permissions (closes [#1060](https://github.com/filebrowser/filebrowser/issues/1060)) ([65ac734](https://github.com/filebrowser/filebrowser/commit/65ac73414fadc4686c94803a93ff319e8f7ce9d1))
|
||||
* preview mobile dropdown ([7787344](https://github.com/filebrowser/filebrowser/commit/778734419de314d4cb64d07109bbab73f8e2e42a))
|
||||
* preview size button ([3d2cb83](https://github.com/filebrowser/filebrowser/commit/3d2cb838d111ee61047599f49e76de80c821f341))
|
||||
* put selected files in the root of the archive (closes [#1065](https://github.com/filebrowser/filebrowser/issues/1065)) ([8142b32](https://github.com/filebrowser/filebrowser/commit/8142b32f3865eccd3331328e0d087f805d186ed5))
|
||||
|
||||
### [2.6.2](https://github.com/filebrowser/filebrowser/compare/v2.6.1...v2.6.2) (2020-08-05)
|
||||
|
||||
### [2.6.1](https://github.com/filebrowser/filebrowser/compare/v2.6.0...v2.6.1) (2020-07-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* delete cached previews when deleting file ([f5d02cd](https://github.com/filebrowser/filebrowser/commit/f5d02cdde97923b963878abf5a300393b9feb348))
|
||||
* escape special characters in preview url (closes [#1002](https://github.com/filebrowser/filebrowser/issues/1002)) ([c9340af](https://github.com/filebrowser/filebrowser/commit/c9340af8d045671ad3338c5d2d887c335ab92de4))
|
||||
|
||||
## [2.6.0](https://github.com/filebrowser/filebrowser/compare/v2.5.0...v2.6.0) (2020-07-27)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add lazy load of image thumbnails ([bc00165](https://github.com/filebrowser/filebrowser/commit/bc001650944ae963b12b5b2538a68de7cd0d8f82))
|
||||
* add param to disable img resizing ([aa78e3a](https://github.com/filebrowser/filebrowser/commit/aa78e3ab1fcae6f618e811ba4e315a7a209f9df2))
|
||||
* cache resized images ([95bc929](https://github.com/filebrowser/filebrowser/commit/95bc92955f391ece22c40d9592f2a3e6e26907b9))
|
||||
* limit image resize workers ([94ef596](https://github.com/filebrowser/filebrowser/commit/94ef59602fb50fc21b1164feda90a3b9aeb5e972))
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* conflict handling on upload button ([f228fa5](https://github.com/filebrowser/filebrowser/commit/f228fa55408824618e9f0879da67c86d22b0d324))
|
||||
* drop feedback ([f2d2c1c](https://github.com/filebrowser/filebrowser/commit/f2d2c1cbf85fba3edffb7b079f121ed3f0bc1e02))
|
||||
* missing error message ([d9be370](https://github.com/filebrowser/filebrowser/commit/d9be370e2474b8070fa58db920c9481270cc4a48))
|
||||
* parent verification on copy ([727c63b](https://github.com/filebrowser/filebrowser/commit/727c63b98e2964d0960d25914c296570f6c79478))
|
||||
* path separator inconsistency on rename ([34dfb49](https://github.com/filebrowser/filebrowser/commit/34dfb49b719c948e709a4639b4af2c5cb73b3887))
|
||||
|
||||
## [2.5.0](https://github.com/filebrowser/filebrowser/compare/v2.4.0...v2.5.0) (2020-07-17)
|
||||
|
||||
|
||||
|
||||
@@ -1,15 +1,11 @@
|
||||
FROM alpine:latest as alpine
|
||||
FROM alpine:latest
|
||||
RUN apk --update add ca-certificates
|
||||
RUN apk --update add mailcap
|
||||
|
||||
FROM scratch
|
||||
COPY --from=alpine /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
|
||||
COPY --from=alpine /etc/mime.types /etc/mime.types
|
||||
|
||||
VOLUME /srv
|
||||
EXPOSE 80
|
||||
|
||||
COPY .docker.json /.filebrowser.json
|
||||
COPY filebrowser /filebrowser
|
||||
|
||||
ENTRYPOINT [ "/filebrowser" ]
|
||||
ENTRYPOINT [ "/filebrowser" ]
|
||||
@@ -1,11 +0,0 @@
|
||||
FROM alpine:latest as alpine
|
||||
RUN apk --update add ca-certificates
|
||||
RUN apk --update add mailcap
|
||||
|
||||
VOLUME /srv
|
||||
EXPOSE 80
|
||||
|
||||
COPY .docker.json /.filebrowser.json
|
||||
COPY filebrowser /filebrowser
|
||||
|
||||
ENTRYPOINT [ "/filebrowser" ]
|
||||
@@ -1,9 +0,0 @@
|
||||
FROM debian:buster
|
||||
|
||||
VOLUME /srv
|
||||
EXPOSE 80
|
||||
|
||||
COPY .docker.json /.filebrowser.json
|
||||
COPY filebrowser /filebrowser
|
||||
|
||||
ENTRYPOINT [ "/filebrowser" ]
|
||||
94
Makefile
Normal file
94
Makefile
Normal file
@@ -0,0 +1,94 @@
|
||||
SHELL := /bin/bash
|
||||
BASE_PATH := $(shell dirname $(realpath $(lastword $(MAKEFILE_LIST))))
|
||||
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
|
||||
cat $(CURDIR)/.version 2> /dev/null || echo v0)
|
||||
VERSION_HASH = $(shell git rev-parse HEAD)
|
||||
|
||||
BIN = $(BASE_PATH)/bin
|
||||
PATH := $(BIN):$(PATH)
|
||||
export PATH
|
||||
|
||||
# printing
|
||||
V = 0
|
||||
Q = $(if $(filter 1,$V),,@)
|
||||
M = $(shell printf "\033[34;1m▶\033[0m")
|
||||
|
||||
GO = GOGC=off go
|
||||
# go module
|
||||
MODULE = $(shell env GO111MODULE=on $(GO) list -m)
|
||||
|
||||
DATE ?= $(shell date +%FT%T%z)
|
||||
VERSION ?= $(shell git describe --tags --always --match=v* 2> /dev/null || \
|
||||
cat $(CURDIR)/.version 2> /dev/null || echo v0)
|
||||
VERSION_HASH = $(shell git rev-parse HEAD)
|
||||
BRANCH = $(shell git rev-parse --abbrev-ref HEAD)
|
||||
|
||||
LDFLAGS += -X "$(MODULE)/varsion.Version=$(VERSION)" -X "$(MODULE)/varsion.CommitSHA=$(VERSION_HASH)"
|
||||
|
||||
# tools
|
||||
$(BIN):
|
||||
@mkdir -p $@
|
||||
$(BIN)/%: | $(BIN) ; $(info $(M) installing $(PACKAGE)…)
|
||||
$Q env GOBIN=$(BIN) $(GO) install $(PACKAGE)
|
||||
|
||||
GOLANGCI_LINT = $(BIN)/golangci-lint
|
||||
$(BIN)/golangci-lint: PACKAGE=github.com/golangci/golangci-lint/cmd/golangci-lint@v1.37.1
|
||||
|
||||
GOIMPORTS = $(BIN)/goimports
|
||||
$(BIN)/goimports: PACKAGE=golang.org/x/tools/cmd/goimports@v0.1.0
|
||||
|
||||
## build: Build
|
||||
.PHONY: build
|
||||
build: | build-frontend build-backend ; $(info $(M) building…)
|
||||
|
||||
## build-frontend: Build frontend
|
||||
.PHONY: build-frontend
|
||||
build-frontend: | ; $(info $(M) building frontend…)
|
||||
$Q cd frontend && npm ci && npm run build
|
||||
|
||||
## build-backend: Build backend
|
||||
.PHONY: build-backend
|
||||
build-backend: | ; $(info $(M) building backend…)
|
||||
$Q $(GO) build -ldflags '$(LDFLAGS)' -o filebrowser
|
||||
|
||||
## test: Run all tests
|
||||
.PHONY: test
|
||||
test: | test-frontend test-backend ; $(info $(M) running tests…)
|
||||
|
||||
## test-frontend: Run frontend tests
|
||||
.PHONY: test-frontend
|
||||
test-frontend: | ; $(info $(M) running frontend tests…)
|
||||
|
||||
## test-backend: Run backend tests
|
||||
.PHONY: test-backend
|
||||
test-backend: | $(RICE) ; $(info $(M) running backend tests…)
|
||||
$Q $(GO) test -v ./...
|
||||
|
||||
## lint: Lint
|
||||
.PHONY: lint
|
||||
lint: lint-frontend lint-backend lint-commits | ; $(info $(M) running all linters…)
|
||||
|
||||
## lint-frontend: Lint frontend
|
||||
.PHONY: lint-frontend
|
||||
lint-frontend: | ; $(info $(M) running frontend linters…)
|
||||
$Q cd frontend && npm ci && npm run lint
|
||||
|
||||
## lint-backend: Lint backend
|
||||
.PHONY: lint-backend
|
||||
lint-backend: | $(GOLANGCI_LINT) ; $(info $(M) running backend linters…)
|
||||
$Q $(GOLANGCI_LINT) run
|
||||
|
||||
## lint-commits: Lint commits
|
||||
.PHONY: lint-commits
|
||||
lint-commits: | ; $(info $(M) running commitlint…)
|
||||
$Q ./scripts/commitlint.sh
|
||||
|
||||
## bump-version: Bump app version
|
||||
.PHONY: bump-version
|
||||
bump-version: | ; $(info $(M) creating a new release…)
|
||||
$Q ./scripts/bump_version.sh
|
||||
|
||||
## help: Show this help
|
||||
.PHONY: help
|
||||
help:
|
||||
@sed -n 's/^## //p' $(MAKEFILE_LIST) | column -t -s ':' | sed -e 's/^/ /' | sort
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||

|
||||
|
||||
[](https://travis-ci.com/filebrowser/filebrowser)
|
||||
[](https://github.com/filebrowser/filebrowser/actions/workflows/main.yaml)
|
||||
[](https://goreportcard.com/report/github.com/filebrowser/filebrowser)
|
||||
[](http://godoc.org/github.com/filebrowser/filebrowser)
|
||||
[](https://github.com/filebrowser/filebrowser/releases/latest)
|
||||
@@ -24,7 +24,7 @@ For installation instructions please refer to our docs at [https://filebrowser.o
|
||||
|
||||
[Authentication Method](https://filebrowser.org/configuration/authentication-method) - You can change the way the user authenticates with the filebrowser server
|
||||
|
||||
[Commander Runner](https://filebrowser.org/configuration/command-runner) - The command runner is a feature that enables you to execute any shell command you want before or after a certain event.
|
||||
[Command Runner](https://filebrowser.org/configuration/command-runner) - The command runner is a feature that enables you to execute any shell command you want before or after a certain event.
|
||||
|
||||
[Custom Branding](https://filebrowser.org/configuration/custom-branding) - You can customize your File Browser installation by change its name to any other you want, by adding a global custom style sheet and by using your own logotype if you want.
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ import (
|
||||
// Auther is the authentication interface.
|
||||
type Auther interface {
|
||||
// Auth is called to authenticate a request.
|
||||
Auth(r *http.Request, s *users.Storage, root string) (*users.User, error)
|
||||
Auth(r *http.Request, s users.Store, root string) (*users.User, error)
|
||||
// LoginPage indicates if this auther needs a login page.
|
||||
LoginPage() bool
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ type JSONAuth struct {
|
||||
}
|
||||
|
||||
// Auth authenticates the user via a json in content body.
|
||||
func (a JSONAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
|
||||
func (a JSONAuth) Auth(r *http.Request, sto users.Store, root string) (*users.User, error) {
|
||||
var cred jsonCred
|
||||
|
||||
if r.Body == nil {
|
||||
@@ -40,7 +40,7 @@ func (a JSONAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users
|
||||
|
||||
// If ReCaptcha is enabled, check the code.
|
||||
if a.ReCaptcha != nil && len(a.ReCaptcha.Secret) > 0 {
|
||||
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:shadow
|
||||
ok, err := a.ReCaptcha.Ok(cred.ReCaptcha) //nolint:govet
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
||||
@@ -14,7 +14,7 @@ const MethodNoAuth settings.AuthMethod = "noauth"
|
||||
type NoAuth struct{}
|
||||
|
||||
// Auth uses authenticates user 1.
|
||||
func (a NoAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
|
||||
func (a NoAuth) Auth(r *http.Request, sto users.Store, root string) (*users.User, error) {
|
||||
return sto.Get(root, uint(1))
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ type ProxyAuth struct {
|
||||
}
|
||||
|
||||
// Auth authenticates the user via an HTTP header.
|
||||
func (a ProxyAuth) Auth(r *http.Request, sto *users.Storage, root string) (*users.User, error) {
|
||||
func (a ProxyAuth) Auth(r *http.Request, sto users.Store, root string) (*users.User, error) {
|
||||
username := r.Header.Get(a.Header)
|
||||
user, err := sto.Get(root, username)
|
||||
if err == errors.ErrNotExist {
|
||||
|
||||
@@ -14,7 +14,7 @@ var cmdsAddCmd = &cobra.Command{
|
||||
Use: "add <event> <command>",
|
||||
Short: "Add a command to run on a specific event",
|
||||
Long: `Add a command to run on a specific event.`,
|
||||
Args: cobra.MinimumNArgs(2), //nolint:mnd
|
||||
Args: cobra.MinimumNArgs(2), //nolint:gomnd
|
||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
||||
s, err := d.store.Settings.Get()
|
||||
checkErr(err)
|
||||
|
||||
@@ -23,7 +23,7 @@ You can also specify an optional parameter (index_end) so
|
||||
you can remove all commands from 'index' to 'index_end',
|
||||
including 'index_end'.`,
|
||||
Args: func(cmd *cobra.Command, args []string) error {
|
||||
if err := cobra.RangeArgs(2, 3)(cmd, args); err != nil { //nolint:mnd
|
||||
if err := cobra.RangeArgs(2, 3)(cmd, args); err != nil { //nolint:gomnd
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ including 'index_end'.`,
|
||||
i, err := strconv.Atoi(args[1])
|
||||
checkErr(err)
|
||||
f := i
|
||||
if len(args) == 3 { //nolint:mnd
|
||||
if len(args) == 3 { //nolint:gomnd
|
||||
f, err = strconv.Atoi(args[2])
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
@@ -140,10 +140,12 @@ func printSettings(ser *settings.Server, set *settings.Settings, auther auth.Aut
|
||||
fmt.Fprintf(w, "\tAddress:\t%s\n", ser.Address)
|
||||
fmt.Fprintf(w, "\tTLS Cert:\t%s\n", ser.TLSCert)
|
||||
fmt.Fprintf(w, "\tTLS Key:\t%s\n", ser.TLSKey)
|
||||
fmt.Fprintf(w, "\tExec Enabled:\t%t\n", ser.EnableExec)
|
||||
fmt.Fprintln(w, "\nDefaults:")
|
||||
fmt.Fprintf(w, "\tScope:\t%s\n", set.Defaults.Scope)
|
||||
fmt.Fprintf(w, "\tLocale:\t%s\n", set.Defaults.Locale)
|
||||
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, "\tCommands:\t%s\n", strings.Join(set.Defaults.Commands, " "))
|
||||
fmt.Fprintf(w, "\tSorting:\n")
|
||||
fmt.Fprintf(w, "\t\tBy:\t%s\n", set.Defaults.Sorting.By)
|
||||
|
||||
@@ -2,7 +2,6 @@ package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
|
||||
@@ -32,7 +31,7 @@ override the options.`,
|
||||
s := &settings.Settings{
|
||||
Key: generateKey(),
|
||||
Signup: mustGetBool(flags, "signup"),
|
||||
Shell: strings.Split(strings.TrimSpace(mustGetString(flags, "shell")), " "),
|
||||
Shell: convertCmdStrToCmdArray(mustGetString(flags, "shell")),
|
||||
AuthMethod: authMethod,
|
||||
Defaults: defaults,
|
||||
Branding: settings.Branding{
|
||||
@@ -62,7 +61,7 @@ override the options.`,
|
||||
|
||||
fmt.Printf(`
|
||||
Congratulations! You've set up your database to use with File Browser.
|
||||
Now add your first user via 'filebrowser users new' and then you just
|
||||
Now add your first user via 'filebrowser users add' and then you just
|
||||
need to call the main command to boot up the server.
|
||||
`)
|
||||
printSettings(ser, s, auther)
|
||||
|
||||
@@ -1,8 +1,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
)
|
||||
@@ -50,7 +48,7 @@ you want to change. Other options will remain unchanged.`,
|
||||
case "auth.method":
|
||||
hasAuth = true
|
||||
case "shell":
|
||||
set.Shell = strings.Split(strings.TrimSpace(mustGetString(flags, flag.Name)), " ")
|
||||
set.Shell = convertCmdStrToCmdArray(mustGetString(flags, flag.Name))
|
||||
case "branding.name":
|
||||
set.Branding.Name = mustGetString(flags, flag.Name)
|
||||
case "branding.disableExternal":
|
||||
|
||||
70
cmd/root.go
70
cmd/root.go
@@ -3,6 +3,7 @@ package cmd
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"io/fs"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net"
|
||||
@@ -14,13 +15,17 @@ import (
|
||||
"syscall"
|
||||
|
||||
homedir "github.com/mitchellh/go-homedir"
|
||||
"github.com/spf13/afero"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
v "github.com/spf13/viper"
|
||||
lumberjack "gopkg.in/natefinch/lumberjack.v2"
|
||||
|
||||
"github.com/filebrowser/filebrowser/v2/auth"
|
||||
"github.com/filebrowser/filebrowser/v2/diskcache"
|
||||
"github.com/filebrowser/filebrowser/v2/frontend"
|
||||
fbhttp "github.com/filebrowser/filebrowser/v2/http"
|
||||
"github.com/filebrowser/filebrowser/v2/img"
|
||||
"github.com/filebrowser/filebrowser/v2/settings"
|
||||
"github.com/filebrowser/filebrowser/v2/storage"
|
||||
"github.com/filebrowser/filebrowser/v2/users"
|
||||
@@ -32,6 +37,7 @@ var (
|
||||
|
||||
func init() {
|
||||
cobra.OnInitialize(initConfig)
|
||||
cobra.MousetrapHelpText = ""
|
||||
|
||||
rootCmd.SetVersionTemplate("File Browser version {{printf \"%s\" .Version}}\n")
|
||||
|
||||
@@ -55,7 +61,14 @@ func addServerFlags(flags *pflag.FlagSet) {
|
||||
flags.StringP("key", "k", "", "tls key")
|
||||
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.Uint32("socket-perm", 0666, "unix socket file permissions")
|
||||
flags.StringP("baseurl", "b", "", "base url")
|
||||
flags.String("cache-dir", "", "file cache directory (disabled if empty)")
|
||||
flags.Int("img-processors", 4, "image processors count")
|
||||
flags.Bool("disable-thumbnails", false, "disable image thumbnails")
|
||||
flags.Bool("disable-preview-resize", false, "disable resize of image previews")
|
||||
flags.Bool("disable-exec", false, "disables Command Runner feature")
|
||||
flags.Bool("disable-type-detection-by-header", false, "disables type detection by reading file headers")
|
||||
}
|
||||
|
||||
var rootCmd = &cobra.Command{
|
||||
@@ -103,6 +116,24 @@ user created with the credentials from options "username" and "password".`,
|
||||
quickSetup(cmd.Flags(), d)
|
||||
}
|
||||
|
||||
// build img service
|
||||
workersCount, err := cmd.Flags().GetInt("img-processors")
|
||||
checkErr(err)
|
||||
if workersCount < 1 {
|
||||
log.Fatal("Image resize workers count could not be < 1")
|
||||
}
|
||||
imgSvc := img.New(workersCount)
|
||||
|
||||
var fileCache diskcache.Interface = diskcache.NewNoOp()
|
||||
cacheDir, err := cmd.Flags().GetString("cache-dir")
|
||||
checkErr(err)
|
||||
if cacheDir != "" {
|
||||
if err := os.MkdirAll(cacheDir, 0700); err != nil { //nolint:govet
|
||||
log.Fatalf("can't make directory %s: %s", cacheDir, err)
|
||||
}
|
||||
fileCache = diskcache.New(afero.NewOsFs(), cacheDir)
|
||||
}
|
||||
|
||||
server := getRunParams(cmd.Flags(), d.store)
|
||||
setupLog(server.Log)
|
||||
|
||||
@@ -118,13 +149,20 @@ user created with the credentials from options "username" and "password".`,
|
||||
case server.Socket != "":
|
||||
listener, err = net.Listen("unix", server.Socket)
|
||||
checkErr(err)
|
||||
case server.TLSKey != "" && server.TLSCert != "":
|
||||
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:shadow
|
||||
socketPerm, err := cmd.Flags().GetUint32("socket-perm") //nolint:govet
|
||||
checkErr(err)
|
||||
listener, err = tls.Listen("tcp", adr, &tls.Config{Certificates: []tls.Certificate{cer}}) //nolint:shadow
|
||||
err = os.Chmod(server.Socket, os.FileMode(socketPerm))
|
||||
checkErr(err)
|
||||
case server.TLSKey != "" && server.TLSCert != "":
|
||||
cer, err := tls.LoadX509KeyPair(server.TLSCert, server.TLSKey) //nolint:govet
|
||||
checkErr(err)
|
||||
listener, err = tls.Listen("tcp", adr, &tls.Config{
|
||||
MinVersion: tls.VersionTLS12,
|
||||
Certificates: []tls.Certificate{cer}},
|
||||
)
|
||||
checkErr(err)
|
||||
default:
|
||||
listener, err = net.Listen("tcp", adr) //nolint:shadow
|
||||
listener, err = net.Listen("tcp", adr)
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
@@ -132,7 +170,12 @@ user created with the credentials from options "username" and "password".`,
|
||||
signal.Notify(sigc, os.Interrupt, syscall.SIGTERM)
|
||||
go cleanupHandler(listener, sigc)
|
||||
|
||||
handler, err := fbhttp.NewHandler(d.store, server)
|
||||
assetsFs, err := fs.Sub(frontend.Assets(), "dist")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
handler, err := fbhttp.NewHandler(imgSvc, fileCache, d.store, server, assetsFs)
|
||||
checkErr(err)
|
||||
|
||||
defer listener.Close()
|
||||
@@ -205,6 +248,18 @@ func getRunParams(flags *pflag.FlagSet, st *storage.Storage) *settings.Server {
|
||||
server.Socket = ""
|
||||
}
|
||||
|
||||
_, disableThumbnails := getParamB(flags, "disable-thumbnails")
|
||||
server.EnableThumbnails = !disableThumbnails
|
||||
|
||||
_, disablePreviewResize := getParamB(flags, "disable-preview-resize")
|
||||
server.ResizePreview = !disablePreviewResize
|
||||
|
||||
_, disableTypeDetectionByHeader := getParamB(flags, "disable-type-detection-by-header")
|
||||
server.TypeDetectionByHeader = !disableTypeDetectionByHeader
|
||||
|
||||
_, disableExec := getParamB(flags, "disable-exec")
|
||||
server.EnableExec = !disableExec
|
||||
|
||||
return server
|
||||
}
|
||||
|
||||
@@ -261,8 +316,9 @@ func quickSetup(flags *pflag.FlagSet, d pythonData) {
|
||||
Signup: false,
|
||||
CreateUserDir: false,
|
||||
Defaults: settings.UserDefaults{
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
Scope: ".",
|
||||
Locale: "en",
|
||||
SingleClick: false,
|
||||
Perm: users.Permissions{
|
||||
Admin: false,
|
||||
Execute: true,
|
||||
|
||||
@@ -44,7 +44,7 @@ including 'index_end'.`,
|
||||
i, err := strconv.Atoi(args[0])
|
||||
checkErr(err)
|
||||
f := i
|
||||
if len(args) == 2 { //nolint:mnd
|
||||
if len(args) == 2 { //nolint:gomnd
|
||||
f, err = strconv.Atoi(args[1])
|
||||
checkErr(err)
|
||||
}
|
||||
|
||||
@@ -27,15 +27,16 @@ var usersCmd = &cobra.Command{
|
||||
|
||||
func printUsers(usrs []*users.User) {
|
||||
w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0)
|
||||
fmt.Fprintln(w, "ID\tUsername\tScope\tLocale\tV. Mode\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 {
|
||||
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\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\n",
|
||||
u.ID,
|
||||
u.Username,
|
||||
u.Scope,
|
||||
u.Locale,
|
||||
u.ViewMode,
|
||||
u.SingleClick,
|
||||
u.Perm.Admin,
|
||||
u.Perm.Execute,
|
||||
u.Perm.Create,
|
||||
@@ -75,6 +76,7 @@ func addUserFlags(flags *pflag.FlagSet) {
|
||||
flags.String("scope", ".", "scope for users")
|
||||
flags.String("locale", "en", "locale for users")
|
||||
flags.String("viewMode", string(users.ListViewMode), "view mode for users")
|
||||
flags.Bool("singleClick", false, "use single clicks only")
|
||||
}
|
||||
|
||||
func getViewMode(flags *pflag.FlagSet) users.ViewMode {
|
||||
@@ -95,6 +97,8 @@ func getUserDefaults(flags *pflag.FlagSet, defaults *settings.UserDefaults, all
|
||||
defaults.Locale = mustGetString(flags, flag.Name)
|
||||
case "viewMode":
|
||||
defaults.ViewMode = getViewMode(flags)
|
||||
case "singleClick":
|
||||
defaults.SingleClick = mustGetBool(flags, flag.Name)
|
||||
case "perm.admin":
|
||||
defaults.Perm.Admin = mustGetBool(flags, flag.Name)
|
||||
case "perm.execute":
|
||||
|
||||
@@ -15,7 +15,7 @@ var usersAddCmd = &cobra.Command{
|
||||
Use: "add <username> <password>",
|
||||
Short: "Create a new user",
|
||||
Long: `Create a new user and add it to the database.`,
|
||||
Args: cobra.ExactArgs(2), //nolint:mnd
|
||||
Args: cobra.ExactArgs(2), //nolint:gomnd
|
||||
Run: python(func(cmd *cobra.Command, args []string, d pythonData) {
|
||||
s, err := d.store.Settings.Get()
|
||||
checkErr(err)
|
||||
|
||||
@@ -67,7 +67,7 @@ list or set it to 0.`,
|
||||
// with the new username. If there is, print an error and cancel the
|
||||
// operation
|
||||
if user.Username != onDB.Username {
|
||||
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:shadow
|
||||
if conflictuous, err := d.store.Users.Get("", user.Username); err == nil { //nolint:govet
|
||||
checkErr(usernameConflictError(user.Username, conflictuous.ID, user.ID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,17 +41,19 @@ options you want to change.`,
|
||||
checkErr(err)
|
||||
|
||||
defaults := settings.UserDefaults{
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
Scope: user.Scope,
|
||||
Locale: user.Locale,
|
||||
ViewMode: user.ViewMode,
|
||||
SingleClick: user.SingleClick,
|
||||
Perm: user.Perm,
|
||||
Sorting: user.Sorting,
|
||||
Commands: user.Commands,
|
||||
}
|
||||
getUserDefaults(flags, &defaults, false)
|
||||
user.Scope = defaults.Scope
|
||||
user.Locale = defaults.Locale
|
||||
user.ViewMode = defaults.ViewMode
|
||||
user.SingleClick = defaults.SingleClick
|
||||
user.Perm = defaults.Perm
|
||||
user.Commands = defaults.Commands
|
||||
user.Sorting = defaults.Sorting
|
||||
|
||||
15
cmd/utils.go
15
cmd/utils.go
@@ -7,6 +7,7 @@ import (
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"github.com/asdine/storm"
|
||||
"github.com/spf13/cobra"
|
||||
@@ -71,7 +72,7 @@ func dbExists(path string) (bool, error) {
|
||||
d := filepath.Dir(path)
|
||||
_, err = os.Stat(d)
|
||||
if os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(d, 0700); err != nil { //nolint:shadow
|
||||
if err := os.MkdirAll(d, 0700); err != nil { //nolint:govet
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
@@ -178,3 +179,15 @@ func cleanUpMapValue(v interface{}) interface{} {
|
||||
return v
|
||||
}
|
||||
}
|
||||
|
||||
// convertCmdStrToCmdArray checks if cmd string is blank (whitespace included)
|
||||
// then returns empty string array, else returns the splitted word array of cmd.
|
||||
// This is to ensure the result will never be []string{""}
|
||||
func convertCmdStrToCmdArray(cmd string) []string {
|
||||
var cmdArray []string
|
||||
trimmedCmdStr := strings.TrimSpace(cmd)
|
||||
if trimmedCmdStr != "" {
|
||||
cmdArray = strings.Split(trimmedCmdStr, " ")
|
||||
}
|
||||
return cmdArray
|
||||
}
|
||||
|
||||
34
commitlint.config.js
Normal file
34
commitlint.config.js
Normal file
@@ -0,0 +1,34 @@
|
||||
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',
|
||||
],
|
||||
],
|
||||
},
|
||||
};
|
||||
11
diskcache/cache.go
Normal file
11
diskcache/cache.go
Normal file
@@ -0,0 +1,11 @@
|
||||
package diskcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Interface interface {
|
||||
Store(ctx context.Context, key string, value []byte) error
|
||||
Load(ctx context.Context, key string) (value []byte, exist bool, err error)
|
||||
Delete(ctx context.Context, key string) error
|
||||
}
|
||||
110
diskcache/file_cache.go
Normal file
110
diskcache/file_cache.go
Normal file
@@ -0,0 +1,110 @@
|
||||
package diskcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"crypto/sha1" //nolint:gosec
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
type FileCache struct {
|
||||
fs afero.Fs
|
||||
|
||||
// granular locks
|
||||
scopedLocks struct {
|
||||
sync.Mutex
|
||||
sync.Once
|
||||
locks map[string]sync.Locker
|
||||
}
|
||||
}
|
||||
|
||||
func New(fs afero.Fs, root string) *FileCache {
|
||||
return &FileCache{
|
||||
fs: afero.NewBasePathFs(fs, root),
|
||||
}
|
||||
}
|
||||
|
||||
func (f *FileCache) Store(ctx context.Context, key string, value []byte) error {
|
||||
mu := f.getScopedLocks(key)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
fileName := f.getFileName(key)
|
||||
if err := f.fs.MkdirAll(filepath.Dir(fileName), 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := afero.WriteFile(f.fs, fileName, value, 0700); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileCache) Load(ctx context.Context, key string) (value []byte, exist bool, err error) {
|
||||
r, ok, err := f.open(key)
|
||||
if err != nil || !ok {
|
||||
return nil, ok, err
|
||||
}
|
||||
defer r.Close()
|
||||
|
||||
value, err = ioutil.ReadAll(r)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
return value, true, nil
|
||||
}
|
||||
|
||||
func (f *FileCache) Delete(ctx context.Context, key string) error {
|
||||
mu := f.getScopedLocks(key)
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
fileName := f.getFileName(key)
|
||||
if err := f.fs.Remove(fileName); err != nil && !errors.Is(err, os.ErrNotExist) {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (f *FileCache) open(key string) (afero.File, bool, error) {
|
||||
fileName := f.getFileName(key)
|
||||
file, err := f.fs.Open(fileName)
|
||||
if err != nil {
|
||||
if errors.Is(err, os.ErrNotExist) {
|
||||
return nil, false, nil
|
||||
}
|
||||
return nil, false, err
|
||||
}
|
||||
|
||||
return file, true, nil
|
||||
}
|
||||
|
||||
// getScopedLocks pull lock from the map if found or create a new one
|
||||
func (f *FileCache) getScopedLocks(key string) (lock sync.Locker) {
|
||||
f.scopedLocks.Do(func() { f.scopedLocks.locks = map[string]sync.Locker{} })
|
||||
|
||||
f.scopedLocks.Lock()
|
||||
lock, ok := f.scopedLocks.locks[key]
|
||||
if !ok {
|
||||
lock = &sync.Mutex{}
|
||||
f.scopedLocks.locks[key] = lock
|
||||
}
|
||||
f.scopedLocks.Unlock()
|
||||
|
||||
return lock
|
||||
}
|
||||
|
||||
func (f *FileCache) getFileName(key string) string {
|
||||
hasher := sha1.New() //nolint:gosec
|
||||
_, _ = hasher.Write([]byte(key))
|
||||
hash := hex.EncodeToString(hasher.Sum(nil))
|
||||
return fmt.Sprintf("%s/%s/%s", hash[:1], hash[1:3], hash)
|
||||
}
|
||||
55
diskcache/file_cache_test.go
Normal file
55
diskcache/file_cache_test.go
Normal file
@@ -0,0 +1,55 @@
|
||||
package diskcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestFileCache(t *testing.T) {
|
||||
ctx := context.Background()
|
||||
const (
|
||||
key = "key"
|
||||
value = "some text"
|
||||
newValue = "new text"
|
||||
cacheRoot = "/cache"
|
||||
cachedFilePath = "a/62/a62f2225bf70bfaccbc7f1ef2a397836717377de"
|
||||
)
|
||||
|
||||
fs := afero.NewMemMapFs()
|
||||
cache := New(fs, "/cache")
|
||||
|
||||
// store new key
|
||||
err := cache.Store(ctx, key, []byte(value))
|
||||
require.NoError(t, err)
|
||||
checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, value)
|
||||
|
||||
// update existing key
|
||||
err = cache.Store(ctx, key, []byte(newValue))
|
||||
require.NoError(t, err)
|
||||
checkValue(t, ctx, fs, filepath.Join(cacheRoot, cachedFilePath), cache, key, newValue)
|
||||
|
||||
// delete key
|
||||
err = cache.Delete(ctx, key)
|
||||
require.NoError(t, err)
|
||||
exists, err := afero.Exists(fs, filepath.Join(cacheRoot, cachedFilePath))
|
||||
require.NoError(t, err)
|
||||
require.False(t, exists)
|
||||
}
|
||||
|
||||
func checkValue(t *testing.T, ctx context.Context, fs afero.Fs, fileFullPath string, cache *FileCache, key, wantValue string) { //nolint:golint
|
||||
t.Helper()
|
||||
// check actual file content
|
||||
b, err := afero.ReadFile(fs, fileFullPath)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, wantValue, string(b))
|
||||
|
||||
// check cache content
|
||||
b, ok, err := cache.Load(ctx, key)
|
||||
require.NoError(t, err)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, wantValue, string(b))
|
||||
}
|
||||
24
diskcache/noop_cache.go
Normal file
24
diskcache/noop_cache.go
Normal file
@@ -0,0 +1,24 @@
|
||||
package diskcache
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type NoOp struct {
|
||||
}
|
||||
|
||||
func NewNoOp() *NoOp {
|
||||
return &NoOp{}
|
||||
}
|
||||
|
||||
func (n *NoOp) Store(ctx context.Context, key string, value []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (n *NoOp) Load(ctx context.Context, key string) (value []byte, exist bool, err error) {
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
func (n *NoOp) Delete(ctx context.Context, key string) error {
|
||||
return nil
|
||||
}
|
||||
@@ -16,4 +16,6 @@ var (
|
||||
ErrInvalidAuthMethod = errors.New("invalid auth method")
|
||||
ErrPermissionDenied = errors.New("permission denied")
|
||||
ErrInvalidRequestParams = errors.New("invalid request params")
|
||||
ErrSourceIsParent = errors.New("source is parent")
|
||||
ErrRootUserDeletion = errors.New("user with id 1 can't be deleted")
|
||||
)
|
||||
|
||||
116
files/file.go
116
files/file.go
@@ -38,15 +38,18 @@ type FileInfo struct {
|
||||
Subtitles []string `json:"subtitles,omitempty"`
|
||||
Content string `json:"content,omitempty"`
|
||||
Checksums map[string]string `json:"checksums,omitempty"`
|
||||
Token string `json:"token,omitempty"`
|
||||
}
|
||||
|
||||
// FileOptions are the options when getting a file info.
|
||||
type FileOptions struct {
|
||||
Fs afero.Fs
|
||||
Path string
|
||||
Modify bool
|
||||
Expand bool
|
||||
Checker rules.Checker
|
||||
Fs afero.Fs
|
||||
Path string
|
||||
Modify bool
|
||||
Expand bool
|
||||
ReadHeader bool
|
||||
Token string
|
||||
Checker rules.Checker
|
||||
}
|
||||
|
||||
// NewFileInfo creates a File object from a path and a given user. This File
|
||||
@@ -71,17 +74,18 @@ func NewFileInfo(opts FileOptions) (*FileInfo, error) {
|
||||
IsDir: info.IsDir(),
|
||||
Size: info.Size(),
|
||||
Extension: filepath.Ext(info.Name()),
|
||||
Token: opts.Token,
|
||||
}
|
||||
|
||||
if opts.Expand {
|
||||
if file.IsDir {
|
||||
if err := file.readListing(opts.Checker); err != nil { //nolint:shadow
|
||||
if err := file.readListing(opts.Checker, opts.ReadHeader); err != nil { //nolint:govet
|
||||
return nil, err
|
||||
}
|
||||
return file, nil
|
||||
}
|
||||
|
||||
err = file.detectType(opts.Modify, true)
|
||||
err = file.detectType(opts.Modify, true, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -134,11 +138,60 @@ func (i *FileInfo) Checksum(algo string) error {
|
||||
|
||||
//nolint:goconst
|
||||
//TODO: use constants
|
||||
func (i *FileInfo) detectType(modify, saveContent bool) error {
|
||||
func (i *FileInfo) detectType(modify, saveContent, readHeader bool) error {
|
||||
if IsNamedPipe(i.Mode) {
|
||||
i.Type = "blob"
|
||||
return nil
|
||||
}
|
||||
// failing to detect the type should not return error.
|
||||
// imagine the situation where a file in a dir with thousands
|
||||
// of files couldn't be opened: we'd have immediately
|
||||
// a 500 even though it doesn't matter. So we just log it.
|
||||
|
||||
var buffer []byte
|
||||
|
||||
mimetype := mime.TypeByExtension(i.Extension)
|
||||
if mimetype == "" && readHeader {
|
||||
buffer = i.readFirstBytes()
|
||||
mimetype = http.DetectContentType(buffer)
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(mimetype, "video"):
|
||||
i.Type = "video"
|
||||
i.detectSubtitles()
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "audio"):
|
||||
i.Type = "audio"
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "image"):
|
||||
i.Type = "image"
|
||||
return nil
|
||||
case (strings.HasPrefix(mimetype, "text") || (len(buffer) > 0 && !isBinary(buffer))) && i.Size <= 10*1024*1024: // 10 MB
|
||||
i.Type = "text"
|
||||
|
||||
if !modify {
|
||||
i.Type = "textImmutable"
|
||||
}
|
||||
|
||||
if saveContent {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
content, err := afs.ReadFile(i.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Content = string(content)
|
||||
}
|
||||
return nil
|
||||
default:
|
||||
i.Type = "blob"
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (i *FileInfo) readFirstBytes() []byte {
|
||||
reader, err := i.Fs.Open(i.Path)
|
||||
if err != nil {
|
||||
log.Print(err)
|
||||
@@ -155,44 +208,7 @@ func (i *FileInfo) detectType(modify, saveContent bool) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
mimetype := mime.TypeByExtension(i.Extension)
|
||||
if mimetype == "" {
|
||||
mimetype = http.DetectContentType(buffer[:n])
|
||||
}
|
||||
|
||||
switch {
|
||||
case strings.HasPrefix(mimetype, "video"):
|
||||
i.Type = "video"
|
||||
i.detectSubtitles()
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "audio"):
|
||||
i.Type = "audio"
|
||||
return nil
|
||||
case strings.HasPrefix(mimetype, "image"):
|
||||
i.Type = "image"
|
||||
return nil
|
||||
case isBinary(buffer[:n], n) || i.Size > 10*1024*1024: // 10 MB
|
||||
i.Type = "blob"
|
||||
return nil
|
||||
default:
|
||||
i.Type = "text"
|
||||
|
||||
if !modify {
|
||||
i.Type = "textImmutable"
|
||||
}
|
||||
|
||||
if saveContent {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
content, err := afs.ReadFile(i.Path)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
i.Content = string(content)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return buffer[:n]
|
||||
}
|
||||
|
||||
func (i *FileInfo) detectSubtitles() {
|
||||
@@ -211,7 +227,7 @@ func (i *FileInfo) detectSubtitles() {
|
||||
}
|
||||
}
|
||||
|
||||
func (i *FileInfo) readListing(checker rules.Checker) error {
|
||||
func (i *FileInfo) readListing(checker rules.Checker, readHeader bool) error {
|
||||
afs := &afero.Afero{Fs: i.Fs}
|
||||
dir, err := afs.ReadDir(i.Path)
|
||||
if err != nil {
|
||||
@@ -232,9 +248,9 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
|
||||
continue
|
||||
}
|
||||
|
||||
if strings.HasPrefix(f.Mode().String(), "L") {
|
||||
if IsSymlink(f.Mode()) {
|
||||
// It's a symbolic link. We try to follow it. If it doesn't work,
|
||||
// we stay with the link information instead if the target's.
|
||||
// we stay with the link information instead of the target's.
|
||||
info, err := i.Fs.Stat(fPath)
|
||||
if err == nil {
|
||||
f = info
|
||||
@@ -257,7 +273,7 @@ func (i *FileInfo) readListing(checker rules.Checker) error {
|
||||
} else {
|
||||
listing.NumFiles++
|
||||
|
||||
err := file.detectType(true, false)
|
||||
err := file.detectType(true, false, readHeader)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"os"
|
||||
"unicode/utf8"
|
||||
)
|
||||
|
||||
func isBinary(content []byte, _ int) bool {
|
||||
func isBinary(content []byte) bool {
|
||||
maybeStr := string(content)
|
||||
runeCnt := utf8.RuneCount(content)
|
||||
runeIndex := 0
|
||||
@@ -48,3 +49,11 @@ func isBinary(content []byte, _ int) bool {
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func IsNamedPipe(mode os.FileMode) bool {
|
||||
return mode&os.ModeNamedPipe != 0
|
||||
}
|
||||
|
||||
func IsSymlink(mode os.FileMode) bool {
|
||||
return mode&os.ModeSymlink != 0
|
||||
}
|
||||
|
||||
@@ -3,11 +3,31 @@ package fileutils
|
||||
import (
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/spf13/afero"
|
||||
)
|
||||
|
||||
// MoveFile moves file from src to dst.
|
||||
// By default the rename filesystem system call is used. If src and dst point to different volumes
|
||||
// the file copy is used as a fallback
|
||||
func MoveFile(fs afero.Fs, src, dst string) error {
|
||||
if fs.Rename(src, dst) == nil {
|
||||
return nil
|
||||
}
|
||||
// fallback
|
||||
err := CopyFile(fs, src, dst)
|
||||
if err != nil {
|
||||
_ = fs.Remove(dst)
|
||||
return err
|
||||
}
|
||||
if err := fs.Remove(src); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// CopyFile copies a file from source to dest and returns
|
||||
// an error if any.
|
||||
func CopyFile(fs afero.Fs, source, dest string) error {
|
||||
@@ -38,15 +58,71 @@ func CopyFile(fs afero.Fs, source, dest string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
// Copy the mode if the user can't
|
||||
// open the file.
|
||||
// Copy the mode
|
||||
info, err := fs.Stat(source)
|
||||
if err != nil {
|
||||
err = fs.Chmod(dest, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return err
|
||||
}
|
||||
err = fs.Chmod(dest, info.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CommonPrefix returns common directory path of provided files
|
||||
func CommonPrefix(sep byte, paths ...string) string {
|
||||
// Handle special cases.
|
||||
switch len(paths) {
|
||||
case 0:
|
||||
return ""
|
||||
case 1:
|
||||
return path.Clean(paths[0])
|
||||
}
|
||||
|
||||
// Note, we treat string as []byte, not []rune as is often
|
||||
// done in Go. (And sep as byte, not rune). This is because
|
||||
// most/all supported OS' treat paths as string of non-zero
|
||||
// bytes. A filename may be displayed as a sequence of Unicode
|
||||
// runes (typically encoded as UTF-8) but paths are
|
||||
// not required to be valid UTF-8 or in any normalized form
|
||||
// (e.g. "é" (U+00C9) and "é" (U+0065,U+0301) are different
|
||||
// file names.
|
||||
c := []byte(path.Clean(paths[0]))
|
||||
|
||||
// We add a trailing sep to handle the case where the
|
||||
// common prefix directory is included in the path list
|
||||
// (e.g. /home/user1, /home/user1/foo, /home/user1/bar).
|
||||
// path.Clean will have cleaned off trailing / separators with
|
||||
// the exception of the root directory, "/" (in which case we
|
||||
// make it "//", but this will get fixed up to "/" bellow).
|
||||
c = append(c, sep)
|
||||
|
||||
// Ignore the first path since it's already in c
|
||||
for _, v := range paths[1:] {
|
||||
// Clean up each path before testing it
|
||||
v = path.Clean(v) + string(sep)
|
||||
|
||||
// Find the first non-common byte and truncate c
|
||||
if len(v) < len(c) {
|
||||
c = c[:len(v)]
|
||||
}
|
||||
for i := 0; i < len(c); i++ {
|
||||
if v[i] != c[i] {
|
||||
c = c[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remove trailing non-separator characters and the final separator
|
||||
for i := len(c) - 1; i >= 0; i-- {
|
||||
if c[i] == sep {
|
||||
c = c[:i]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return string(c)
|
||||
}
|
||||
|
||||
46
fileutils/file_test.go
Normal file
46
fileutils/file_test.go
Normal file
@@ -0,0 +1,46 @@
|
||||
package fileutils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestCommonPrefix(t *testing.T) {
|
||||
testCases := map[string]struct {
|
||||
paths []string
|
||||
want string
|
||||
}{
|
||||
"same lvl": {
|
||||
paths: []string{
|
||||
"/home/user/file1",
|
||||
"/home/user/file2",
|
||||
},
|
||||
want: "/home/user",
|
||||
},
|
||||
"sub folder": {
|
||||
paths: []string{
|
||||
"/home/user/folder",
|
||||
"/home/user/folder/file",
|
||||
},
|
||||
want: "/home/user/folder",
|
||||
},
|
||||
"relative path": {
|
||||
paths: []string{
|
||||
"/home/user/folder",
|
||||
"/home/user/folder/../folder2",
|
||||
},
|
||||
want: "/home/user",
|
||||
},
|
||||
"no common path": {
|
||||
paths: []string{
|
||||
"/home/user/folder",
|
||||
"/etc/file",
|
||||
},
|
||||
want: "",
|
||||
},
|
||||
}
|
||||
for name, tt := range testCases {
|
||||
t.Run(name, func(t *testing.T) {
|
||||
if got := CommonPrefix('/', tt.paths...); got != tt.want {
|
||||
t.Errorf("CommonPrefix() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
10
frontend/assets.go
Normal file
10
frontend/assets.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package frontend
|
||||
|
||||
import "embed"
|
||||
|
||||
//go:embed dist/*
|
||||
var assets embed.FS
|
||||
|
||||
func Assets() embed.FS {
|
||||
return assets
|
||||
}
|
||||
4
frontend/dist/.gitignore
vendored
Normal file
4
frontend/dist/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
16
frontend/package-lock.json
generated
16
frontend/package-lock.json
generated
@@ -9929,8 +9929,7 @@
|
||||
"pako": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz",
|
||||
"integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==",
|
||||
"dev": true
|
||||
"integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA=="
|
||||
},
|
||||
"parallel-transform": {
|
||||
"version": "1.1.0",
|
||||
@@ -12895,6 +12894,14 @@
|
||||
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
|
||||
"dev": true
|
||||
},
|
||||
"utif": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "http://mirrors.cloud.tencent.com/npm/utif/-/utif-3.1.0.tgz",
|
||||
"integrity": "sha512-WEo4D/xOvFW53K5f5QTaTbbiORcm2/pCL9P6qmJnup+17eYfKaEhDeX9PeQkuyEoIxlbGklDuGl8xwuXYMrrXQ==",
|
||||
"requires": {
|
||||
"pako": "^1.0.5"
|
||||
}
|
||||
},
|
||||
"util": {
|
||||
"version": "0.11.1",
|
||||
"resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz",
|
||||
@@ -13030,6 +13037,11 @@
|
||||
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.15.3.tgz",
|
||||
"integrity": "sha512-PVNgo6yhOmacZVFjSapZ314oewwLyXHjJwAqjnaPN1GJAJd/dvsrShGzSiJuCX4Hc36G4epJvNXUwO8y7wEKew=="
|
||||
},
|
||||
"vue-lazyload": {
|
||||
"version": "1.3.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.3.3.tgz",
|
||||
"integrity": "sha512-uHnq0FTEeNmqnbBC2aRKlmtd9LofMZ6Q3mWvgfLa+i9vhxU8fDK+nGs9c1iVT85axSua/AUnMttIq3xPaU9G3A=="
|
||||
},
|
||||
"vue-loader": {
|
||||
"version": "15.8.3",
|
||||
"resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.8.3.tgz",
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"watch": "vue-cli-service build --watch",
|
||||
"build": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitignore' -exec rm -r {} + && vue-cli-service build --no-clean",
|
||||
"watch": "find ./dist -maxdepth 1 -mindepth 1 ! -name '.gitignore' -exec rm -r {} + && vue-cli-service build --watch --no-clean",
|
||||
"lint": "vue-cli-service lint --fix"
|
||||
},
|
||||
"dependencies": {
|
||||
@@ -19,8 +19,10 @@
|
||||
"normalize.css": "^8.0.1",
|
||||
"noty": "^3.2.0-beta",
|
||||
"qrcode.vue": "^1.7.0",
|
||||
"utif": "^3.1.0",
|
||||
"vue": "^2.6.10",
|
||||
"vue-i18n": "^8.15.3",
|
||||
"vue-lazyload": "^1.3.3",
|
||||
"vue-router": "^3.1.3",
|
||||
"vuex": "^3.1.2",
|
||||
"vuex-router-sync": "^5.0.0"
|
||||
|
||||
@@ -13,24 +13,25 @@
|
||||
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="[{[ .StaticURL ]}]/img/icons/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="[{[ .StaticURL ]}]/img/icons/favicon-16x16.png">
|
||||
|
||||
<!-- Add to home screen for Android and modern mobile browsers -->
|
||||
<link rel="manifest" id="manifestPlaceholder" crossorigin="use-credentials">
|
||||
<meta name="theme-color" content="#2979ff">
|
||||
|
||||
<!-- Add to home screen for Safari on iOS -->
|
||||
<!-- Add to home screen for Safari on iOS/iPadOS -->
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||
<meta name="apple-mobile-web-app-title" content="assets">
|
||||
<link rel="apple-touch-icon" href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" href="[{[ .StaticURL ]}]/img/icons/apple-touch-icon.png">
|
||||
|
||||
<!-- Add to home screen for Windows -->
|
||||
<meta name="msapplication-TileImage" content="[{[ .StaticURL ]}]/img/icons/msapplication-icon-144x144.png">
|
||||
<meta name="msapplication-TileImage" content="[{[ .StaticURL ]}]/img/icons/mstile-144x144.png">
|
||||
<meta name="msapplication-TileColor" content="#2979ff">
|
||||
|
||||
<!-- Inject Some Variables and generate the manifest json -->
|
||||
<script>
|
||||
window.FileBrowser = JSON.parse(`[{[ .Json ]}]`);
|
||||
|
||||
|
||||
var fullStaticURL = window.location.origin + window.FileBrowser.StaticURL;
|
||||
var dynamicManifest = {
|
||||
"name": window.FileBrowser.Name || 'File Browser',
|
||||
|
||||
@@ -69,13 +69,16 @@ nav > div {
|
||||
border-color: var(--divider);
|
||||
}
|
||||
|
||||
#breadcrumbs {
|
||||
.breadcrumbs {
|
||||
border-color: var(--divider);
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
#breadcrumbs span {
|
||||
.breadcrumbs span {
|
||||
color: var(--textPrimary) !important;
|
||||
}
|
||||
.breadcrumbs a:hover {
|
||||
background-color: rgba(255, 255, 255, .1);
|
||||
}
|
||||
|
||||
#listing .item {
|
||||
background: var(--surfacePrimary);
|
||||
@@ -114,13 +117,20 @@ nav > div {
|
||||
background: var(--surfaceSecondary);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li {
|
||||
color: var(--textSecondary);
|
||||
}
|
||||
.dashboard #nav ul li:hover {
|
||||
background: var(--surfaceSecondary);
|
||||
}
|
||||
|
||||
.card h3,
|
||||
.dashboard #nav,
|
||||
.dashboard p label {
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
.card#share ul li input,
|
||||
.card#share ul li select,
|
||||
.card#share input,
|
||||
.card#share select,
|
||||
.input {
|
||||
background: var(--surfaceSecondary);
|
||||
color: var(--textPrimary);
|
||||
@@ -138,7 +148,7 @@ nav > div {
|
||||
background: #147A41;
|
||||
}
|
||||
|
||||
.dashboard #nav li,
|
||||
.dashboard #nav .wrapper,
|
||||
.collapsible {
|
||||
border-color: var(--divider);
|
||||
}
|
||||
@@ -191,10 +201,11 @@ table th {
|
||||
}
|
||||
}
|
||||
|
||||
.share__box, .share__box__download {
|
||||
background: var(--surfaceSecondary) !important;
|
||||
.share__box {
|
||||
background: var(--surfacePrimary) !important;
|
||||
color: var(--textPrimary);
|
||||
}
|
||||
.share__box__download {
|
||||
border-bottom-color: var(--divider);
|
||||
|
||||
.share__box__element {
|
||||
border-top-color: var(--divider);
|
||||
}
|
||||
@@ -43,7 +43,7 @@ async function resourceAction (url, method, content) {
|
||||
const res = await fetchURL(`/api/resources${url}`, opts)
|
||||
|
||||
if (res.status !== 200) {
|
||||
throw new Error(res.responseText)
|
||||
throw new Error(await res.text())
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
@@ -74,17 +74,25 @@ export function download (format, ...files) {
|
||||
url += `/?files=${arg}&`
|
||||
}
|
||||
|
||||
if (format !== null) {
|
||||
if (format) {
|
||||
url += `algo=${format}&`
|
||||
}
|
||||
|
||||
url += `auth=${store.state.jwt}`
|
||||
if (store.state.jwt){
|
||||
url += `auth=${store.state.jwt}&`
|
||||
}
|
||||
|
||||
window.open(url)
|
||||
}
|
||||
|
||||
export async function post (url, content = '', overwrite = false, onupload) {
|
||||
url = removePrefix(url)
|
||||
|
||||
let bufferContent
|
||||
if (content instanceof Blob && !['http:', 'https:'].includes(window.location.protocol)) {
|
||||
bufferContent = await new Response(content).arrayBuffer()
|
||||
}
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
let request = new XMLHttpRequest()
|
||||
request.open('POST', `${baseURL}/api/resources${url}?override=${overwrite}`, true)
|
||||
@@ -108,7 +116,7 @@ export async function post (url, content = '', overwrite = false, onupload) {
|
||||
reject(error)
|
||||
}
|
||||
|
||||
request.send(content)
|
||||
request.send(bufferContent || content)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -116,7 +124,7 @@ function moveCopy (items, copy = false, overwrite = false, rename = false) {
|
||||
let promises = []
|
||||
|
||||
for (let item of items) {
|
||||
const from = removePrefix(item.from)
|
||||
const from = item.from
|
||||
const to = encodeURIComponent(removePrefix(item.to))
|
||||
const url = `${from}?action=${copy ? 'copy' : 'rename'}&destination=${to}&override=${overwrite}&rename=${rename}`
|
||||
promises.push(resourceAction(url, 'PATCH'))
|
||||
|
||||
@@ -2,6 +2,7 @@ import * as files from './files'
|
||||
import * as share from './share'
|
||||
import * as users from './users'
|
||||
import * as settings from './settings'
|
||||
import * as pub from './pub'
|
||||
import search from './search'
|
||||
import commands from './commands'
|
||||
|
||||
@@ -10,6 +11,7 @@ export {
|
||||
share,
|
||||
users,
|
||||
settings,
|
||||
pub,
|
||||
commands,
|
||||
search
|
||||
}
|
||||
|
||||
61
frontend/src/api/pub.js
Normal file
61
frontend/src/api/pub.js
Normal file
@@ -0,0 +1,61 @@
|
||||
import { fetchURL, removePrefix } from './utils'
|
||||
import { baseURL } from '@/utils/constants'
|
||||
|
||||
export async function fetch (url, password = "") {
|
||||
url = removePrefix(url)
|
||||
|
||||
const res = await fetchURL(`/api/public/share${url}`, {
|
||||
headers: {'X-SHARE-PASSWORD': password},
|
||||
})
|
||||
|
||||
if (res.status === 200) {
|
||||
let data = await res.json()
|
||||
data.url = `/share${url}`
|
||||
|
||||
if (data.isDir) {
|
||||
if (!data.url.endsWith('/')) data.url += '/'
|
||||
data.items = data.items.map((item, index) => {
|
||||
item.index = index
|
||||
item.url = `${data.url}${encodeURIComponent(item.name)}`
|
||||
|
||||
if (item.isDir) {
|
||||
item.url += '/'
|
||||
}
|
||||
|
||||
return item
|
||||
})
|
||||
}
|
||||
|
||||
return data
|
||||
} else {
|
||||
throw new Error(res.status)
|
||||
}
|
||||
}
|
||||
|
||||
export function download(format, hash, token, ...files) {
|
||||
let url = `${baseURL}/api/public/dl/${hash}`
|
||||
|
||||
if (files.length === 1) {
|
||||
url += encodeURIComponent(files[0]) + '?'
|
||||
} else {
|
||||
let arg = ''
|
||||
|
||||
for (let file of files) {
|
||||
arg += encodeURIComponent(file) + ','
|
||||
}
|
||||
|
||||
arg = arg.substring(0, arg.length - 1)
|
||||
arg = encodeURIComponent(arg)
|
||||
url += `/?files=${arg}&`
|
||||
}
|
||||
|
||||
if (format) {
|
||||
url += `algo=${format}&`
|
||||
}
|
||||
|
||||
if (token) {
|
||||
url += `token=${token}&`
|
||||
}
|
||||
|
||||
window.open(url)
|
||||
}
|
||||
@@ -1,8 +1,31 @@
|
||||
import { fetchJSON, removePrefix } from './utils'
|
||||
import { fetchURL, removePrefix } from './utils'
|
||||
import url from '../utils/url'
|
||||
|
||||
export default async function search (url, query) {
|
||||
url = removePrefix(url)
|
||||
export default async function search (base, query) {
|
||||
base = removePrefix(base)
|
||||
query = encodeURIComponent(query)
|
||||
|
||||
return fetchJSON(`/api/search${url}?query=${query}`, {})
|
||||
}
|
||||
if (!base.endsWith('/')) {
|
||||
base += '/'
|
||||
}
|
||||
|
||||
let res = await fetchURL(`/api/search${base}?query=${query}`, {})
|
||||
|
||||
if (res.status === 200) {
|
||||
let data = await res.json()
|
||||
|
||||
data = data.map((item) => {
|
||||
item.url = `/files${base}` + url.encodePath(item.path)
|
||||
|
||||
if (item.dir) {
|
||||
item.url += '/'
|
||||
}
|
||||
|
||||
return item
|
||||
})
|
||||
|
||||
return data
|
||||
} else {
|
||||
throw Error(res.status)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fetchURL, fetchJSON, removePrefix } from './utils'
|
||||
|
||||
export async function getHash(hash) {
|
||||
return fetchJSON(`/api/public/share/${hash}`)
|
||||
export async function list() {
|
||||
return fetchJSON('/api/shares')
|
||||
}
|
||||
|
||||
export async function get(url) {
|
||||
@@ -19,14 +19,18 @@ export async function remove(hash) {
|
||||
}
|
||||
}
|
||||
|
||||
export async function create(url, expires = '', unit = 'hours') {
|
||||
export async function create(url, password = '', expires = '', unit = 'hours') {
|
||||
url = removePrefix(url)
|
||||
url = `/api/share${url}`
|
||||
if (expires !== '') {
|
||||
url += `?expires=${expires}&unit=${unit}`
|
||||
}
|
||||
|
||||
let body = '{}';
|
||||
if (password != '' || expires !== '' || unit !== 'hours') {
|
||||
body = JSON.stringify({password: password, expires: expires, unit: unit})
|
||||
}
|
||||
return fetchJSON(url, {
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
body: body,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -34,9 +34,7 @@ export async function fetchJSON (url, opts) {
|
||||
}
|
||||
|
||||
export function removePrefix (url) {
|
||||
if (url.startsWith('/files')) {
|
||||
url = url.slice(6)
|
||||
}
|
||||
url = url.split('/').splice(2).join('/')
|
||||
|
||||
if (url === '') url = '/'
|
||||
if (url[0] !== '/') url = '/' + url
|
||||
|
||||
67
frontend/src/components/Breadcrumbs.vue
Normal file
67
frontend/src/components/Breadcrumbs.vue
Normal file
@@ -0,0 +1,67 @@
|
||||
<template>
|
||||
<div class="breadcrumbs">
|
||||
<component :is="element" :to="base || ''" :aria-label="$t('files.home')" :title="$t('files.home')">
|
||||
<i class="material-icons">home</i>
|
||||
</component>
|
||||
|
||||
<span v-for="(link, index) in items" :key="index">
|
||||
<span class="chevron"><i class="material-icons">keyboard_arrow_right</i></span>
|
||||
<component :is="element" :to="link.url">{{ link.name }}</component>
|
||||
</span>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'breadcrumbs',
|
||||
props: [
|
||||
'base',
|
||||
'noLink'
|
||||
],
|
||||
computed: {
|
||||
items () {
|
||||
const relativePath = this.$route.path.replace(this.base, '')
|
||||
let parts = relativePath.split('/')
|
||||
|
||||
if (parts[0] === '') {
|
||||
parts.shift()
|
||||
}
|
||||
|
||||
if (parts[parts.length - 1] === '') {
|
||||
parts.pop()
|
||||
}
|
||||
|
||||
let breadcrumbs = []
|
||||
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (i === 0) {
|
||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: this.base + '/' + parts[i] + '/' })
|
||||
} else {
|
||||
breadcrumbs.push({ name: decodeURIComponent(parts[i]), url: breadcrumbs[i - 1].url + parts[i] + '/' })
|
||||
}
|
||||
}
|
||||
|
||||
if (breadcrumbs.length > 3) {
|
||||
while (breadcrumbs.length !== 4) {
|
||||
breadcrumbs.shift()
|
||||
}
|
||||
|
||||
breadcrumbs[0].name = '...'
|
||||
}
|
||||
|
||||
return breadcrumbs
|
||||
},
|
||||
element () {
|
||||
if (this.noLink !== undefined) {
|
||||
return 'span'
|
||||
}
|
||||
|
||||
return 'router-link'
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -1,182 +0,0 @@
|
||||
<template>
|
||||
<header v-if="!isEditor">
|
||||
<div>
|
||||
<button @click="openSidebar" :aria-label="$t('buttons.toggleSidebar')" :title="$t('buttons.toggleSidebar')" class="action">
|
||||
<i class="material-icons">menu</i>
|
||||
</button>
|
||||
<img :src="logoURL" alt="File Browser">
|
||||
<search v-if="isLogged"></search>
|
||||
</div>
|
||||
<div>
|
||||
<template v-if="isLogged">
|
||||
<button @click="openSearch" :aria-label="$t('buttons.search')" :title="$t('buttons.search')" class="search-button action">
|
||||
<i class="material-icons">search</i>
|
||||
</button>
|
||||
|
||||
<button @click="openMore" id="more" :aria-label="$t('buttons.more')" :title="$t('buttons.more')" class="action">
|
||||
<i class="material-icons">more_vert</i>
|
||||
</button>
|
||||
|
||||
<!-- Menu that shows on listing AND mobile when there are files selected -->
|
||||
<div id="file-selection" v-if="isMobile && isListing">
|
||||
<span v-if="selectedCount > 0">{{ selectedCount }} selected</span>
|
||||
<share-button v-show="showShareButton"></share-button>
|
||||
<rename-button v-show="showRenameButton"></rename-button>
|
||||
<copy-button v-show="showCopyButton"></copy-button>
|
||||
<move-button v-show="showMoveButton"></move-button>
|
||||
<delete-button v-show="showDeleteButton"></delete-button>
|
||||
</div>
|
||||
|
||||
<!-- This buttons are shown on a dropdown on mobile phones -->
|
||||
<div id="dropdown" :class="{ active: showMore }">
|
||||
<div v-if="!isListing || !isMobile">
|
||||
<share-button v-show="showShareButton"></share-button>
|
||||
<rename-button v-show="showRenameButton"></rename-button>
|
||||
<copy-button v-show="showCopyButton"></copy-button>
|
||||
<move-button v-show="showMoveButton"></move-button>
|
||||
<delete-button v-show="showDeleteButton"></delete-button>
|
||||
</div>
|
||||
|
||||
<shell-button v-show="user.perm.execute" />
|
||||
<switch-button v-show="isListing"></switch-button>
|
||||
<download-button v-show="showDownloadButton"></download-button>
|
||||
<upload-button v-show="showUpload"></upload-button>
|
||||
<info-button v-show="isFiles"></info-button>
|
||||
|
||||
<button v-show="isListing" @click="toggleMultipleSelection" :aria-label="$t('buttons.selectMultiple')" :title="$t('buttons.selectMultiple')" class="action" >
|
||||
<i class="material-icons">check_circle</i>
|
||||
<span>{{ $t('buttons.select') }}</span>
|
||||
</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<div v-show="showOverlay" @click="resetPrompts" class="overlay"></div>
|
||||
</div>
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Search from './Search'
|
||||
import InfoButton from './buttons/Info'
|
||||
import DeleteButton from './buttons/Delete'
|
||||
import RenameButton from './buttons/Rename'
|
||||
import UploadButton from './buttons/Upload'
|
||||
import DownloadButton from './buttons/Download'
|
||||
import SwitchButton from './buttons/SwitchView'
|
||||
import MoveButton from './buttons/Move'
|
||||
import CopyButton from './buttons/Copy'
|
||||
import ShareButton from './buttons/Share'
|
||||
import ShellButton from './buttons/Shell'
|
||||
import {mapGetters, mapState} from 'vuex'
|
||||
import { logoURL } from '@/utils/constants'
|
||||
import * as api from '@/api'
|
||||
import buttons from '@/utils/buttons'
|
||||
|
||||
export default {
|
||||
name: 'header-layout',
|
||||
components: {
|
||||
Search,
|
||||
InfoButton,
|
||||
DeleteButton,
|
||||
ShareButton,
|
||||
RenameButton,
|
||||
DownloadButton,
|
||||
CopyButton,
|
||||
UploadButton,
|
||||
SwitchButton,
|
||||
MoveButton,
|
||||
ShellButton
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
width: window.innerWidth,
|
||||
pluginData: {
|
||||
api,
|
||||
buttons,
|
||||
'store': this.$store,
|
||||
'router': this.$router
|
||||
}
|
||||
}
|
||||
},
|
||||
created () {
|
||||
window.addEventListener('resize', () => {
|
||||
this.width = window.innerWidth
|
||||
})
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'selectedCount',
|
||||
'isFiles',
|
||||
'isEditor',
|
||||
'isListing',
|
||||
'isLogged'
|
||||
]),
|
||||
...mapState([
|
||||
'req',
|
||||
'user',
|
||||
'loading',
|
||||
'reload',
|
||||
'multiple'
|
||||
]),
|
||||
logoURL: () => logoURL,
|
||||
isMobile () {
|
||||
return this.width <= 736
|
||||
},
|
||||
showUpload () {
|
||||
return this.isListing && this.user.perm.create
|
||||
},
|
||||
showDownloadButton () {
|
||||
return this.isFiles && this.user.perm.download
|
||||
},
|
||||
showDeleteButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount !== 0 && this.user.perm.delete)
|
||||
: this.user.perm.delete)
|
||||
},
|
||||
showRenameButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount === 1 && this.user.perm.rename)
|
||||
: this.user.perm.rename)
|
||||
},
|
||||
showShareButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount === 1 && this.user.perm.share)
|
||||
: this.user.perm.share)
|
||||
},
|
||||
showMoveButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount > 0 && this.user.perm.rename)
|
||||
: this.user.perm.rename)
|
||||
},
|
||||
showCopyButton () {
|
||||
return this.isFiles && (this.isListing
|
||||
? (this.selectedCount > 0 && this.user.perm.create)
|
||||
: this.user.perm.create)
|
||||
},
|
||||
showMore () {
|
||||
return this.isFiles && this.$store.state.show === 'more'
|
||||
},
|
||||
showOverlay () {
|
||||
return this.showMore
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSidebar () {
|
||||
this.$store.commit('showHover', 'sidebar')
|
||||
},
|
||||
openMore () {
|
||||
this.$store.commit('showHover', 'more')
|
||||
},
|
||||
openSearch () {
|
||||
this.$store.commit('showHover', 'search')
|
||||
},
|
||||
toggleMultipleSelection () {
|
||||
this.$store.commit('multiple', !this.multiple)
|
||||
this.resetPrompts()
|
||||
},
|
||||
resetPrompts () {
|
||||
this.$store.commit('closeHovers')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -49,7 +49,7 @@
|
||||
</template>
|
||||
<ul v-show="results.length > 0">
|
||||
<li v-for="(s,k) in filteredResults" :key="k">
|
||||
<router-link @click.native="close" :to="'./' + s.path">
|
||||
<router-link @click.native="close" :to="s.url">
|
||||
<i v-if="s.dir" class="material-icons">folder</i>
|
||||
<i v-else class="material-icons">insert_drive_file</i>
|
||||
<span>./{{ s.path }}</span>
|
||||
@@ -183,8 +183,12 @@ export default {
|
||||
|
||||
this.ongoing = true
|
||||
|
||||
try {
|
||||
this.results = await search(path, this.value)
|
||||
} catch (error) {
|
||||
this.$showError(error)
|
||||
}
|
||||
|
||||
this.results = await search(path, this.value)
|
||||
this.ongoing = false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.copy')" :title="$t('buttons.copy')" class="action" id="copy-button">
|
||||
<i class="material-icons">content_copy</i>
|
||||
<span>{{ $t('buttons.copyFile') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'copy-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('showHover', 'copy')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.delete')" :title="$t('buttons.delete')" class="action" id="delete-button">
|
||||
<i class="material-icons">delete</i>
|
||||
<span>{{ $t('buttons.delete') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'delete-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('showHover', 'delete')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,35 +0,0 @@
|
||||
<template>
|
||||
<button @click="download" :aria-label="$t('buttons.download')" :title="$t('buttons.download')" id="download-button" class="action">
|
||||
<i class="material-icons">file_download</i>
|
||||
<span>{{ $t('buttons.download') }}</span>
|
||||
<span v-if="selectedCount > 0" class="counter">{{ selectedCount }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters, mapState} from 'vuex'
|
||||
import { files as api } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'download-button',
|
||||
computed: {
|
||||
...mapState(['req', 'selected']),
|
||||
...mapGetters(['isListing', 'selectedCount'])
|
||||
},
|
||||
methods: {
|
||||
download: function () {
|
||||
if (!this.isListing) {
|
||||
api.download(null, this.$route.path)
|
||||
return
|
||||
}
|
||||
|
||||
if (this.selectedCount === 1 && !this.req.items[this.selected[0]].isDir) {
|
||||
api.download(null, this.req.items[this.selected[0]].url)
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.commit('showHover', 'download')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button :title="$t('buttons.info')" :aria-label="$t('buttons.info')" class="action" @click="show">
|
||||
<i class="material-icons">info</i>
|
||||
<span>{{ $t('buttons.info') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'info-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('showHover', 'info')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.move')" :title="$t('buttons.move')" class="action" id="move-button">
|
||||
<i class="material-icons">forward</i>
|
||||
<span>{{ $t('buttons.moveFile') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'move-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('showHover', 'move')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.rename')" :title="$t('buttons.rename')" class="action" id="rename-button">
|
||||
<i class="material-icons">mode_edit</i>
|
||||
<span>{{ $t('buttons.rename') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'rename-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('showHover', 'rename')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.share')" :title="$t('buttons.share')" class="action">
|
||||
<i class="material-icons">share</i>
|
||||
<span>{{ $t('buttons.share') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'share-button',
|
||||
methods: {
|
||||
show () {
|
||||
this.$store.commit('showHover', 'share')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,17 +0,0 @@
|
||||
<template>
|
||||
<button @click="show" :aria-label="$t('buttons.shell')" :title="$t('buttons.shell')" class="action">
|
||||
<i class="material-icons">code</i>
|
||||
<span>{{ $t('buttons.shell') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'shell-button',
|
||||
methods: {
|
||||
show: function () {
|
||||
this.$store.commit('toggleShell')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,40 +0,0 @@
|
||||
<template>
|
||||
<button @click="change" :aria-label="$t('buttons.switchView')" :title="$t('buttons.switchView')" class="action" id="switch-view-button">
|
||||
<i class="material-icons">{{ icon }}</i>
|
||||
<span>{{ $t('buttons.switchView') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import { users as api } from '@/api'
|
||||
|
||||
export default {
|
||||
name: 'switch-button',
|
||||
computed: {
|
||||
...mapState(['user']),
|
||||
icon: function () {
|
||||
if (this.user.viewMode === 'mosaic') return 'view_list'
|
||||
return 'view_module'
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([ 'updateUser', 'closeHovers' ]),
|
||||
change: async function () {
|
||||
this.closeHovers()
|
||||
|
||||
const data = {
|
||||
id: this.user.id,
|
||||
viewMode: (this.icon === 'view_list') ? 'list' : 'mosaic'
|
||||
}
|
||||
|
||||
try {
|
||||
await api.update(data, ['viewMode'])
|
||||
this.updateUser(data)
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,21 +0,0 @@
|
||||
<template>
|
||||
<button @click="upload" :aria-label="$t('buttons.upload')" :title="$t('buttons.upload')" class="action" id="upload-button">
|
||||
<i class="material-icons">file_upload</i>
|
||||
<span>{{ $t('buttons.upload') }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'upload-button',
|
||||
methods: {
|
||||
upload: function () {
|
||||
if (typeof(DataTransferItem.prototype.webkitGetAsEntry) !== 'undefined') {
|
||||
this.$store.commit('showHover', 'upload')
|
||||
} else {
|
||||
document.getElementById('upload-input').click();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -10,11 +10,12 @@
|
||||
@mouseup="mouseUp"
|
||||
@wheel="wheelMove"
|
||||
>
|
||||
<img :src="src" class="image-ex-img image-ex-img-center" ref="imgex" @load="onLoad">
|
||||
<img src="" class="image-ex-img image-ex-img-center" ref="imgex" @load="onLoad">
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import throttle from 'lodash.throttle'
|
||||
import UTIF from 'utif'
|
||||
|
||||
export default {
|
||||
props: {
|
||||
@@ -61,6 +62,9 @@ export default {
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
if (!this.decodeUTIF()) {
|
||||
this.$refs.imgex.src = this.src
|
||||
}
|
||||
let container = this.$refs.container
|
||||
this.classList.forEach(className => container.classList.add(className))
|
||||
// set width and height if they are zero
|
||||
@@ -77,7 +81,28 @@ export default {
|
||||
window.removeEventListener('resize', this.onResize)
|
||||
document.removeEventListener('mouseup', this.onMouseUp)
|
||||
},
|
||||
watch: {
|
||||
src: function () {
|
||||
this.scale = 1
|
||||
this.setZoom()
|
||||
this.setCenter()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// Modified from UTIF.replaceIMG
|
||||
decodeUTIF() {
|
||||
const sufs = ["tif", "tiff", "dng", "cr2", "nef"]
|
||||
let suff = document.location.pathname.split(".").pop().toLowerCase()
|
||||
if (sufs.indexOf(suff) == -1) return false
|
||||
let xhr = new XMLHttpRequest()
|
||||
UTIF._xhrs.push(xhr)
|
||||
UTIF._imgs.push(this.$refs.imgex)
|
||||
xhr.open("GET", this.src)
|
||||
xhr.responseType = "arraybuffer"
|
||||
xhr.onload = UTIF._imgLoaded
|
||||
xhr.send()
|
||||
return true
|
||||
},
|
||||
onLoad() {
|
||||
let img = this.$refs.imgex
|
||||
|
||||
@@ -131,6 +156,15 @@ export default {
|
||||
this.lastX = null
|
||||
this.lastY = null
|
||||
this.lastTouchDistance = null
|
||||
if (event.targetTouches.length < 2) {
|
||||
setTimeout(() => {
|
||||
this.touches = 0
|
||||
}, 300)
|
||||
this.touches++
|
||||
if (this.touches > 1) {
|
||||
this.zoomAuto(event)
|
||||
}
|
||||
}
|
||||
event.preventDefault()
|
||||
},
|
||||
zoomAuto(event) {
|
||||
@@ -144,6 +178,7 @@ export default {
|
||||
default:
|
||||
case 4:
|
||||
this.scale = 1
|
||||
this.setCenter()
|
||||
break
|
||||
}
|
||||
this.setZoom()
|
||||
|
||||
@@ -1,453 +0,0 @@
|
||||
<template>
|
||||
<div v-if="(req.numDirs + req.numFiles) == 0">
|
||||
<h2 class="message">
|
||||
<i class="material-icons">sentiment_dissatisfied</i>
|
||||
<span>{{ $t('files.lonely') }}</span>
|
||||
</h2>
|
||||
<input style="display:none" type="file" id="upload-input" @change="uploadInput($event)" multiple>
|
||||
<input style="display:none" type="file" id="upload-folder-input" @change="uploadInput($event)" webkitdirectory multiple>
|
||||
</div>
|
||||
<div v-else id="listing"
|
||||
:class="user.viewMode"
|
||||
@dragenter="dragEnter"
|
||||
@dragend="dragEnd">
|
||||
<div>
|
||||
<div class="item header">
|
||||
<div></div>
|
||||
<div>
|
||||
<p :class="{ active: nameSorted }" class="name"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('name')"
|
||||
:title="$t('files.sortByName')"
|
||||
:aria-label="$t('files.sortByName')">
|
||||
<span>{{ $t('files.name') }}</span>
|
||||
<i class="material-icons">{{ nameIcon }}</i>
|
||||
</p>
|
||||
|
||||
<p :class="{ active: sizeSorted }" class="size"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('size')"
|
||||
:title="$t('files.sortBySize')"
|
||||
:aria-label="$t('files.sortBySize')">
|
||||
<span>{{ $t('files.size') }}</span>
|
||||
<i class="material-icons">{{ sizeIcon }}</i>
|
||||
</p>
|
||||
<p :class="{ active: modifiedSorted }" class="modified"
|
||||
role="button"
|
||||
tabindex="0"
|
||||
@click="sort('modified')"
|
||||
:title="$t('files.sortByLastModified')"
|
||||
:aria-label="$t('files.sortByLastModified')">
|
||||
<span>{{ $t('files.lastModified') }}</span>
|
||||
<i class="material-icons">{{ modifiedIcon }}</i>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h2 v-if="req.numDirs > 0">{{ $t('files.folders') }}</h2>
|
||||
<div v-if="req.numDirs > 0">
|
||||
<item v-for="(item) in dirs"
|
||||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
v-bind:type="item.type"
|
||||
v-bind:size="item.size">
|
||||
</item>
|
||||
</div>
|
||||
|
||||
<h2 v-if="req.numFiles > 0">{{ $t('files.files') }}</h2>
|
||||
<div v-if="req.numFiles > 0">
|
||||
<item v-for="(item) in files"
|
||||
:key="base64(item.name)"
|
||||
v-bind:index="item.index"
|
||||
v-bind:name="item.name"
|
||||
v-bind:isDir="item.isDir"
|
||||
v-bind:url="item.url"
|
||||
v-bind:modified="item.modified"
|
||||
v-bind:type="item.type"
|
||||
v-bind:size="item.size">
|
||||
</item>
|
||||
</div>
|
||||
|
||||
<input style="display:none" type="file" id="upload-input" @change="uploadInput($event)" multiple>
|
||||
<input style="display:none" type="file" id="upload-folder-input" @change="uploadInput($event)" webkitdirectory multiple>
|
||||
|
||||
<div :class="{ active: $store.state.multiple }" id="multiple-selection">
|
||||
<p>{{ $t('files.multipleSelectionEnabled') }}</p>
|
||||
<div @click="$store.commit('multiple', false)" tabindex="0" role="button" :title="$t('files.clear')" :aria-label="$t('files.clear')" class="action">
|
||||
<i class="material-icons">clear</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState, mapMutations } from 'vuex'
|
||||
import Item from './ListingItem'
|
||||
import css from '@/utils/css'
|
||||
import { users, files as api } from '@/api'
|
||||
import * as upload from '@/utils/upload'
|
||||
|
||||
export default {
|
||||
name: 'listing',
|
||||
components: { Item },
|
||||
data: function () {
|
||||
return {
|
||||
showLimit: 50
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['req', 'selected', 'user', 'show']),
|
||||
nameSorted () {
|
||||
return (this.req.sorting.by === 'name')
|
||||
},
|
||||
sizeSorted () {
|
||||
return (this.req.sorting.by === 'size')
|
||||
},
|
||||
modifiedSorted () {
|
||||
return (this.req.sorting.by === 'modified')
|
||||
},
|
||||
ascOrdered () {
|
||||
return this.req.sorting.asc
|
||||
},
|
||||
items () {
|
||||
const dirs = []
|
||||
const files = []
|
||||
|
||||
this.req.items.forEach((item) => {
|
||||
if (item.isDir) {
|
||||
dirs.push(item)
|
||||
} else {
|
||||
files.push(item)
|
||||
}
|
||||
})
|
||||
|
||||
return { dirs, files }
|
||||
},
|
||||
dirs () {
|
||||
return this.items.dirs.slice(0, this.showLimit)
|
||||
},
|
||||
files () {
|
||||
let showLimit = this.showLimit - this.items.dirs.length
|
||||
|
||||
if (showLimit < 0) showLimit = 0
|
||||
|
||||
return this.items.files.slice(0, showLimit)
|
||||
},
|
||||
nameIcon () {
|
||||
if (this.nameSorted && !this.ascOrdered) {
|
||||
return 'arrow_upward'
|
||||
}
|
||||
|
||||
return 'arrow_downward'
|
||||
},
|
||||
sizeIcon () {
|
||||
if (this.sizeSorted && this.ascOrdered) {
|
||||
return 'arrow_downward'
|
||||
}
|
||||
|
||||
return 'arrow_upward'
|
||||
},
|
||||
modifiedIcon () {
|
||||
if (this.modifiedSorted && this.ascOrdered) {
|
||||
return 'arrow_downward'
|
||||
}
|
||||
|
||||
return 'arrow_upward'
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
// Check the columns size for the first time.
|
||||
this.resizeEvent()
|
||||
|
||||
// Add the needed event listeners to the window and document.
|
||||
window.addEventListener('keydown', this.keyEvent)
|
||||
window.addEventListener('resize', this.resizeEvent)
|
||||
window.addEventListener('scroll', this.scrollEvent)
|
||||
document.addEventListener('dragover', this.preventDefault)
|
||||
document.addEventListener('drop', this.drop)
|
||||
},
|
||||
beforeDestroy () {
|
||||
// Remove event listeners before destroying this page.
|
||||
window.removeEventListener('keydown', this.keyEvent)
|
||||
window.removeEventListener('resize', this.resizeEvent)
|
||||
window.removeEventListener('scroll', this.scrollEvent)
|
||||
document.removeEventListener('dragover', this.preventDefault)
|
||||
document.removeEventListener('drop', this.drop)
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([ 'updateUser', 'addSelected' ]),
|
||||
base64: function (name) {
|
||||
return window.btoa(unescape(encodeURIComponent(name)))
|
||||
},
|
||||
keyEvent (event) {
|
||||
if (this.show !== null) {
|
||||
return
|
||||
}
|
||||
|
||||
if (!event.ctrlKey && !event.metaKey) {
|
||||
return
|
||||
}
|
||||
|
||||
let key = String.fromCharCode(event.which).toLowerCase()
|
||||
|
||||
switch (key) {
|
||||
case 'f':
|
||||
event.preventDefault()
|
||||
this.$store.commit('showHover', 'search')
|
||||
break
|
||||
case 'c':
|
||||
case 'x':
|
||||
this.copyCut(event, key)
|
||||
break
|
||||
case 'v':
|
||||
this.paste(event)
|
||||
break
|
||||
case 'a':
|
||||
event.preventDefault()
|
||||
for (let file of this.items.files) {
|
||||
if (this.$store.state.selected.indexOf(file.index) === -1) {
|
||||
this.addSelected(file.index)
|
||||
}
|
||||
}
|
||||
for (let dir of this.items.dirs) {
|
||||
if (this.$store.state.selected.indexOf(dir.index) === -1) {
|
||||
this.addSelected(dir.index)
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
},
|
||||
preventDefault (event) {
|
||||
// Wrapper around prevent default.
|
||||
event.preventDefault()
|
||||
},
|
||||
copyCut (event, key) {
|
||||
if (event.target.tagName.toLowerCase() === 'input') {
|
||||
return
|
||||
}
|
||||
|
||||
let items = []
|
||||
|
||||
for (let i of this.selected) {
|
||||
items.push({
|
||||
from: this.req.items[i].url,
|
||||
name: encodeURIComponent(this.req.items[i].name)
|
||||
})
|
||||
}
|
||||
|
||||
if (items.length == 0) {
|
||||
return
|
||||
}
|
||||
|
||||
this.$store.commit('updateClipboard', {
|
||||
key: key,
|
||||
items: items,
|
||||
path: this.$route.path
|
||||
})
|
||||
},
|
||||
paste (event) {
|
||||
if (event.target.tagName.toLowerCase() === 'input') {
|
||||
return
|
||||
}
|
||||
|
||||
let items = []
|
||||
|
||||
for (let item of this.$store.state.clipboard.items) {
|
||||
const from = item.from.endsWith('/') ? item.from.slice(0, -1) : item.from
|
||||
const to = this.$route.path + item.name
|
||||
items.push({ from, to, name: item.name })
|
||||
}
|
||||
|
||||
if (items.length === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
let action = (overwrite, rename) => {
|
||||
api.copy(items, overwrite, rename).then(() => {
|
||||
this.$store.commit('setReload', true)
|
||||
}).catch(this.$showError)
|
||||
}
|
||||
|
||||
if (this.$store.state.clipboard.key === 'x') {
|
||||
action = (overwrite, rename) => {
|
||||
api.move(items, overwrite, rename).then(() => {
|
||||
this.$store.commit('resetClipboard')
|
||||
this.$store.commit('setReload', true)
|
||||
}).catch(this.$showError)
|
||||
}
|
||||
}
|
||||
|
||||
if (this.$store.state.clipboard.path == this.$route.path) {
|
||||
action(false, true)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
let conflict = upload.checkConflict(items, this.req.items)
|
||||
|
||||
let overwrite = false
|
||||
let rename = false
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit('showHover', {
|
||||
prompt: 'replace-rename',
|
||||
confirm: (event, option) => {
|
||||
overwrite = option == 'overwrite'
|
||||
rename = option == 'rename'
|
||||
|
||||
event.preventDefault()
|
||||
this.$store.commit('closeHovers')
|
||||
action(overwrite, rename)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
action(overwrite, rename)
|
||||
},
|
||||
resizeEvent () {
|
||||
// Update the columns size based on the window width.
|
||||
let columns = Math.floor(document.querySelector('main').offsetWidth / 300)
|
||||
let items = css(['#listing.mosaic .item', '.mosaic#listing .item'])
|
||||
if (columns === 0) columns = 1
|
||||
items.style.width = `calc(${100 / columns}% - 1em)`
|
||||
},
|
||||
scrollEvent () {
|
||||
if ((window.innerHeight + window.scrollY) >= document.body.offsetHeight) {
|
||||
this.showLimit += 50
|
||||
}
|
||||
},
|
||||
dragEnter () {
|
||||
// When the user starts dragging an item, put every
|
||||
// file on the listing with 50% opacity.
|
||||
let items = document.getElementsByClassName('item')
|
||||
|
||||
Array.from(items).forEach(file => {
|
||||
file.style.opacity = 0.5
|
||||
})
|
||||
},
|
||||
dragEnd () {
|
||||
this.resetOpacity()
|
||||
},
|
||||
drop: async function (event) {
|
||||
event.preventDefault()
|
||||
this.resetOpacity()
|
||||
|
||||
let dt = event.dataTransfer
|
||||
let el = event.target
|
||||
|
||||
if (dt.files.length <= 0) return
|
||||
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (el !== null && !el.classList.contains('item')) {
|
||||
el = el.parentElement
|
||||
}
|
||||
}
|
||||
|
||||
let base = ''
|
||||
if (el !== null && el.classList.contains('item') && el.dataset.dir === 'true') {
|
||||
base = el.querySelector('.name').innerHTML + '/'
|
||||
}
|
||||
|
||||
let files = await upload.scanFiles(dt)
|
||||
let path = this.$route.path + base
|
||||
let items = this.req.items
|
||||
|
||||
if (base !== '') {
|
||||
try {
|
||||
items = (await api.fetch(path)).items
|
||||
} catch (error) {
|
||||
this.$showError(error)
|
||||
}
|
||||
}
|
||||
|
||||
let conflict = upload.checkConflict(files, items)
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit('showHover', {
|
||||
prompt: 'replace',
|
||||
confirm: (event) => {
|
||||
event.preventDefault()
|
||||
this.$store.commit('closeHovers')
|
||||
upload.handleFiles(files, path, true)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
upload.handleFiles(files, path)
|
||||
},
|
||||
uploadInput (event) {
|
||||
this.$store.commit('closeHovers')
|
||||
|
||||
let files = event.currentTarget.files
|
||||
let folder_upload = files[0].webkitRelativePath !== undefined && files[0].webkitRelativePath !== ''
|
||||
|
||||
if (folder_upload) {
|
||||
for (let i = 0; i < files.length; i++) {
|
||||
let file = files[i]
|
||||
files[i].fullPath = file.webkitRelativePath
|
||||
}
|
||||
}
|
||||
|
||||
let path = this.$route.path
|
||||
let conflict = upload.checkConflict(files, this.req.items)
|
||||
|
||||
if (conflict) {
|
||||
this.$store.commit('showHover', {
|
||||
prompt: 'replace',
|
||||
confirm: (event) => {
|
||||
event.preventDefault()
|
||||
this.$store.commit('closeHovers')
|
||||
this.handleFiles(files, path, true)
|
||||
}
|
||||
})
|
||||
|
||||
return
|
||||
}
|
||||
upload.handleFiles(files, path)
|
||||
},
|
||||
resetOpacity () {
|
||||
let items = document.getElementsByClassName('item')
|
||||
|
||||
Array.from(items).forEach(file => {
|
||||
file.style.opacity = 1
|
||||
})
|
||||
},
|
||||
async sort (by) {
|
||||
let asc = false
|
||||
|
||||
if (by === 'name') {
|
||||
if (this.nameIcon === 'arrow_upward') {
|
||||
asc = true
|
||||
}
|
||||
} else if (by === 'size') {
|
||||
if (this.sizeIcon === 'arrow_upward') {
|
||||
asc = true
|
||||
}
|
||||
} else if (by === 'modified') {
|
||||
if (this.modifiedIcon === 'arrow_upward') {
|
||||
asc = true
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
await users.update({ id: this.user.id, sorting: { by, asc } }, ['sorting'])
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
|
||||
this.$store.commit('setReload', true)
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -6,14 +6,14 @@
|
||||
@dragstart="dragStart"
|
||||
@dragover="dragOver"
|
||||
@drop="drop"
|
||||
@click="click"
|
||||
@dblclick="open"
|
||||
@click="itemClick"
|
||||
@dblclick="dblclick"
|
||||
@touchstart="touchstart"
|
||||
:data-dir="isDir"
|
||||
:aria-label="name"
|
||||
:aria-selected="isSelected">
|
||||
<div>
|
||||
<img v-if="type==='image'" :src="thumbnailUrl">
|
||||
<img v-if="readOnly == undefined && type==='image' && isThumbsEnabled" v-lazy="thumbnailUrl">
|
||||
<i v-else class="material-icons">{{ icon }}</i>
|
||||
</div>
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { baseURL } from '@/utils/constants'
|
||||
import { baseURL, enableThumbs } from '@/utils/constants'
|
||||
import { mapMutations, mapGetters, mapState } from 'vuex'
|
||||
import filesize from 'filesize'
|
||||
import moment from 'moment'
|
||||
@@ -45,10 +45,13 @@ export default {
|
||||
touches: 0
|
||||
}
|
||||
},
|
||||
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index'],
|
||||
props: ['name', 'isDir', 'url', 'type', 'size', 'modified', 'index', 'readOnly'],
|
||||
computed: {
|
||||
...mapState(['selected', 'req', 'user', 'jwt']),
|
||||
...mapState(['user', 'selected', 'req', 'jwt']),
|
||||
...mapGetters(['selectedCount']),
|
||||
singleClick () {
|
||||
return this.readOnly == undefined && this.user.singleClick
|
||||
},
|
||||
isSelected () {
|
||||
return (this.selected.indexOf(this.index) !== -1)
|
||||
},
|
||||
@@ -60,10 +63,10 @@ export default {
|
||||
return 'insert_drive_file'
|
||||
},
|
||||
isDraggable () {
|
||||
return this.user.perm.rename
|
||||
return this.readOnly == undefined && this.user.perm.rename
|
||||
},
|
||||
canDrop () {
|
||||
if (!this.isDir) return false
|
||||
if (!this.isDir || this.readOnly !== undefined) return false
|
||||
|
||||
for (let i of this.selected) {
|
||||
if (this.req.items[i].url === this.url) {
|
||||
@@ -75,7 +78,14 @@ export default {
|
||||
},
|
||||
thumbnailUrl () {
|
||||
const path = this.url.replace(/^\/files\//, '')
|
||||
return `${baseURL}/api/preview/thumb/${path}?auth=${this.jwt}&inline=true`
|
||||
|
||||
// reload the image when the file is replaced
|
||||
const key = Date.parse(this.modified)
|
||||
|
||||
return `${baseURL}/api/preview/thumb/${path}?auth=${this.jwt}&inline=true&k=${key}`
|
||||
},
|
||||
isThumbsEnabled () {
|
||||
return enableThumbs
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
@@ -132,7 +142,7 @@ export default {
|
||||
to: this.url + this.req.items[i].name,
|
||||
name: this.req.items[i].name
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
let base = el.querySelector('.name').innerHTML + '/'
|
||||
let path = this.$route.path + base
|
||||
@@ -167,8 +177,12 @@ export default {
|
||||
|
||||
action(overwrite, rename)
|
||||
},
|
||||
itemClick: function(event) {
|
||||
if (this.singleClick && !this.$store.state.multiple) this.open()
|
||||
else this.click(event)
|
||||
},
|
||||
click: function (event) {
|
||||
if (this.selectedCount !== 0) event.preventDefault()
|
||||
if (!this.singleClick && this.selectedCount !== 0) event.preventDefault()
|
||||
if (this.$store.state.selected.indexOf(this.index) !== -1) {
|
||||
this.removeSelected(this.index)
|
||||
return
|
||||
@@ -195,9 +209,12 @@ export default {
|
||||
return
|
||||
}
|
||||
|
||||
if (!event.ctrlKey && !this.$store.state.multiple) this.resetSelected()
|
||||
if (!this.singleClick && !event.ctrlKey && !event.metaKey && !this.$store.state.multiple) this.resetSelected()
|
||||
this.addSelected(this.index)
|
||||
},
|
||||
dblclick: function () {
|
||||
if (!this.singleClick) this.open()
|
||||
},
|
||||
touchstart () {
|
||||
setTimeout(() => {
|
||||
this.touches = 0
|
||||
@@ -213,4 +230,4 @@ export default {
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</script>
|
||||
@@ -1,195 +0,0 @@
|
||||
<template>
|
||||
<div id="previewer">
|
||||
<div class="bar">
|
||||
<button @click="back" class="action" :title="$t('files.closePreview')" :aria-label="$t('files.closePreview')" id="close">
|
||||
<i class="material-icons">close</i>
|
||||
</button>
|
||||
|
||||
<div class="title">
|
||||
<span>{{ this.name }}</span>
|
||||
</div>
|
||||
|
||||
<rename-button :disabled="loading" v-if="user.perm.rename"></rename-button>
|
||||
<delete-button :disabled="loading" v-if="user.perm.delete"></delete-button>
|
||||
<download-button :disabled="loading" v-if="user.perm.download"></download-button>
|
||||
<info-button :disabled="loading"></info-button>
|
||||
</div>
|
||||
|
||||
<div class="loading" v-if="loading">
|
||||
<div class="spinner">
|
||||
<div class="bounce1"></div>
|
||||
<div class="bounce2"></div>
|
||||
<div class="bounce3"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button class="action" @click="prev" v-show="hasPrevious" :aria-label="$t('buttons.previous')" :title="$t('buttons.previous')">
|
||||
<i class="material-icons">chevron_left</i>
|
||||
</button>
|
||||
<button class="action" @click="next" v-show="hasNext" :aria-label="$t('buttons.next')" :title="$t('buttons.next')">
|
||||
<i class="material-icons">chevron_right</i>
|
||||
</button>
|
||||
|
||||
<template v-if="!loading">
|
||||
<div class="preview">
|
||||
<ExtendedImage v-if="req.type == 'image'" :src="raw"></ExtendedImage>
|
||||
<audio v-else-if="req.type == 'audio'" :src="raw" autoplay controls></audio>
|
||||
<video v-else-if="req.type == 'video'" :src="raw" autoplay controls>
|
||||
<track
|
||||
kind="captions"
|
||||
v-for="(sub, index) in subtitles"
|
||||
:key="index"
|
||||
:src="sub"
|
||||
:label="'Subtitle ' + index" :default="index === 0">
|
||||
Sorry, your browser doesn't support embedded videos,
|
||||
but don't worry, you can <a :href="download">download it</a>
|
||||
and watch it with your favorite video player!
|
||||
</video>
|
||||
<object v-else-if="req.extension == '.pdf'" class="pdf" :data="raw"></object>
|
||||
<a v-else-if="req.type == 'blob'" :href="download">
|
||||
<h2 class="message">{{ $t('buttons.download') }} <i class="material-icons">file_download</i></h2>
|
||||
</a>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapState } from 'vuex'
|
||||
import url from '@/utils/url'
|
||||
import { baseURL } from '@/utils/constants'
|
||||
import { files as api } from '@/api'
|
||||
import InfoButton from '@/components/buttons/Info'
|
||||
import DeleteButton from '@/components/buttons/Delete'
|
||||
import RenameButton from '@/components/buttons/Rename'
|
||||
import DownloadButton from '@/components/buttons/Download'
|
||||
import ExtendedImage from './ExtendedImage'
|
||||
|
||||
const mediaTypes = [
|
||||
"image",
|
||||
"video",
|
||||
"audio",
|
||||
"blob"
|
||||
]
|
||||
|
||||
export default {
|
||||
name: 'preview',
|
||||
components: {
|
||||
InfoButton,
|
||||
DeleteButton,
|
||||
RenameButton,
|
||||
DownloadButton,
|
||||
ExtendedImage
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
previousLink: '',
|
||||
nextLink: '',
|
||||
listing: null,
|
||||
name: '',
|
||||
subtitles: []
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState(['req', 'user', 'oldReq', 'jwt', 'loading']),
|
||||
hasPrevious () {
|
||||
return (this.previousLink !== '')
|
||||
},
|
||||
hasNext () {
|
||||
return (this.nextLink !== '')
|
||||
},
|
||||
download () {
|
||||
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`
|
||||
},
|
||||
previewUrl () {
|
||||
if (this.req.type === 'image') {
|
||||
return `${baseURL}/api/preview/big${this.req.path}?auth=${this.jwt}`
|
||||
}
|
||||
return `${baseURL}/api/raw${this.req.path}?auth=${this.jwt}`
|
||||
},
|
||||
raw () {
|
||||
return `${this.previewUrl}&inline=true`
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
$route: function () {
|
||||
this.updatePreview()
|
||||
}
|
||||
},
|
||||
async mounted () {
|
||||
window.addEventListener('keyup', this.key)
|
||||
this.$store.commit('setPreviewMode', true)
|
||||
this.listing = this.oldReq.items
|
||||
this.updatePreview()
|
||||
},
|
||||
beforeDestroy () {
|
||||
window.removeEventListener('keyup', this.key)
|
||||
this.$store.commit('setPreviewMode', false)
|
||||
},
|
||||
methods: {
|
||||
back () {
|
||||
this.$store.commit('setPreviewMode', false)
|
||||
let uri = url.removeLastDir(this.$route.path) + '/'
|
||||
this.$router.push({ path: uri })
|
||||
},
|
||||
prev () {
|
||||
this.$router.push({ path: this.previousLink })
|
||||
},
|
||||
next () {
|
||||
this.$router.push({ path: this.nextLink })
|
||||
},
|
||||
key (event) {
|
||||
event.preventDefault()
|
||||
|
||||
if (event.which === 13 || event.which === 39) { // right arrow
|
||||
if (this.hasNext) this.next()
|
||||
} else if (event.which === 37) { // left arrow
|
||||
if (this.hasPrevious) this.prev()
|
||||
}
|
||||
},
|
||||
async updatePreview () {
|
||||
if (this.req.subtitles) {
|
||||
this.subtitles = this.req.subtitles.map(sub => `${baseURL}/api/raw${sub}?auth=${this.jwt}&inline=true`)
|
||||
}
|
||||
|
||||
let dirs = this.$route.fullPath.split("/")
|
||||
this.name = decodeURIComponent(dirs[dirs.length - 1])
|
||||
|
||||
if (!this.listing) {
|
||||
try {
|
||||
const path = url.removeLastDir(this.$route.path)
|
||||
const res = await api.fetch(path)
|
||||
this.listing = res.items
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
}
|
||||
|
||||
this.previousLink = ''
|
||||
this.nextLink = ''
|
||||
|
||||
for (let i = 0; i < this.listing.length; i++) {
|
||||
if (this.listing[i].name !== this.name) {
|
||||
continue
|
||||
}
|
||||
|
||||
for (let j = i - 1; j >= 0; j--) {
|
||||
if (mediaTypes.includes(this.listing[j].type)) {
|
||||
this.previousLink = this.listing[j].url
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
for (let j = i + 1; j < this.listing.length; j++) {
|
||||
if (mediaTypes.includes(this.listing[j].type)) {
|
||||
this.nextLink = this.listing[j].url
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
32
frontend/src/components/header/Action.vue
Normal file
32
frontend/src/components/header/Action.vue
Normal file
@@ -0,0 +1,32 @@
|
||||
<template>
|
||||
<button @click="action" :aria-label="label" :title="label" class="action">
|
||||
<i class="material-icons">{{ icon }}</i>
|
||||
<span>{{ label }}</span>
|
||||
<span v-if="counter > 0" class="counter">{{ counter }}</span>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'action',
|
||||
props: [
|
||||
'icon',
|
||||
'label',
|
||||
'counter',
|
||||
'show'
|
||||
],
|
||||
methods: {
|
||||
action: function () {
|
||||
if (this.show) {
|
||||
this.$store.commit('showHover', this.show)
|
||||
}
|
||||
|
||||
this.$emit('action')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
47
frontend/src/components/header/HeaderBar.vue
Normal file
47
frontend/src/components/header/HeaderBar.vue
Normal file
@@ -0,0 +1,47 @@
|
||||
<template>
|
||||
<header>
|
||||
<img v-if="showLogo !== undefined" :src="logoURL" />
|
||||
<action v-if="showMenu !== undefined" class="menu-button" icon="menu" :label="$t('buttons.toggleSidebar')" @action="openSidebar()" />
|
||||
|
||||
<slot />
|
||||
|
||||
<div id="dropdown" :class="{ active: this.$store.state.show === 'more' }">
|
||||
<slot name="actions" />
|
||||
</div>
|
||||
|
||||
<action v-if="this.$slots.actions" id="more" icon="more_vert" :label="$t('buttons.more')" @action="$store.commit('showHover', 'more')" />
|
||||
|
||||
<div class="overlay" v-show="this.$store.state.show == 'more'" @click="$store.commit('closeHovers')" />
|
||||
</header>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { logoURL } from '@/utils/constants'
|
||||
|
||||
import Action from '@/components/header/Action'
|
||||
|
||||
export default {
|
||||
name: 'header-bar',
|
||||
props: [
|
||||
'showLogo',
|
||||
'showMenu',
|
||||
],
|
||||
components: {
|
||||
Action
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
logoURL
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
openSidebar () {
|
||||
this.$store.commit('showHover', 'sidebar')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
@@ -20,29 +20,31 @@
|
||||
<script>
|
||||
import {mapGetters, mapMutations, mapState} from 'vuex'
|
||||
import { files as api } from '@/api'
|
||||
import url from '@/utils/url'
|
||||
import buttons from '@/utils/buttons'
|
||||
|
||||
export default {
|
||||
name: 'delete',
|
||||
computed: {
|
||||
...mapGetters(['isListing', 'selectedCount']),
|
||||
...mapState(['req', 'selected'])
|
||||
...mapState(['req', 'selected', 'showConfirm'])
|
||||
},
|
||||
methods: {
|
||||
...mapMutations(['closeHovers']),
|
||||
submit: async function () {
|
||||
this.closeHovers()
|
||||
buttons.loading('delete')
|
||||
|
||||
try {
|
||||
if (!this.isListing) {
|
||||
await api.remove(this.$route.path)
|
||||
buttons.success('delete')
|
||||
this.$router.push({ path: url.removeLastDir(this.$route.path) + '/' })
|
||||
|
||||
this.showConfirm()
|
||||
this.closeHovers()
|
||||
return
|
||||
}
|
||||
|
||||
this.closeHovers()
|
||||
|
||||
if (this.selectedCount === 0) {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -7,43 +7,29 @@
|
||||
<div class="card-content">
|
||||
<p>{{ $t('prompts.downloadMessage') }}</p>
|
||||
|
||||
<button class="button button--block" @click="download('zip')" v-focus>zip</button>
|
||||
<button class="button button--block" @click="download('tar')" v-focus>tar</button>
|
||||
<button class="button button--block" @click="download('targz')" v-focus>tar.gz</button>
|
||||
<button class="button button--block" @click="download('tarbz2')" v-focus>tar.bz2</button>
|
||||
<button class="button button--block" @click="download('tarxz')" v-focus>tar.xz</button>
|
||||
<button class="button button--block" @click="download('tarlz4')" v-focus>tar.lz4</button>
|
||||
<button class="button button--block" @click="download('tarsz')" v-focus>tar.sz</button>
|
||||
<button v-for="(ext, format) in formats" :key="format" class="button button--block" @click="showConfirm(format)" v-focus>{{ ext }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters, mapState} from 'vuex'
|
||||
import { files as api } from '@/api'
|
||||
import { mapState } from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'download',
|
||||
computed: {
|
||||
...mapState(['selected', 'req']),
|
||||
...mapGetters(['selectedCount'])
|
||||
},
|
||||
methods: {
|
||||
download: function (format) {
|
||||
if (this.selectedCount === 0) {
|
||||
api.download(format, this.$route.path)
|
||||
} else {
|
||||
let files = []
|
||||
|
||||
for (let i of this.selected) {
|
||||
files.push(this.req.items[i].url)
|
||||
}
|
||||
|
||||
api.download(format, ...files)
|
||||
data: function () {
|
||||
return {
|
||||
formats: {
|
||||
zip: 'zip',
|
||||
tar: 'tar',
|
||||
targz: 'tar.gz',
|
||||
tarbz2: 'tar.bz2',
|
||||
tarxz: 'tar.xz',
|
||||
tarlz4: 'tar.lz4',
|
||||
tarsz: 'tar.sz'
|
||||
}
|
||||
|
||||
this.$store.commit('closeHovers')
|
||||
}
|
||||
}
|
||||
},
|
||||
computed: mapState(['showConfirm'])
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div>
|
||||
<ul class="file-list">
|
||||
<li @click="select"
|
||||
<li @click="itemClick"
|
||||
@touchstart="touchstart"
|
||||
@dblclick="next"
|
||||
role="button"
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapState([ 'req' ]),
|
||||
...mapState([ 'req', 'user' ]),
|
||||
nav () {
|
||||
return decodeURIComponent(this.current)
|
||||
}
|
||||
@@ -111,6 +111,10 @@ export default {
|
||||
this.next(event)
|
||||
}
|
||||
},
|
||||
itemClick: function (event) {
|
||||
if (this.user.singleClick) this.next(event)
|
||||
else this.select(event)
|
||||
},
|
||||
select: function (event) {
|
||||
// If the element is already selected, unselect it.
|
||||
if (this.selected === event.currentTarget.dataset.url) {
|
||||
|
||||
@@ -63,7 +63,7 @@ export default {
|
||||
return moment(this.req.modified).fromNow()
|
||||
}
|
||||
|
||||
return moment(this.req.items[this.selected[0]]).fromNow()
|
||||
return moment(this.req.items[this.selected[0]].modified).fromNow()
|
||||
},
|
||||
name: function () {
|
||||
return this.selectedCount === 0 ? this.req.name : this.req.items[this.selected[0]].name
|
||||
|
||||
@@ -19,6 +19,7 @@ import Replace from './Replace'
|
||||
import ReplaceRename from './ReplaceRename'
|
||||
import Share from './Share'
|
||||
import Upload from './Upload'
|
||||
import ShareDelete from './ShareDelete'
|
||||
import { mapState } from 'vuex'
|
||||
import buttons from '@/utils/buttons'
|
||||
|
||||
@@ -37,7 +38,8 @@ export default {
|
||||
Help,
|
||||
Replace,
|
||||
ReplaceRename,
|
||||
Upload
|
||||
Upload,
|
||||
ShareDelete
|
||||
},
|
||||
data: function () {
|
||||
return {
|
||||
@@ -91,7 +93,8 @@ export default {
|
||||
'replace',
|
||||
'replace-rename',
|
||||
'share',
|
||||
'upload'
|
||||
'upload',
|
||||
'share-delete'
|
||||
].indexOf(this.show) >= 0;
|
||||
|
||||
return matched && this.show || null;
|
||||
|
||||
@@ -1,59 +1,85 @@
|
||||
<template>
|
||||
<div class="card floating" id="share">
|
||||
<div class="card floating share__promt__card" id="share">
|
||||
<div class="card-title">
|
||||
<h2>{{ $t('buttons.share') }}</h2>
|
||||
</div>
|
||||
|
||||
<div class="card-content">
|
||||
<ul>
|
||||
<li v-if="!hasPermanent">
|
||||
<a @click="getPermalink" :aria-label="$t('buttons.permalink')">{{ $t('buttons.permalink') }}</a>
|
||||
</li>
|
||||
<template v-if="listing">
|
||||
<div class="card-content">
|
||||
<table>
|
||||
<tr>
|
||||
<th>#</th>
|
||||
<th>{{ $t('settings.shareDuration') }}</th>
|
||||
<th></th>
|
||||
<th></th>
|
||||
</tr>
|
||||
|
||||
<li v-for="link in links" :key="link.hash">
|
||||
<a :href="buildLink(link.hash)" target="_blank">
|
||||
<template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template>
|
||||
<template v-else>{{ $t('permanent') }}</template>
|
||||
</a>
|
||||
<tr v-for="link in links" :key="link.hash">
|
||||
<td>{{ link.hash }}</td>
|
||||
<td>
|
||||
<template v-if="link.expire !== 0">{{ humanTime(link.expire) }}</template>
|
||||
<template v-else>{{ $t('permanent') }}</template>
|
||||
</td>
|
||||
<td class="small">
|
||||
<button class="action copy-clipboard"
|
||||
:data-clipboard-text="buildLink(link.hash)"
|
||||
:aria-label="$t('buttons.copyToClipboard')"
|
||||
:title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button>
|
||||
</td>
|
||||
<td class="small">
|
||||
<button class="action"
|
||||
@click="deleteLink($event, link)"
|
||||
:aria-label="$t('buttons.delete')"
|
||||
:title="$t('buttons.delete')"><i class="material-icons">delete</i></button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<button class="action"
|
||||
@click="deleteLink($event, link)"
|
||||
:aria-label="$t('buttons.delete')"
|
||||
:title="$t('buttons.delete')"><i class="material-icons">delete</i></button>
|
||||
<div class="card-action">
|
||||
<button class="button button--flat button--grey"
|
||||
@click="$store.commit('closeHovers')"
|
||||
:aria-label="$t('buttons.close')"
|
||||
:title="$t('buttons.close')">{{ $t('buttons.close') }}</button>
|
||||
<button class="button button--flat button--blue"
|
||||
@click="() => switchListing()"
|
||||
:aria-label="$t('buttons.new')"
|
||||
:title="$t('buttons.new')">{{ $t('buttons.new') }}</button>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<button class="action copy-clipboard"
|
||||
:data-clipboard-text="buildLink(link.hash)"
|
||||
:aria-label="$t('buttons.copyToClipboard')"
|
||||
:title="$t('buttons.copyToClipboard')"><i class="material-icons">content_paste</i></button>
|
||||
</li>
|
||||
<template v-else>
|
||||
<div class="card-content">
|
||||
<p>{{ $t('settings.shareDuration') }}</p>
|
||||
<div class="input-group input">
|
||||
<input v-focus
|
||||
type="number"
|
||||
max="2147483647"
|
||||
min="1"
|
||||
@keyup.enter="submit"
|
||||
v-model.trim="time">
|
||||
<select class="right" v-model="unit" :aria-label="$t('time.unit')">
|
||||
<option value="seconds">{{ $t('time.seconds') }}</option>
|
||||
<option value="minutes">{{ $t('time.minutes') }}</option>
|
||||
<option value="hours">{{ $t('time.hours') }}</option>
|
||||
<option value="days">{{ $t('time.days') }}</option>
|
||||
</select>
|
||||
</div>
|
||||
<p>{{ $t('prompts.optionalPassword') }}</p>
|
||||
<input class="input input--block" type="password" v-model.trim="password">
|
||||
</div>
|
||||
|
||||
<li>
|
||||
<input v-focus
|
||||
type="number"
|
||||
max="2147483647"
|
||||
min="0"
|
||||
@keyup.enter="submit"
|
||||
v-model.trim="time">
|
||||
<select v-model="unit" :aria-label="$t('time.unit')">
|
||||
<option value="seconds">{{ $t('time.seconds') }}</option>
|
||||
<option value="minutes">{{ $t('time.minutes') }}</option>
|
||||
<option value="hours">{{ $t('time.hours') }}</option>
|
||||
<option value="days">{{ $t('time.days') }}</option>
|
||||
</select>
|
||||
<button class="action"
|
||||
@click="submit"
|
||||
:aria-label="$t('buttons.create')"
|
||||
:title="$t('buttons.create')"><i class="material-icons">add</i></button>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="card-action">
|
||||
<button class="button button--flat"
|
||||
@click="$store.commit('closeHovers')"
|
||||
:aria-label="$t('buttons.close')"
|
||||
:title="$t('buttons.close')">{{ $t('buttons.close') }}</button>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<button class="button button--flat button--grey"
|
||||
@click="() => switchListing()"
|
||||
:aria-label="$t('buttons.cancel')"
|
||||
:title="$t('buttons.cancel')">{{ $t('buttons.cancel') }}</button>
|
||||
<button class="button button--flat button--blue"
|
||||
@click="submit"
|
||||
:aria-label="$t('buttons.share')"
|
||||
:title="$t('buttons.share')">{{ $t('buttons.share') }}</button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -70,9 +96,10 @@ export default {
|
||||
return {
|
||||
time: '',
|
||||
unit: 'hours',
|
||||
hasPermanent: false,
|
||||
links: [],
|
||||
clip: null
|
||||
clip: null,
|
||||
password: '',
|
||||
listing: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
@@ -97,11 +124,8 @@ export default {
|
||||
this.links = links
|
||||
this.sort()
|
||||
|
||||
for (let link of this.links) {
|
||||
if (link.expire === 0) {
|
||||
this.hasPermanent = true
|
||||
break
|
||||
}
|
||||
if (this.links.length == 0) {
|
||||
this.listing = false
|
||||
}
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
@@ -118,22 +142,25 @@ export default {
|
||||
},
|
||||
methods: {
|
||||
submit: async function () {
|
||||
if (!this.time) return
|
||||
let isPermanent = !this.time || this.time == 0
|
||||
|
||||
try {
|
||||
const res = await api.create(this.url, this.time, this.unit)
|
||||
let res = null
|
||||
|
||||
if (isPermanent) {
|
||||
res = await api.create(this.url, this.password)
|
||||
} else {
|
||||
res = await api.create(this.url, this.password, this.time, this.unit)
|
||||
}
|
||||
|
||||
this.links.push(res)
|
||||
this.sort()
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
},
|
||||
getPermalink: async function () {
|
||||
try {
|
||||
const res = await api.create(this.url)
|
||||
this.links.push(res)
|
||||
this.sort()
|
||||
this.hasPermanent = true
|
||||
|
||||
this.time = ''
|
||||
this.unit = 'hours'
|
||||
this.password = ''
|
||||
|
||||
this.listing = true
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
@@ -142,8 +169,11 @@ export default {
|
||||
event.preventDefault()
|
||||
try {
|
||||
await api.remove(link.hash)
|
||||
if (link.expire === 0) this.hasPermanent = false
|
||||
this.links = this.links.filter(item => item.hash !== link.hash)
|
||||
|
||||
if (this.links.length == 0) {
|
||||
this.listing = false
|
||||
}
|
||||
} catch (e) {
|
||||
this.$showError(e)
|
||||
}
|
||||
@@ -160,6 +190,13 @@ export default {
|
||||
if (b.expire === 0) return 1
|
||||
return new Date(a.expire) - new Date(b.expire)
|
||||
})
|
||||
},
|
||||
switchListing () {
|
||||
if (this.links.length == 0 && !this.listing) {
|
||||
this.$store.commit('closeHovers')
|
||||
}
|
||||
|
||||
this.listing = !this.listing
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
33
frontend/src/components/prompts/ShareDelete.vue
Normal file
33
frontend/src/components/prompts/ShareDelete.vue
Normal file
@@ -0,0 +1,33 @@
|
||||
<template>
|
||||
<div class="card floating">
|
||||
<div class="card-content">
|
||||
<p>{{ $t('prompts.deleteMessageShare', {path: ''}) }}</p>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<button @click="$store.commit('closeHovers')"
|
||||
class="button button--flat button--grey"
|
||||
:aria-label="$t('buttons.cancel')"
|
||||
:title="$t('buttons.cancel')">{{ $t('buttons.cancel') }}</button>
|
||||
<button @click="submit"
|
||||
class="button button--flat button--red"
|
||||
:aria-label="$t('buttons.delete')"
|
||||
:title="$t('buttons.delete')">{{ $t('buttons.delete') }}</button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
|
||||
export default {
|
||||
name: 'share-delete',
|
||||
computed: {
|
||||
...mapState(['showConfirm'])
|
||||
},
|
||||
methods: {
|
||||
submit: function () {
|
||||
this.showConfirm()
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -27,9 +27,11 @@ export default {
|
||||
name: 'upload',
|
||||
methods: {
|
||||
uploadFile: function () {
|
||||
document.getElementById('upload-input').value = ''
|
||||
document.getElementById('upload-input').click()
|
||||
},
|
||||
uploadFolder: function () {
|
||||
document.getElementById('upload-folder-input').value = ''
|
||||
document.getElementById('upload-folder-input').click()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,11 @@ export default {
|
||||
return this.commands.join(' ')
|
||||
},
|
||||
set (value) {
|
||||
this.$emit('update:commands', value.split(' '))
|
||||
if (value !== '') {
|
||||
this.$emit('update:commands', value.split(' '))
|
||||
} else {
|
||||
this.$emit('update:commands', [])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,13 +9,14 @@
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.delete"> {{ $t('settings.perm.delete') }}</p>
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.download"> {{ $t('settings.perm.download') }}</p>
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.modify"> {{ $t('settings.perm.modify') }}</p>
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.execute"> {{ $t('settings.perm.execute') }}</p>
|
||||
<p v-if="isExecEnabled"><input type="checkbox" :disabled="admin" v-model="perm.execute"> {{ $t('settings.perm.execute') }}</p>
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.rename"> {{ $t('settings.perm.rename') }}</p>
|
||||
<p><input type="checkbox" :disabled="admin" v-model="perm.share"> {{ $t('settings.perm.share') }}</p>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { enableExec } from '@/utils/constants'
|
||||
export default {
|
||||
name: 'permissions',
|
||||
props: ['perm'],
|
||||
@@ -33,7 +34,8 @@ export default {
|
||||
|
||||
this.perm.admin = value
|
||||
}
|
||||
}
|
||||
},
|
||||
isExecEnabled: () => enableExec
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
</p>
|
||||
|
||||
<permissions :perm.sync="user.perm" />
|
||||
<commands :commands.sync="user.commands" />
|
||||
<commands v-if="isExecEnabled" :commands.sync="user.commands" />
|
||||
|
||||
<div v-if="!isDefault">
|
||||
<h3>{{ $t('settings.rules') }}</h3>
|
||||
@@ -40,6 +40,7 @@ import Languages from './Languages'
|
||||
import Rules from './Rules'
|
||||
import Permissions from './Permissions'
|
||||
import Commands from './Commands'
|
||||
import { enableExec } from '@/utils/constants'
|
||||
|
||||
export default {
|
||||
name: 'user',
|
||||
@@ -53,7 +54,8 @@ export default {
|
||||
computed: {
|
||||
passwordPlaceholder () {
|
||||
return this.isNew ? '' : this.$t('settings.avoidChanges')
|
||||
}
|
||||
},
|
||||
isExecEnabled: () => enableExec
|
||||
},
|
||||
watch: {
|
||||
'user.perm.admin': function () {
|
||||
|
||||
@@ -1,29 +1,73 @@
|
||||
.share__box {
|
||||
text-align: center;
|
||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
background: #fff;
|
||||
display: block;
|
||||
border-radius: 0.2em;
|
||||
width: 90%;
|
||||
max-width: 25em;
|
||||
margin: 6em auto;
|
||||
.share {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.share__box__download {
|
||||
width: 100%;
|
||||
@media (max-width: 736px) {
|
||||
.share {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
.share__box {
|
||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
background: #fff;
|
||||
border-radius: 0.2em;
|
||||
margin: 5px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.share__box__header {
|
||||
padding: 1em;
|
||||
cursor: pointer;
|
||||
background: #ffffff;
|
||||
color: rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.share__box__icon i {
|
||||
font-size: 10em;
|
||||
color: #40c4ff;
|
||||
}
|
||||
|
||||
.share__box__center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.share__box__info {
|
||||
padding: 2em 3em;
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.share__box__title {
|
||||
margin-top: .2em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
.share__box__element {
|
||||
padding: 1em;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.share__box__items {
|
||||
text-align: left;
|
||||
flex: 10 0 25em;
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item {
|
||||
cursor: pointer;
|
||||
border-left: 0;
|
||||
border-right: 0;
|
||||
border-bottom: 0;
|
||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item .name {
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.share__box__items #listing.list .item .modified {
|
||||
width: 25%;
|
||||
}
|
||||
|
||||
.share__wrong__password {
|
||||
background: var(--red);
|
||||
color: #fff;
|
||||
padding: .5em;
|
||||
text-align: center;
|
||||
animation: .2s opac forwards;
|
||||
}
|
||||
@@ -83,29 +83,29 @@ main {
|
||||
width: calc(100% - 19em);
|
||||
}
|
||||
|
||||
#breadcrumbs {
|
||||
.breadcrumbs {
|
||||
height: 3em;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
#breadcrumbs span,
|
||||
#breadcrumbs {
|
||||
.breadcrumbs span,
|
||||
.breadcrumbs {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #6f6f6f;
|
||||
}
|
||||
|
||||
#breadcrumbs a {
|
||||
.breadcrumbs a {
|
||||
color: inherit;
|
||||
transition: .1s ease-in;
|
||||
border-radius: .125em;
|
||||
}
|
||||
|
||||
#breadcrumbs a:hover {
|
||||
.breadcrumbs a:hover {
|
||||
background-color: rgba(0,0,0, 0.05);
|
||||
}
|
||||
|
||||
#breadcrumbs span a {
|
||||
.breadcrumbs span a {
|
||||
padding: .2em;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,8 +1,29 @@
|
||||
.dashboard {
|
||||
max-width: 600px;
|
||||
margin: 1em 0;
|
||||
}
|
||||
|
||||
.dashboard .row {
|
||||
display: flex;
|
||||
margin: 0 -.5em;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.dashboard .row .column {
|
||||
display: flex;
|
||||
padding: 0 .5em;
|
||||
width: 50%;
|
||||
}
|
||||
|
||||
.dashboard .row .column .card {
|
||||
flex-grow: 1;
|
||||
}
|
||||
|
||||
@media(max-width: 1200px) {
|
||||
.dashboard .row .column {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
color: inherit
|
||||
}
|
||||
@@ -28,25 +49,56 @@ p code {
|
||||
}
|
||||
|
||||
.dashboard #nav {
|
||||
display: flex;
|
||||
padding-bottom: 1em;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.dashboard #nav .wrapper {
|
||||
display: flex;
|
||||
flex-grow: 1;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.dashboard #nav ul {
|
||||
list-style: none;
|
||||
display: flex;
|
||||
color: rgb(84, 110, 122);
|
||||
font-weight: 500;
|
||||
margin: 0 0 1em;
|
||||
padding: 0;
|
||||
margin: 0 0 -2px 0;
|
||||
font-size: .8em;
|
||||
text-align: center;
|
||||
justify-content: space-between;
|
||||
padding: 0;
|
||||
justify-content: left;
|
||||
}
|
||||
|
||||
.dashboard #nav li {
|
||||
.dashboard #nav ul li {
|
||||
position: relative;
|
||||
padding: 1.5em 2em;
|
||||
white-space: nowrap;
|
||||
border-bottom: 2px solid transparent;
|
||||
transition: .1s ease-in-out all;
|
||||
|
||||
}
|
||||
|
||||
.dashboard #nav ul li:hover {
|
||||
background: var(--moon-grey);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li.active {
|
||||
border-color: var(--blue);
|
||||
color: var(--blue);
|
||||
}
|
||||
|
||||
.dashboard #nav ul li.active::before {
|
||||
width: 100%;
|
||||
padding: 0 0 1em;
|
||||
border-bottom: 2px solid rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.dashboard #nav li.active {
|
||||
border-color: var(--blue)
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
content: "";
|
||||
background: var(--blue);
|
||||
opacity: 0.08;
|
||||
}
|
||||
|
||||
.dashboard #nav i {
|
||||
@@ -92,7 +144,7 @@ table tr>*:last-child {
|
||||
|
||||
.card {
|
||||
position: relative;
|
||||
margin: .5rem 0 1rem 0;
|
||||
margin: 0 0 1rem 0;
|
||||
background-color: #fff;
|
||||
border-radius: 2px;
|
||||
box-shadow: 0 2px 2px 0 rgba(0, 0, 0, 0.14), 0 1px 5px 0 rgba(0, 0, 0, 0.12), 0 3px 1px -2px rgba(0, 0, 0, 0.2);
|
||||
@@ -151,6 +203,7 @@ table tr>*:last-child {
|
||||
|
||||
.card .card-content.full {
|
||||
padding-bottom: 0;
|
||||
overflow: auto;
|
||||
}
|
||||
|
||||
.card h2 {
|
||||
@@ -226,6 +279,18 @@ table tr>*:last-child {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.card#share .input-group {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
.card#share .input-group * {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.card#share .input-group input {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.overlay {
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
position: fixed;
|
||||
|
||||
@@ -6,9 +6,25 @@ header {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 4em;
|
||||
width: 100%;
|
||||
padding: 0;
|
||||
display: flex;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header > * {
|
||||
flex: 0 0 auto;
|
||||
}
|
||||
|
||||
header title {
|
||||
display: block;
|
||||
flex: 1 1 auto;
|
||||
padding: 0 1em;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
header .overlay {
|
||||
@@ -30,17 +46,6 @@ header img {
|
||||
height: 2.5em;
|
||||
}
|
||||
|
||||
header>div:first-child>.action {
|
||||
display: none;
|
||||
}
|
||||
|
||||
header>div {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
padding: 0.5em 0.5em 0.5em 1em;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
header .action span {
|
||||
display: none;
|
||||
}
|
||||
@@ -50,19 +55,8 @@ header>div div {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
header>div:last-child div {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
header>div:first-child {
|
||||
height: 4em;
|
||||
}
|
||||
|
||||
header>div:last-child {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
header .search-button {
|
||||
header .search-button,
|
||||
header .menu-button {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@
|
||||
box-shadow: rgba(0, 0, 0, 0.06) 0px 1px 3px, rgba(0, 0, 0, 0.12) 0px 1px 2px;
|
||||
width: 95%;
|
||||
max-width: 20em;
|
||||
z-index: 1;
|
||||
}
|
||||
#file-selection .action {
|
||||
border-radius: 50%;
|
||||
@@ -81,6 +82,9 @@
|
||||
color: #6f6f6f;
|
||||
margin-right: auto;
|
||||
}
|
||||
#file-selection .action span {
|
||||
display: none;
|
||||
}
|
||||
nav {
|
||||
top: 0;
|
||||
z-index: 99999;
|
||||
@@ -95,7 +99,7 @@
|
||||
left: 0;
|
||||
}
|
||||
header .search-button,
|
||||
header>div:first-child>.action {
|
||||
header .menu-button {
|
||||
display: inherit;
|
||||
}
|
||||
header img {
|
||||
|
||||
@@ -96,10 +96,11 @@
|
||||
color: #fff;
|
||||
border-radius: 50%;
|
||||
font-size: .75em;
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
width: 1.8em;
|
||||
height: 1.8em;
|
||||
text-align: center;
|
||||
line-height: 1.25em;
|
||||
line-height: 1.55em;
|
||||
font-weight: bold;
|
||||
border: 2px solid white;
|
||||
}
|
||||
|
||||
@@ -117,40 +118,33 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#previewer .bar {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
height: 3.7em;
|
||||
}
|
||||
|
||||
#previewer .bar .title {
|
||||
margin-right: auto;
|
||||
padding: 0 1em;
|
||||
line-height: 2.7em;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
#previewer header {
|
||||
background: none;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#previewer .action i {
|
||||
#previewer header > .action i {
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
#previewer .action:hover {
|
||||
@media (min-width: 738px) {
|
||||
#previewer header #dropdown .action i {
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
|
||||
#previewer header .action:hover {
|
||||
background-color: rgba(255, 255, 255, 0.3)
|
||||
}
|
||||
|
||||
#previewer .action span {
|
||||
#previewer header .action span {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#previewer .preview {
|
||||
margin: 2em auto 4em;
|
||||
max-width: 80%;
|
||||
margin-top: 4em;
|
||||
text-align: center;
|
||||
height: calc(100vh - 9.7em);
|
||||
height: calc(100vh - 4em);
|
||||
}
|
||||
|
||||
#previewer .preview pre {
|
||||
@@ -165,6 +159,10 @@
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#previewer .preview video {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
#previewer .pdf {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -177,8 +175,25 @@
|
||||
#previewer>button {
|
||||
margin: 0;
|
||||
position: fixed;
|
||||
top: 50%;
|
||||
top: calc(50% + 1.85em);
|
||||
transform: translateY(-50%);
|
||||
background-color: rgba(80, 80, 80, .5);
|
||||
color: white;
|
||||
border-radius: 50%;
|
||||
cursor: pointer;
|
||||
border: 0;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
transition: 0.2s ease all;
|
||||
}
|
||||
|
||||
#previewer>button.hidden {
|
||||
opacity: 0;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
#previewer>button>i {
|
||||
padding: 0.4em;
|
||||
}
|
||||
|
||||
#previewer>button:first-of-type {
|
||||
@@ -194,6 +209,7 @@
|
||||
#editor-container {
|
||||
background-color: #fafafa;
|
||||
position: fixed;
|
||||
margin-top: 4em;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
@@ -201,47 +217,28 @@
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#editor-container .bar {
|
||||
width: 100%;
|
||||
text-align: right;
|
||||
display: flex;
|
||||
padding: 0.5em;
|
||||
height: 3.7em;
|
||||
background-color: #fff;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.075);
|
||||
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
#editor-container .title {
|
||||
margin-right: auto;
|
||||
padding: 0 1em;
|
||||
line-height: 2.7em;
|
||||
overflow: hidden;
|
||||
word-break: break-word;
|
||||
}
|
||||
|
||||
#previewer .title span {
|
||||
font-size: 1.2em;
|
||||
}
|
||||
|
||||
#previewer .loading {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#editor-container #editor {
|
||||
height: calc(100vh - 8.2em);
|
||||
height: calc(100vh - 8.4em);
|
||||
}
|
||||
|
||||
#editor-container #breadcrumbs {
|
||||
#editor-container .breadcrumbs {
|
||||
height: 2.3em;
|
||||
padding: 0 1em;
|
||||
}
|
||||
|
||||
#editor-container #breadcrumbs span {
|
||||
#editor-container .breadcrumbs span {
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
#editor-container .breadcrumbs i {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
/* * * * * * * * * * * * * * * *
|
||||
* PROMPT *
|
||||
* * * * * * * * * * * * * * * */
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "دائم",
|
||||
"buttons": {
|
||||
"shell": "Toggle shell",
|
||||
"cancel": "إلغاء",
|
||||
"close": "إغلاق",
|
||||
"copy": "نسخ",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "إنشاء",
|
||||
"delete": "حذف",
|
||||
"download": "تحميل",
|
||||
"hideDotfiles": "",
|
||||
"info": "معلومات",
|
||||
"more": "المزيد",
|
||||
"move": "نقل",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "جديد",
|
||||
"next": "التالي",
|
||||
"ok": "موافق",
|
||||
"replace": "استبدال",
|
||||
"permalink": "الحصول على لنك دائم",
|
||||
"previous": "السابق",
|
||||
"publish": "نشر",
|
||||
"rename": "إعادة تسمية",
|
||||
"replace": "استبدال",
|
||||
"reportIssue": "إبلاغ عن مشكلة",
|
||||
"save": "حفظ",
|
||||
"schedule": "جدولة",
|
||||
"search": "بحث",
|
||||
"select": "تحديد",
|
||||
"share": "مشاركة",
|
||||
"publish": "نشر",
|
||||
"selectMultiple": "تحديد متعدد",
|
||||
"schedule": "جدولة",
|
||||
"share": "مشاركة",
|
||||
"shell": "Toggle shell",
|
||||
"switchView": "تغيير العرض",
|
||||
"toggleSidebar": "تبديل الشريط الجانبي",
|
||||
"update": "تحديث",
|
||||
"upload": "رفع",
|
||||
"permalink": "الحصول على لنك دائم"
|
||||
"upload": "رفع"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "تم نسخ الملف"
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "You don't have permissions to access this.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "لا يمكن الوصول لهذا المحتوى."
|
||||
},
|
||||
"files": {
|
||||
"folders": "المجلدات",
|
||||
"files": "الملفات",
|
||||
"body": "الصفحة",
|
||||
"clear": "مسح",
|
||||
"closePreview": "إغلاق العرض",
|
||||
"files": "الملفات",
|
||||
"folders": "المجلدات",
|
||||
"home": "الصفحة الاولى",
|
||||
"lastModified": "آخر تعديل",
|
||||
"loading": "جاري التحميل...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "التحديد المتعدد مفعل",
|
||||
"name": "الإسم",
|
||||
"size": "الحجم",
|
||||
"sortByLastModified": "الترتيب بآخر تعديل",
|
||||
"sortByName": "الترتيب بالإسم",
|
||||
"sortBySize": "الترتيب بالحجم",
|
||||
"sortByLastModified": "الترتيب بآخر تعديل"
|
||||
"sortBySize": "الترتيب بالحجم"
|
||||
},
|
||||
"help": {
|
||||
"click": "حدد الملف أو المجلد",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "إعادة تسمية الملف",
|
||||
"help": "مساعدة"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "كلمة المرور",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"submit": "تسجيل دخول",
|
||||
"createAnAccount": "Create an account",
|
||||
"loginInstead": "Already have an account",
|
||||
"password": "كلمة المرور",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"passwordsDontMatch": "Passwords don't match",
|
||||
"usernameTaken": "Username already taken",
|
||||
"signup": "Signup",
|
||||
"submit": "تسجيل دخول",
|
||||
"username": "إسم المستخدم",
|
||||
"usernameTaken": "Username already taken",
|
||||
"wrongCredentials": "بيانات دخول خاطئة"
|
||||
},
|
||||
"permanent": "دائم",
|
||||
"prompts": {
|
||||
"copy": "نسخ",
|
||||
"copyMessage": "رجاء حدد المكان لنسخ ملفاتك فيه:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "آخر تعديل",
|
||||
"move": "نقل",
|
||||
"moveMessage": "إختر مكان جديد للملفات أو المجلدات المراد نقلها:",
|
||||
"newArchetype": "إنشاء منشور من المنشور الأصلي. الملف سيتم انشاءه في مجلد المحتويات.",
|
||||
"newDir": "مجلد جديد",
|
||||
"newDirMessage": "رجاء أدخل اسم المجلد الجديد.",
|
||||
"newFile": "ملف جديد",
|
||||
"newFileMessage": "رجاء ادخل اسم الملف الجديد.",
|
||||
"numberDirs": "عدد المجلدات",
|
||||
"numberFiles": "عدد الملفات",
|
||||
"replace": "إستبدال",
|
||||
"replaceMessage": "أحد الملفات التي تحاول رفعها يتعارض مع ملف موجود بنفس الإسم. هل تريد إستبدال الملف الموجود؟\n",
|
||||
"rename": "إعادة تسمية",
|
||||
"renameMessage": "إدراج اسم جديد لـ",
|
||||
"show": "عرض",
|
||||
"size": "الحجم",
|
||||
"replace": "إستبدال",
|
||||
"replaceMessage": "أحد الملفات التي تحاول رفعها يتعارض مع ملف موجود بنفس الإسم. هل تريد إستبدال الملف الموجود؟\n",
|
||||
"schedule": "جدولة",
|
||||
"scheduleMessage": "أختر الوقت والتاريخ لجدولة نشر هذا المقال.",
|
||||
"newArchetype": "إنشاء منشور من المنشور الأصلي. الملف سيتم انشاءه في مجلد المحتويات."
|
||||
"show": "عرض",
|
||||
"size": "الحجم",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "الصور",
|
||||
"music": "الموسيقى",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Press enter to search...",
|
||||
"search": "البحث...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"types": "الأنواع",
|
||||
"video": "فيديوهات"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instance name",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "documentation",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrator",
|
||||
"allowCommands": "تنفيذ الأوامر",
|
||||
"allowEdit": "تعديل، إعادة تسمية وحذف الملفات والمجلدات",
|
||||
"allowNew": "إنشاء ملفات ومجلدات جديدة",
|
||||
"allowPublish": "نشر مقالات وصفحات جديدة",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"avoidChanges": "(أتركه فارغاً إن لم ترد تغييره)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"changePassword": "تغيير كلمة المرور",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "تم تحديث الأوامر",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "ستايل مخصص",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"documentation": "documentation",
|
||||
"examples": "أمثلة",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "إعدادات عامة",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Insert the path",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "اللغة",
|
||||
"lockPassword": "منع المستخدم من تغيير كلمة المرور",
|
||||
"newPassword": "كلمة المرور الجديدة",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "مستخدم جديد",
|
||||
"password": "كلمة المرور",
|
||||
"passwordUpdated": "تم تغيير كلمة المرور",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"execute": "Execute commands",
|
||||
"modify": "Edit files",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
},
|
||||
"permissions": "الصلاحيات",
|
||||
"permissionsHelp": "يمكنك تعيين المستخدم كـ \"مدير\" أو تحديد الصلاحيات بشكل منفرد.\n إذا قمت بتحديد المستخدم كـ \"مدير\"، باقي الخيارات سيتم تحديدها تلقائياً.\n إدارة المستخدمين تبقى صلاحية فريدة للـ \"مدير\" فقط.\n",
|
||||
"profileSettings": "إعدادات الحساب",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "يمكنك هنا تحديد مجموعة من شروط السماح والمنع لهذا المستخدم. الملفات الممنوعة لن تظهر ضمن القائمة لهذا المستخدم ولن يستطيع الوصول لها. هنا ندعم الـ regex والـ relative path لنطاق المستخدمين.\n",
|
||||
"scope": "نطاق",
|
||||
"settingsUpdated": "تم تعديل الإعدادات",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "المستخدم",
|
||||
"userCommands": "الأوامر",
|
||||
"userCommandsHelp": "الأوامر المتاحة لهذا المستخدم مفصولة فيما بينها بمسافة. مثال:\n",
|
||||
"userCreated": "تم إنشاء المستخدم",
|
||||
"userDefaults": "User default settings",
|
||||
"userDeleted": "تم حذف المستخدم",
|
||||
"userManagement": "إدارة المستخدمين",
|
||||
"username": "إسم المستخدم",
|
||||
"users": "المستخدمين",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"insertPath": "Insert the path",
|
||||
"userUpdated": "تم تعديل المستخدم",
|
||||
"userDefaults": "User default settings",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"modify": "Edit files",
|
||||
"execute": "Execute commands",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
}
|
||||
"username": "إسم المستخدم",
|
||||
"users": "المستخدمين"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "مساعدة",
|
||||
"hugoNew": "هيوجو جديد",
|
||||
"login": "Login",
|
||||
"signup": "Signup",
|
||||
"logout": "تسجيل خروج",
|
||||
"myFiles": "ملفاتي",
|
||||
"newFile": "ملف جديد",
|
||||
"newFolder": "مجلد جديد",
|
||||
"preview": "معاينة",
|
||||
"settings": "الإعدادات",
|
||||
"siteSettings": "إعدادات الموقع",
|
||||
"hugoNew": "هيوجو جديد",
|
||||
"preview": "معاينة"
|
||||
"signup": "Signup",
|
||||
"siteSettings": "إعدادات الموقع"
|
||||
},
|
||||
"search": {
|
||||
"images": "الصور",
|
||||
"music": "الموسيقى",
|
||||
"pdf": "PDF",
|
||||
"types": "الأنواع",
|
||||
"video": "فيديوهات",
|
||||
"search": "البحث...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"pressToSearch": "Press enter to search..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "تم نسخ الملف"
|
||||
},
|
||||
"time": {
|
||||
"unit": "وحدة الوقت",
|
||||
"seconds": "ثواني",
|
||||
"minutes": "دقائق",
|
||||
"days": "أيام",
|
||||
"hours": "ساعات",
|
||||
"days": "أيام"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"minutes": "دقائق",
|
||||
"seconds": "ثواني",
|
||||
"unit": "وحدة الوقت"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanent",
|
||||
"buttons": {
|
||||
"shell": "Kommandozeile ein/ausschalten",
|
||||
"cancel": "Abbrechen",
|
||||
"close": "Schließen",
|
||||
"copy": "Kopieren",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Neu",
|
||||
"delete": "Löschen",
|
||||
"download": "Downloaden",
|
||||
"hideDotfiles": "",
|
||||
"info": "Info",
|
||||
"more": "mehr",
|
||||
"move": "Verschieben",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Neu",
|
||||
"next": "nächste",
|
||||
"ok": "OK",
|
||||
"replace": "Ersetzen",
|
||||
"permalink": "permanenten Verweis anzeigen",
|
||||
"previous": "vorherige",
|
||||
"publish": "Veröffentlichen",
|
||||
"rename": "umbenennen",
|
||||
"replace": "Ersetzen",
|
||||
"reportIssue": "Fehler melden",
|
||||
"save": "Speichern",
|
||||
"schedule": "Planung",
|
||||
"search": "Suchen",
|
||||
"select": "Auswählen",
|
||||
"share": "Teilen",
|
||||
"publish": "Veröffentlichen",
|
||||
"selectMultiple": "Mehrfachauswahl",
|
||||
"schedule": "Planung",
|
||||
"share": "Teilen",
|
||||
"shell": "Kommandozeile ein/ausschalten",
|
||||
"switchView": "Ansicht wechseln",
|
||||
"toggleSidebar": "Seitenleiste anzeigen",
|
||||
"update": "Update",
|
||||
"upload": "Upload",
|
||||
"permalink": "permanenten Verweis anzeigen"
|
||||
"upload": "Upload"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Verweis wurde kopiert!"
|
||||
"download": {
|
||||
"downloadFile": "Download Datei",
|
||||
"downloadFolder": "Download Ordner",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "Sie haben keine Berechtigung dies abzurufen.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "Dieser Ort kann nicht angezeigt werden."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Ordner",
|
||||
"files": "Dateien",
|
||||
"body": "Body",
|
||||
"clear": "Clear",
|
||||
"closePreview": "Vorschau schließen",
|
||||
"files": "Dateien",
|
||||
"folders": "Ordner",
|
||||
"home": "Home",
|
||||
"lastModified": "zuletzt verändert",
|
||||
"loading": "Lade...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "Mehrfachauswahl ausgewählt",
|
||||
"name": "Name",
|
||||
"size": "Größe",
|
||||
"sortByLastModified": "Nach Änderungsdatum sortieren",
|
||||
"sortByName": "Nach Namen sortieren",
|
||||
"sortBySize": "Nach Größe sortieren",
|
||||
"sortByLastModified": "Nach Änderungsdatum sortieren"
|
||||
"sortBySize": "Nach Größe sortieren"
|
||||
},
|
||||
"help": {
|
||||
"click": "wähle Datei oder Ordner",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "Datei umbenennen",
|
||||
"help": "Hilfe"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Passwort",
|
||||
"passwordConfirm": "Passwort Bestätigung",
|
||||
"submit": "Login",
|
||||
"createAnAccount": "Account erstellen",
|
||||
"loginInstead": "Account besteht bereits",
|
||||
"password": "Passwort",
|
||||
"passwordConfirm": "Passwort Bestätigung",
|
||||
"passwordsDontMatch": "Passwörter stimmen nicht überein",
|
||||
"usernameTaken": "Benutzername ist bereits vergeben",
|
||||
"signup": "Registrieren",
|
||||
"submit": "Login",
|
||||
"username": "Benutzername",
|
||||
"usernameTaken": "Benutzername ist bereits vergeben",
|
||||
"wrongCredentials": "Falsche Zugangsdaten"
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
"prompts": {
|
||||
"copy": "Kopieren",
|
||||
"copyMessage": "Wählen Sie einen Zielort zum Kopieren:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Zuletzt geändert",
|
||||
"move": "Verschieben",
|
||||
"moveMessage": "Wählen sie einen neuen Platz für ihre Datei(en)/Ordner:",
|
||||
"newArchetype": "Erstelle neuen Beitrag auf dem Archetyp. Ihre Datei wird im Inhalteordner erstellt.",
|
||||
"newDir": "Neuer Ordner",
|
||||
"newDirMessage": "Geben Sie den Namen des neuen Ordners an.",
|
||||
"newFile": "Neue Datei",
|
||||
"newFileMessage": "Geben Sie den Namen der neuen Datei an.",
|
||||
"numberDirs": "Anzahl der Ordner",
|
||||
"numberFiles": "Anzahl der Dateien",
|
||||
"replace": "Ersetzen",
|
||||
"replaceMessage": "Eine der Datei mit dem gleichen Namen, wie die Sie hochladen wollen, existiert bereits. Soll die vorhandene Datei ersetzt werden ?\n",
|
||||
"rename": "Umbenennen",
|
||||
"renameMessage": "Fügen Sie einen Namen ein für",
|
||||
"show": "Anzeigen",
|
||||
"size": "Größe",
|
||||
"replace": "Ersetzen",
|
||||
"replaceMessage": "Eine der Datei mit dem gleichen Namen, wie die Sie hochladen wollen, existiert bereits. Soll die vorhandene Datei ersetzt werden ?\n",
|
||||
"schedule": "Plan",
|
||||
"scheduleMessage": "Wählen Sie ein Datum und eine Zeit für die Veröffentlichung dieses Beitrags.",
|
||||
"newArchetype": "Erstelle neuen Beitrag auf dem Archetyp. Ihre Datei wird im Inhalteordner erstellt."
|
||||
"show": "Anzeigen",
|
||||
"size": "Größe",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Bilder",
|
||||
"music": "Musik",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Drücken sie Enter um zu suchen...",
|
||||
"search": "Suche...",
|
||||
"typeToSearch": "Tippe um zu suchen...",
|
||||
"types": "Typen",
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instanzname",
|
||||
"brandingDirectoryPath": "Markenverzeichnispfad",
|
||||
"documentation": "Dokumentation",
|
||||
"branding": "Marke",
|
||||
"disableExternalLinks": "Externe Links deaktivieren (außer Dokumentation)",
|
||||
"brandingHelp": "Sie können das Erscheinungsbild ihres File Browser anpassen, in dem sie den Namen ändern, das Logo austauchsen oder eigene Stile definieren und sogar externe Links zu GitHub deaktivieren.\nUm mehr Informationen zum Anpassen an ihre Marke zu bekommen, gehen sie bitte zu {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrator",
|
||||
"allowCommands": "Befehle ausführen",
|
||||
"allowEdit": "Bearbeiten, Umbenennen und Löschen von Dateien oder Ordnern",
|
||||
"allowNew": "Erstellen neuer Dateien und Ordner",
|
||||
"allowPublish": "Veröffentlichen von neuen Beiträgen und Seiten",
|
||||
"allowSignup": "Erlaube Benutzern sich zu registrieren",
|
||||
"avoidChanges": "(leer lassen um Änderungen zu vermeiden)",
|
||||
"branding": "Marke",
|
||||
"brandingDirectoryPath": "Markenverzeichnispfad",
|
||||
"brandingHelp": "Sie können das Erscheinungsbild ihres File Browser anpassen, in dem sie den Namen ändern, das Logo austauchsen oder eigene Stile definieren und sogar externe Links zu GitHub deaktivieren.\nUm mehr Informationen zum Anpassen an ihre Marke zu bekommen, gehen sie bitte zu {0}.",
|
||||
"changePassword": "Ändere das Passwort",
|
||||
"commandRunner": "Befehlseingabe",
|
||||
"commandRunnerHelp": "Hier könne sie Befehle eintragen die bei benannten Aktionen ausgeführt werden. Sie müssen pro Zeile jeweils einen 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 das {2}.",
|
||||
"commandsUpdated": "Befehle aktualisiert!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "Individuelles Stylesheet",
|
||||
"defaultUserDescription": "Das sind die Standard Einstellunge für Benutzer",
|
||||
"disableExternalLinks": "Externe Links deaktivieren (außer Dokumentation)",
|
||||
"documentation": "Dokumentation",
|
||||
"examples": "Beispiele",
|
||||
"executeOnShell": "In shell ausführen",
|
||||
"executeOnShellDescription": "Es ist voreingestellt das der File Brower Befehle ausführt in dem er die Befehlsdatein direkt auf ruft. Wenn sie wollen das sie auf einer Kommandozeile (wo Bash oder PowerShell) laufen, könne sie das hier definieren mit allen bennötigten Argumenten und Optionen. Wenn gesetzt, wird das Kommando das ausgeführt werden soll als Parameter angehängt. Das gilt für Benuzerkommandos sowie auch für Ereignisse.",
|
||||
"globalRules": "Das ist ein globales Set von Regeln die erlauben oder nicht erlauben. Die sind für alle Benutzer zutreffend. Es können spezielle Regeln in den Einstellungen der Benutzer definiert werden die diese übersteuern.",
|
||||
"globalSettings": "Globale Einstellungen",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Pfad einfügen",
|
||||
"insertRegex": "Regex Ausdruck einfügen",
|
||||
"instanceName": "Instanzname",
|
||||
"language": "Sprache",
|
||||
"lockPassword": "Verhindere, dass der Benutzer sein Passwort ändert",
|
||||
"newPassword": "Ihr neues Passwort.",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Neuer Benutzer",
|
||||
"password": "Passwort",
|
||||
"passwordUpdated": "Passwort aktualisiert!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Dateien und Ordner erstellen",
|
||||
"delete": "Dateien und Ordner löschen",
|
||||
"download": "Download",
|
||||
"execute": "Befehle ausführen",
|
||||
"modify": "Dateien editieren",
|
||||
"rename": "Umbenennen oder Verschieben von Dateien oder Ordnern",
|
||||
"share": "Datei teilen"
|
||||
},
|
||||
"permissions": "Berechtigungen",
|
||||
"permissionsHelp": "Sie können einem Benutzer Administratorrechte einräumen oder die Berechtigunen individuell festlegen. Wenn Sie \"Administrator\" auswählen, werden alle anderen Rechte automatisch vergeben. Die Nutzerverwaltung kann nur durch einen Administrator erfolgen.\n",
|
||||
"profileSettings": "Profileinstellungen",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Hier können Sie erlaubte und verbotene Aktionen für einen einzelnen Benutzer festlegen. Bockierte Dateien werden nicht im Listing angezeigt und sind nicht erreichbar für den Nutzer. Wir unterstützen reguläre Ausdrücke (Regex) und Pfade die relativ zum Benutzerordner sind. \n",
|
||||
"scope": "Scope",
|
||||
"settingsUpdated": "Einstellungen aktualisiert!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Benutzer",
|
||||
"userCommands": "Befehle",
|
||||
"userCommandsHelp": "Eine Liste, mit einem Leerzeichen als Trennung, mit den für diesen Nutzer verfügbaren Befehlen. Example:\n",
|
||||
"userCreated": "Benutzer angelegt!",
|
||||
"userDefaults": "Benutzer Standard Einstellungen",
|
||||
"userDeleted": "Benutzer gelöscht!",
|
||||
"userManagement": "Benutzerverwaltung",
|
||||
"username": "Nutzername",
|
||||
"users": "Nutzer",
|
||||
"globalRules": "Das ist ein globales Set von Regeln die erlauben oder nicht erlauben. Die sind für alle Benutzer zutreffend. Es können spezielle Regeln in den Einstellungen der Benutzer definiert werden die diese übersteuern.",
|
||||
"allowSignup": "Erlaube Benutzern sich zu registrieren",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Regex Ausdruck einfügen",
|
||||
"insertPath": "Pfad einfügen",
|
||||
"userUpdated": "Benutzer aktualisiert!",
|
||||
"userDefaults": "Benutzer Standard Einstellungen",
|
||||
"defaultUserDescription": "Das sind die Standard Einstellunge für Benutzer",
|
||||
"executeOnShell": "In shell ausführen",
|
||||
"executeOnShellDescription": "Es ist voreingestellt das der File Brower Befehle ausführt in dem er die Befehlsdatein direkt auf ruft. Wenn sie wollen das sie auf einer Kommandozeile (wo Bash oder PowerShell) laufen, könne sie das hier definieren mit allen bennötigten Argumenten und Optionen. Wenn gesetzt, wird das Kommando das ausgeführt werden soll als Parameter angehängt. Das gilt für Benuzerkommandos sowie auch für Ereignisse.",
|
||||
"perm": {
|
||||
"create": "Dateien und Ordner erstellen",
|
||||
"delete": "Dateien und Ordner löschen",
|
||||
"download": "Download",
|
||||
"modify": "Dateien editieren",
|
||||
"execute": "Befehle ausführen",
|
||||
"rename": "Umbenennen oder Verschieben von Dateien oder Ordnern",
|
||||
"share": "Datei teilen"
|
||||
}
|
||||
"username": "Nutzername",
|
||||
"users": "Nutzer"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hilfe",
|
||||
"hugoNew": "Hugo Neu",
|
||||
"login": "Anmelden",
|
||||
"signup": "Registrieren",
|
||||
"logout": "Logout",
|
||||
"myFiles": "Meine Dateien",
|
||||
"newFile": "Neue Datei",
|
||||
"newFolder": "Neuer Ordner",
|
||||
"preview": "Vorschau",
|
||||
"settings": "Einstellungen",
|
||||
"siteSettings": "Seiteneinstellungen",
|
||||
"hugoNew": "Hugo Neu",
|
||||
"preview": "Vorschau"
|
||||
"signup": "Registrieren",
|
||||
"siteSettings": "Seiteneinstellungen"
|
||||
},
|
||||
"search": {
|
||||
"images": "Bilder",
|
||||
"music": "Musik",
|
||||
"pdf": "PDF",
|
||||
"types": "Typen",
|
||||
"video": "Video",
|
||||
"search": "Suche...",
|
||||
"typeToSearch": "Tippe um zu suchen...",
|
||||
"pressToSearch": "Drücken sie Enter um zu suchen..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "Verweis wurde kopiert!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Zeiteinheit",
|
||||
"seconds": "Sekunden",
|
||||
"minutes": "Minuten",
|
||||
"days": "Tage",
|
||||
"hours": "Stunden",
|
||||
"days": "Tage"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download Datei",
|
||||
"downloadFolder": "Download Ordner"
|
||||
"minutes": "Minuten",
|
||||
"seconds": "Sekunden",
|
||||
"unit": "Zeiteinheit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanent",
|
||||
"buttons": {
|
||||
"shell": "Toggle shell",
|
||||
"cancel": "Cancel",
|
||||
"close": "Close",
|
||||
"copy": "Copy",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Create",
|
||||
"delete": "Delete",
|
||||
"download": "Download",
|
||||
"hideDotfiles": "Hide dotfiles",
|
||||
"info": "Info",
|
||||
"more": "More",
|
||||
"move": "Move",
|
||||
@@ -17,25 +16,29 @@
|
||||
"new": "New",
|
||||
"next": "Next",
|
||||
"ok": "OK",
|
||||
"replace": "Replace",
|
||||
"permalink": "Get Permanent Link",
|
||||
"previous": "Previous",
|
||||
"publish": "Publish",
|
||||
"rename": "Rename",
|
||||
"replace": "Replace",
|
||||
"reportIssue": "Report Issue",
|
||||
"save": "Save",
|
||||
"schedule": "Schedule",
|
||||
"search": "Search",
|
||||
"select": "Select",
|
||||
"share": "Share",
|
||||
"publish": "Publish",
|
||||
"selectMultiple": "Select multiple",
|
||||
"schedule": "Schedule",
|
||||
"share": "Share",
|
||||
"shell": "Toggle shell",
|
||||
"submit": "Submit",
|
||||
"switchView": "Switch view",
|
||||
"toggleSidebar": "Toggle sidebar",
|
||||
"update": "Update",
|
||||
"upload": "Upload",
|
||||
"permalink": "Get Permanent Link"
|
||||
"upload": "Upload"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Link copied!"
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": "Download Selected"
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "You don't have permissions to access this.",
|
||||
@@ -43,11 +46,11 @@
|
||||
"notFound": "This location can't be reached."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Folders",
|
||||
"files": "Files",
|
||||
"body": "Body",
|
||||
"clear": "Clear",
|
||||
"closePreview": "Close preview",
|
||||
"files": "Files",
|
||||
"folders": "Folders",
|
||||
"home": "Home",
|
||||
"lastModified": "Last modified",
|
||||
"loading": "Loading...",
|
||||
@@ -56,9 +59,9 @@
|
||||
"multipleSelectionEnabled": "Multiple selection enabled",
|
||||
"name": "Name",
|
||||
"size": "Size",
|
||||
"sortByLastModified": "Sort by last modified",
|
||||
"sortByName": "Sort by name",
|
||||
"sortBySize": "Sort by size",
|
||||
"sortByLastModified": "Sort by last modified"
|
||||
"sortBySize": "Sort by size"
|
||||
},
|
||||
"help": {
|
||||
"click": "select file or directory",
|
||||
@@ -74,24 +77,46 @@
|
||||
"f2": "rename file",
|
||||
"help": "Help"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "Icelandic",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "Dutch (Belgium)",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "Romanian",
|
||||
"ru": "Русский",
|
||||
"svSE": "Swedish (Sweden)",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Password",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"submit": "Login",
|
||||
"createAnAccount": "Create an account",
|
||||
"loginInstead": "Already have an account",
|
||||
"password": "Password",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"passwordsDontMatch": "Passwords don't match",
|
||||
"usernameTaken": "Username already taken",
|
||||
"signup": "Signup",
|
||||
"submit": "Login",
|
||||
"username": "Username",
|
||||
"usernameTaken": "Username already taken",
|
||||
"wrongCredentials": "Wrong credentials"
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
"prompts": {
|
||||
"copy": "Copy",
|
||||
"copyMessage": "Choose the place to copy your files:",
|
||||
"currentlyNavigating": "Currently navigating on:",
|
||||
"deleteMessageMultiple": "Are you sure you want to delete {count} file(s)?",
|
||||
"deleteMessageSingle": "Are you sure you want to delete this file/folder?",
|
||||
"deleteMessageShare": "Are you sure you want to delete this share({path})?",
|
||||
"deleteTitle": "Delete files",
|
||||
"displayName": "Display Name:",
|
||||
"download": "Download files",
|
||||
@@ -102,50 +127,65 @@
|
||||
"lastModified": "Last Modified",
|
||||
"move": "Move",
|
||||
"moveMessage": "Choose new house for your file(s)/folder(s):",
|
||||
"newArchetype": "Create a new post based on an archetype. Your file will be created on content folder.",
|
||||
"newDir": "New directory",
|
||||
"newDirMessage": "Write the name of the new directory.",
|
||||
"newFile": "New file",
|
||||
"newFileMessage": "Write the name of the new file.",
|
||||
"numberDirs": "Number of directories",
|
||||
"numberFiles": "Number of files",
|
||||
"replace": "Replace",
|
||||
"replaceMessage": "One of the files you're trying to upload is conflicting because of its name. Do you wish to replace the existing one?\n",
|
||||
"rename": "Rename",
|
||||
"renameMessage": "Insert a new name for",
|
||||
"show": "Show",
|
||||
"size": "Size",
|
||||
"replace": "Replace",
|
||||
"replaceMessage": "One of the files you're trying to upload is conflicting because of its name. Do you wish to replace the existing one?\n",
|
||||
"schedule": "Schedule",
|
||||
"scheduleMessage": "Pick a date and time to schedule the publication of this post.",
|
||||
"newArchetype": "Create a new post based on an archetype. Your file will be created on content folder.",
|
||||
"show": "Show",
|
||||
"size": "Size",
|
||||
"upload": "Upload",
|
||||
"uploadMessage": "Select an option to upload."
|
||||
"uploadMessage": "Select an option to upload.",
|
||||
"optionalPassword": "Optional password"
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Music",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Press enter to search...",
|
||||
"search": "Search...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"types": "Types",
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"themes": {
|
||||
"title": "Theme",
|
||||
"light": "Light",
|
||||
"dark": "Dark"
|
||||
},
|
||||
"instanceName": "Instance name",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "documentation",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrator",
|
||||
"allowCommands": "Execute commands",
|
||||
"allowEdit": "Edit, rename and delete files or directories",
|
||||
"allowNew": "Create new files and directories",
|
||||
"allowPublish": "Publish new posts and pages",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"avoidChanges": "(leave blank to avoid changes)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"changePassword": "Change Password",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "Commands updated!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "Custom Stylesheet",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"documentation": "documentation",
|
||||
"examples": "Examples",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "Global Settings",
|
||||
"hideDotfiles": "Hide dotfiles",
|
||||
"insertPath": "Insert the path",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "Language",
|
||||
"lockPassword": "Prevent the user from changing the password",
|
||||
"newPassword": "Your new password",
|
||||
@@ -153,6 +193,16 @@
|
||||
"newUser": "New User",
|
||||
"password": "Password",
|
||||
"passwordUpdated": "Password updated!",
|
||||
"path": "Path",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"execute": "Execute commands",
|
||||
"modify": "Edit files",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
},
|
||||
"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",
|
||||
"profileSettings": "Profile Settings",
|
||||
@@ -162,86 +212,46 @@
|
||||
"rulesHelp": "Here you can define a set of allow and disallow rules for this specific user. The blocked files won't show up in the listings and they wont be accessible to the user. We support regex and paths relative to the users scope.\n",
|
||||
"scope": "Scope",
|
||||
"settingsUpdated": "Settings updated!",
|
||||
"shareDuration": "Share Duration",
|
||||
"shareManagement": "Share Management",
|
||||
"singleClick": "Use single clicks to open files and directories",
|
||||
"themes": {
|
||||
"dark": "Dark",
|
||||
"light": "Light",
|
||||
"title": "Theme"
|
||||
},
|
||||
"user": "User",
|
||||
"userCommands": "Commands",
|
||||
"userCommandsHelp": "A space separated list with the available commands for this user. Example:\n",
|
||||
"userCreated": "User created!",
|
||||
"userDefaults": "User default settings",
|
||||
"userDeleted": "User deleted!",
|
||||
"userManagement": "User Management",
|
||||
"username": "Username",
|
||||
"users": "Users",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"insertPath": "Insert the path",
|
||||
"userUpdated": "User updated!",
|
||||
"userDefaults": "User default settings",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"modify": "Edit files",
|
||||
"execute": "Execute commands",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
}
|
||||
"username": "Username",
|
||||
"users": "Users"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Help",
|
||||
"hugoNew": "Hugo New",
|
||||
"login": "Login",
|
||||
"signup": "Signup",
|
||||
"logout": "Logout",
|
||||
"myFiles": "My files",
|
||||
"newFile": "New file",
|
||||
"newFolder": "New folder",
|
||||
"preview": "Preview",
|
||||
"settings": "Settings",
|
||||
"siteSettings": "Site Settings",
|
||||
"hugoNew": "Hugo New",
|
||||
"preview": "Preview"
|
||||
"signup": "Signup",
|
||||
"siteSettings": "Site Settings"
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Music",
|
||||
"pdf": "PDF",
|
||||
"types": "Types",
|
||||
"video": "Video",
|
||||
"search": "Search...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"pressToSearch": "Press enter to search..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"is": "Icelandic",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어",
|
||||
"nlBE": "Dutch (Belgium)",
|
||||
"ro": "Romanian",
|
||||
"svSE": "Swedish (Sweden)"
|
||||
"success": {
|
||||
"linkCopied": "Link copied!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Time Unit",
|
||||
"seconds": "Seconds",
|
||||
"minutes": "Minutes",
|
||||
"days": "Days",
|
||||
"hours": "Hours",
|
||||
"days": "Days"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"minutes": "Minutes",
|
||||
"seconds": "Seconds",
|
||||
"unit": "Time Unit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanente",
|
||||
"buttons": {
|
||||
"shell": "Presiona Enter para buscar...",
|
||||
"cancel": "Cancelar",
|
||||
"close": "Cerrar",
|
||||
"copy": "Copiar",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Crear",
|
||||
"delete": "Borrar",
|
||||
"download": "Descargar",
|
||||
"hideDotfiles": "",
|
||||
"info": "Info",
|
||||
"more": "Más",
|
||||
"move": "Mover",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Nuevo",
|
||||
"next": "Siguiente",
|
||||
"ok": "OK",
|
||||
"replace": "Reemplazar",
|
||||
"permalink": "Link permanente",
|
||||
"previous": "Anterior",
|
||||
"publish": "Publicar",
|
||||
"rename": "Renombrar",
|
||||
"replace": "Reemplazar",
|
||||
"reportIssue": "Reportar problema",
|
||||
"save": "Guardar",
|
||||
"schedule": "Programar",
|
||||
"search": "Buscar",
|
||||
"select": "Seleccionar",
|
||||
"share": "Compartir",
|
||||
"publish": "Publicar",
|
||||
"selectMultiple": "Selección múltiple",
|
||||
"schedule": "Programar",
|
||||
"share": "Compartir",
|
||||
"shell": "Presiona Enter para buscar...",
|
||||
"switchView": "Cambiar vista",
|
||||
"toggleSidebar": "Mostrar/Ocultar menú",
|
||||
"update": "Actualizar",
|
||||
"upload": "Subir",
|
||||
"permalink": "Link permanente"
|
||||
"upload": "Subir"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "¡Link copiado!"
|
||||
"download": {
|
||||
"downloadFile": "Descargar fichero",
|
||||
"downloadFolder": "Descargar directorio",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "No tienes los permisos necesarios para acceder.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "No se puede acceder a este lugar."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Carpetas",
|
||||
"files": "Archivos",
|
||||
"body": "Cuerpo",
|
||||
"clear": "Limpiar",
|
||||
"closePreview": "Cerrar vista previa",
|
||||
"files": "Archivos",
|
||||
"folders": "Carpetas",
|
||||
"home": "Inicio",
|
||||
"lastModified": "Última modificación",
|
||||
"loading": "Cargando...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "Selección múltiple activada",
|
||||
"name": "Nombre",
|
||||
"size": "Tamaño",
|
||||
"sortByLastModified": "Ordenar por última modificación",
|
||||
"sortByName": "Ordenar por nombre",
|
||||
"sortBySize": "Ordenar por tamaño",
|
||||
"sortByLastModified": "Ordenar por última modificación"
|
||||
"sortBySize": "Ordenar por tamaño"
|
||||
},
|
||||
"help": {
|
||||
"click": "seleccionar archivo o carpeta",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "renombrar archivo",
|
||||
"help": "Ayuda"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Contraseña",
|
||||
"passwordConfirm": "Confirmación de contraseña",
|
||||
"submit": "Iniciar sesión",
|
||||
"createAnAccount": "Crear una cuenta",
|
||||
"loginInstead": "Usuario ya existente",
|
||||
"password": "Contraseña",
|
||||
"passwordConfirm": "Confirmación de contraseña",
|
||||
"passwordsDontMatch": "Las contraseñas no coinciden",
|
||||
"usernameTaken": "Nombre usuario no disponible",
|
||||
"signup": "Registrate",
|
||||
"submit": "Iniciar sesión",
|
||||
"username": "Usuario",
|
||||
"usernameTaken": "Nombre usuario no disponible",
|
||||
"wrongCredentials": "Usuario y/o contraseña incorrectos"
|
||||
},
|
||||
"permanent": "Permanente",
|
||||
"prompts": {
|
||||
"copy": "Copiar",
|
||||
"copyMessage": "Elige el lugar donde quieres copiar tus archivos:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Última modificación",
|
||||
"move": "Mover",
|
||||
"moveMessage": "Elige una nueva casa para tus archivo(s)/carpeta(s):",
|
||||
"newArchetype": "Crea un nuevo post basado en un arquetipo. Tu archivo será creado en la carpeta de contenido.",
|
||||
"newDir": "Nueva carpeta",
|
||||
"newDirMessage": "Escribe el nombre de la nueva carpeta.",
|
||||
"newFile": "Nuevo archivo",
|
||||
"newFileMessage": "Escribe el nombre del nuevo archivo.",
|
||||
"numberDirs": "Número de carpetas",
|
||||
"numberFiles": "Número de archivos",
|
||||
"replace": "Reemplazar",
|
||||
"replaceMessage": "Uno de los archivos ue intentas subir está creando conflicto por su nombre. ¿Quieres cambiar el nombre del ya existente?\n",
|
||||
"rename": "Renombrar",
|
||||
"renameMessage": "Escribe el nuevo nombre para",
|
||||
"show": "Mostrar",
|
||||
"size": "Tamaño",
|
||||
"replace": "Reemplazar",
|
||||
"replaceMessage": "Uno de los archivos ue intentas subir está creando conflicto por su nombre. ¿Quieres cambiar el nombre del ya existente?\n",
|
||||
"schedule": "Programar",
|
||||
"scheduleMessage": "Elige una hora y fecha para programar la publicación de este post.",
|
||||
"newArchetype": "Crea un nuevo post basado en un arquetipo. Tu archivo será creado en la carpeta de contenido."
|
||||
"show": "Mostrar",
|
||||
"size": "Tamaño",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Música",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Presiona enter para buscar...",
|
||||
"search": "Buscar...",
|
||||
"typeToSearch": "Escribe para realizar una busqueda...",
|
||||
"types": "Tipos",
|
||||
"video": "Vídeo"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Nombre de la instancia",
|
||||
"brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca",
|
||||
"documentation": "documentación",
|
||||
"branding": "Marca",
|
||||
"disableExternalLinks": "Deshabilitar enlaces externos (excepto documentación)",
|
||||
"brandingHelp": "Tú puedes personalizar como se ve tu instancia de FileBrowser cambiándole el nombre, reemplazando ellogo, agregar estilos personalizados e incluso deshabilitando loslinks externos que apuntan hacia GitHub. \nPara mayor información acerca de personalización de marca, por favor revisa el {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrador",
|
||||
"allowCommands": "Ejecutar comandos",
|
||||
"allowEdit": "Editar, renombrar y borrar archivos o carpetas",
|
||||
"allowNew": "Crear nuevos archivos y carpetas",
|
||||
"allowPublish": "Publicar nuevos posts y páginas",
|
||||
"allowSignup": "Permitir registro de usuarios",
|
||||
"avoidChanges": "(dejar en blanco para evitar cambios)",
|
||||
"branding": "Marca",
|
||||
"brandingDirectoryPath": "Ruta de la carpeta de personalizacion de marca",
|
||||
"brandingHelp": "Tú puedes personalizar como se ve tu instancia de FileBrowser cambiándole el nombre, reemplazando ellogo, agregar estilos personalizados e incluso deshabilitando loslinks externos que apuntan hacia GitHub. \nPara mayor información acerca de personalización de marca, por favor revisa el {0}.",
|
||||
"changePassword": "Cambiar contraseña",
|
||||
"commandRunner": "Executor de comandos",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "¡Comandos actualizados!",
|
||||
"createUserDir": "Crea automaticamente una carpeta de inicio cuando se agrega un usuario",
|
||||
"customStylesheet": "Modificar hoja de estilos",
|
||||
"defaultUserDescription": "Estas son las configuraciones por defecto para nuevos usuarios.",
|
||||
"disableExternalLinks": "Deshabilitar enlaces externos (excepto documentación)",
|
||||
"documentation": "documentación",
|
||||
"examples": "Ejemplos",
|
||||
"executeOnShell": "Ejecutar en la shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "Ajustes globales",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Introduce la ruta",
|
||||
"insertRegex": "Introducir expresión regular",
|
||||
"instanceName": "Nombre de la instancia",
|
||||
"language": "Idioma",
|
||||
"lockPassword": "Evitar que el usuario cambie la contraseña",
|
||||
"newPassword": "Tu nueva contraseña",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Nuevo usuario",
|
||||
"password": "Contraseña",
|
||||
"passwordUpdated": "¡Contraseña actualizada!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Crear ficheros y directorios",
|
||||
"delete": "Eliminar ficheros y directorios",
|
||||
"download": "Descargar",
|
||||
"execute": "Executar comandos",
|
||||
"modify": "Editar ficheros",
|
||||
"rename": "Renombrar o mover ficheros y directorios",
|
||||
"share": "Compartir ficheros"
|
||||
},
|
||||
"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",
|
||||
"profileSettings": "Ajustes del perfil",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Aquí puedes definir un conjunto de reglas de permisos para este usuario específico. Los archivos bloqueados no se mostrarán en las listas y no serán accesibles por el usuario. Puedes utilizar regex y rutas relativas a la raíz del usuario.\n",
|
||||
"scope": "Raíz",
|
||||
"settingsUpdated": "¡Ajustes actualizados!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Usuario",
|
||||
"userCommands": "Comandos",
|
||||
"userCommandsHelp": "Una lista separada por espacios con los comandos permitidos para este usuario. Ejemplo:\n",
|
||||
"userCreated": "¡Usuario creado!",
|
||||
"userDefaults": "Configuración de usuario por defecto",
|
||||
"userDeleted": "¡Usuario eliminado!",
|
||||
"userManagement": "Administración de usuarios",
|
||||
"username": "Usuario",
|
||||
"users": "Usuarios",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Permitir registro de usuarios",
|
||||
"createUserDir": "Crea automaticamente una carpeta de inicio cuando se agrega un usuario",
|
||||
"insertRegex": "Introducir expresión regular",
|
||||
"insertPath": "Introduce la ruta",
|
||||
"userUpdated": "¡Usuario actualizado!",
|
||||
"userDefaults": "Configuración de usuario por defecto",
|
||||
"defaultUserDescription": "Estas son las configuraciones por defecto para nuevos usuarios.",
|
||||
"executeOnShell": "Ejecutar en la shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Crear ficheros y directorios",
|
||||
"delete": "Eliminar ficheros y directorios",
|
||||
"download": "Descargar",
|
||||
"modify": "Editar ficheros",
|
||||
"execute": "Executar comandos",
|
||||
"rename": "Renombrar o mover ficheros y directorios",
|
||||
"share": "Compartir ficheros"
|
||||
}
|
||||
"username": "Usuario",
|
||||
"users": "Usuarios"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Ayuda",
|
||||
"hugoNew": "Nuevo Hugo",
|
||||
"login": "Iniciar sesión",
|
||||
"signup": "Registrate",
|
||||
"logout": "Cerrar sesión",
|
||||
"myFiles": "Mis archivos",
|
||||
"newFile": "Nuevo archivo",
|
||||
"newFolder": "Nueva carpeta",
|
||||
"preview": "Vista previa",
|
||||
"settings": "Ajustes",
|
||||
"siteSettings": "Ajustes del sitio",
|
||||
"hugoNew": "Nuevo Hugo",
|
||||
"preview": "Vista previa"
|
||||
"signup": "Registrate",
|
||||
"siteSettings": "Ajustes del sitio"
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Música",
|
||||
"pdf": "PDF",
|
||||
"types": "Tipos",
|
||||
"video": "Vídeo",
|
||||
"search": "Buscar...",
|
||||
"typeToSearch": "Escribe para realizar una busqueda...",
|
||||
"pressToSearch": "Presiona enter para buscar..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "¡Link copiado!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Unidad",
|
||||
"seconds": "Segundos",
|
||||
"minutes": "Minutos",
|
||||
"days": "Días",
|
||||
"hours": "Horas",
|
||||
"days": "Días"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Descargar fichero",
|
||||
"downloadFolder": "Descargar directorio"
|
||||
"minutes": "Minutos",
|
||||
"seconds": "Segundos",
|
||||
"unit": "Unidad"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanent",
|
||||
"buttons": {
|
||||
"shell": "Toggle shell",
|
||||
"cancel": "Annuler",
|
||||
"close": "Fermer",
|
||||
"copy": "Copier",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Créer",
|
||||
"delete": "Supprimer",
|
||||
"download": "Télécharger",
|
||||
"hideDotfiles": "",
|
||||
"info": "Info",
|
||||
"more": "Plus",
|
||||
"move": "Déplacer",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Nouveau",
|
||||
"next": "Suivant",
|
||||
"ok": "OK",
|
||||
"replace": "Remplacer",
|
||||
"permalink": "Obtenir un lien permanent",
|
||||
"previous": "Précédent",
|
||||
"publish": "Publier",
|
||||
"rename": "Renommer",
|
||||
"replace": "Remplacer",
|
||||
"reportIssue": "Rapport d'erreur",
|
||||
"save": "Enregistrer",
|
||||
"schedule": "Fixer la date",
|
||||
"search": "Chercher",
|
||||
"select": "Sélectionner",
|
||||
"share": "Partager",
|
||||
"publish": "Publier",
|
||||
"selectMultiple": "Sélection multiple",
|
||||
"schedule": "Fixer la date",
|
||||
"share": "Partager",
|
||||
"shell": "Toggle shell",
|
||||
"switchView": "Changer le mode d'affichage",
|
||||
"toggleSidebar": "Afficher/Masquer la barre latérale",
|
||||
"update": "Mettre à jour",
|
||||
"upload": "Importer",
|
||||
"permalink": "Obtenir un lien permanent"
|
||||
"upload": "Importer"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Link copied!"
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "You don't have permissions to access this.",
|
||||
@@ -43,22 +45,22 @@
|
||||
"notFound": "Impossible d'accéder à cet emplacement."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Dossiers",
|
||||
"files": "Fichiers",
|
||||
"body": "Corps",
|
||||
"clear": "Fermer",
|
||||
"closePreview": "Fermer la prévisualisation",
|
||||
"files": "Fichiers",
|
||||
"folders": "Dossiers",
|
||||
"home": "Accueil",
|
||||
"lastModified": "Dernière modification",
|
||||
"loading": "Chargement...",
|
||||
"lonely": "Il semble qu'il n'y ai rien par ici...",
|
||||
"lonely": "Il semble qu'il n'y ait rien par ici...",
|
||||
"metadata": "Metadonnées",
|
||||
"multipleSelectionEnabled": "Sélection multiple activée",
|
||||
"name": "Nom",
|
||||
"size": "Taille",
|
||||
"sortByLastModified": "Trier par date de dernière modification",
|
||||
"sortByName": "Trier par nom",
|
||||
"sortBySize": "Trier par taille",
|
||||
"sortByLastModified": "Trier par date de dernière modification"
|
||||
"sortBySize": "Trier par taille"
|
||||
},
|
||||
"help": {
|
||||
"click": "Sélectionner un élément",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "Renommer le fichier",
|
||||
"help": "Aide"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Mot de passe",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"submit": "Se connecter",
|
||||
"createAnAccount": "Create an account",
|
||||
"loginInstead": "Already have an account",
|
||||
"password": "Mot de passe",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"passwordsDontMatch": "Passwords don't match",
|
||||
"usernameTaken": "Username already taken",
|
||||
"signup": "Signup",
|
||||
"submit": "Se connecter",
|
||||
"username": "Utilisateur",
|
||||
"usernameTaken": "Username already taken",
|
||||
"wrongCredentials": "Identifiants incorrects !"
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
"prompts": {
|
||||
"copy": "Copier",
|
||||
"copyMessage": "Choisissez l'emplacement où copier la sélection :",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Dernière modification",
|
||||
"move": "Déplacer",
|
||||
"moveMessage": "Choisissez l'emplacement où déplacer la sélection :",
|
||||
"newArchetype": "Créer un nouveau post basé sur un archétype. Votre fichier sera créé dans le dossier de contenu.",
|
||||
"newDir": "Nouveau dossier",
|
||||
"newDirMessage": "Nom du nouveau dossier :",
|
||||
"newFile": "Nouveau fichier",
|
||||
"newFileMessage": "Nom du nouveau fichier :",
|
||||
"numberDirs": "Nombre de dossiers",
|
||||
"numberFiles": "Nombre de fichiers",
|
||||
"replace": "Remplacer",
|
||||
"replaceMessage": "Un des fichiers que vous êtes en train d'importer a le même nom qu'un autre déjà présent. Voulez-vous remplacer le fichier actuel par le nouveau ?\n",
|
||||
"rename": "Renommer",
|
||||
"renameMessage": "Nouveau nom pour",
|
||||
"show": "Montrer",
|
||||
"size": "Taille",
|
||||
"replace": "Remplacer",
|
||||
"replaceMessage": "Un des fichiers que vous êtes en train d'importer a le même nom qu'un autre déjà présent. Voulez-vous remplacer le fichier actuel par le nouveau ?\n",
|
||||
"schedule": "Fixer la date",
|
||||
"scheduleMessage": "Choisissez une date pour planifier la publication de ce post",
|
||||
"newArchetype": "Créer un nouveau post basé sur un archétype. Votre fichier sera créé dans le dossier de contenu."
|
||||
"show": "Montrer",
|
||||
"size": "Taille",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Musique",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Press enter to search...",
|
||||
"search": "Recherche en cours...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"types": "Types",
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instance name",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "documentation",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrateur",
|
||||
"allowCommands": "Exécuter des commandes",
|
||||
"allowEdit": "Editer, renommer et supprimer des fichiers ou des dossiers",
|
||||
"allowNew": "Créer de nouveaux fichiers et dossiers",
|
||||
"allowPublish": "Publier de nouveaux posts et pages",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"avoidChanges": "(Laisser vide pour conserver l'actuel)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"changePassword": "Modifier le mot de passe",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "Commandes mises à jour !",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "Feuille de style personnalisée",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"documentation": "documentation",
|
||||
"examples": "Exemples",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "Paramètres généraux",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Insert the path",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "Langue",
|
||||
"lockPassword": "Prevent the user from changing the password",
|
||||
"newPassword": "Votre nouveau mot de passe",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Nouvel Utilisateur",
|
||||
"password": "Mot de passe",
|
||||
"passwordUpdated": "Mot de passe mis à jour !",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"execute": "Execute commands",
|
||||
"modify": "Edit files",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
},
|
||||
"permissions": "Permissions",
|
||||
"permissionsHelp": "Vous pouvez définir l'utilisateur comme étant un administrateur ou encore choisir les permissions individuellement. Si vous sélectionnez \"Administrateur\", toutes les autres options seront automatiquement activées. La gestion des utilisateurs est un privilège que seul l'administrateur possède.\n",
|
||||
"profileSettings": "Paramètres du profil",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Vous pouvez définir ici un ensemble de règles pour cet utilisateur. Les fichiers bloqués ne seront pas affichés et ne seront pas accessibles par l'utilisateur. Les expressions régulières sont supportées et les chemins d'accès sont relatifs par rapport au dossier de l'utilisateur.\n",
|
||||
"scope": "Portée du dossier utilisateur",
|
||||
"settingsUpdated": "Les paramètres ont été mis à jour !",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Utilisateur",
|
||||
"userCommands": "Commandes",
|
||||
"userCommandsHelp": "Une liste séparée par des espaces des commandes permises pour l'utilisateur. Exemple :",
|
||||
"userCreated": "Utilisateur créé !",
|
||||
"userDefaults": "User default settings",
|
||||
"userDeleted": "Utilisateur supprimé !",
|
||||
"userManagement": "Gestion des utilisateurs",
|
||||
"username": "Nom d'utilisateur",
|
||||
"users": "Utilisateurs",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"insertPath": "Insert the path",
|
||||
"userUpdated": "Utilisateur mis à jour !",
|
||||
"userDefaults": "User default settings",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"modify": "Edit files",
|
||||
"execute": "Execute commands",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
}
|
||||
"username": "Nom d'utilisateur",
|
||||
"users": "Utilisateurs"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aide",
|
||||
"hugoNew": "Nouveau Hugo",
|
||||
"login": "Login",
|
||||
"signup": "Signup",
|
||||
"logout": "Se déconnecter",
|
||||
"myFiles": "Mes fichiers",
|
||||
"newFile": "Nouveau fichier",
|
||||
"newFolder": "Nouveau dossier",
|
||||
"preview": "Prévisualiser",
|
||||
"settings": "Paramètres",
|
||||
"siteSettings": "Paramètres du site",
|
||||
"hugoNew": "Nouveau Hugo",
|
||||
"preview": "Prévisualiser"
|
||||
"signup": "Signup",
|
||||
"siteSettings": "Paramètres du site"
|
||||
},
|
||||
"search": {
|
||||
"images": "Images",
|
||||
"music": "Musique",
|
||||
"pdf": "PDF",
|
||||
"types": "Types",
|
||||
"video": "Video",
|
||||
"search": "Recherche en cours...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"pressToSearch": "Press enter to search..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "Link copied!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Unité de temps",
|
||||
"seconds": "Secondes",
|
||||
"minutes": "Minutes",
|
||||
"days": "Jours",
|
||||
"hours": "Heures",
|
||||
"days": "Jours"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"minutes": "Minutes",
|
||||
"seconds": "Secondes",
|
||||
"unit": "Unité de temps"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,28 +77,39 @@ export function detectLocale () {
|
||||
return locale
|
||||
}
|
||||
|
||||
const removeEmpty = (obj) =>
|
||||
Object.keys(obj)
|
||||
.filter((k) => obj[k] !== null && obj[k] !== undefined && obj[k] !== '') // Remove undef. and null and empty.string.
|
||||
.reduce(
|
||||
(newObj, k) =>
|
||||
typeof obj[k] === 'object'
|
||||
? Object.assign(newObj, { [k]: removeEmpty(obj[k]) }) // Recurse.
|
||||
: Object.assign(newObj, { [k]: obj[k] }), // Copy value.
|
||||
{},
|
||||
);
|
||||
|
||||
const i18n = new VueI18n({
|
||||
locale: detectLocale(),
|
||||
fallbackLocale: 'en',
|
||||
messages: {
|
||||
'ar': ar,
|
||||
'de': de,
|
||||
'ar': removeEmpty(ar),
|
||||
'de': removeEmpty(de),
|
||||
'en': en,
|
||||
'es': es,
|
||||
'fr': fr,
|
||||
'is': is,
|
||||
'it': it,
|
||||
'ja': ja,
|
||||
'ko': ko,
|
||||
'nl-be': nlBE,
|
||||
'pl': pl,
|
||||
'pt-br': ptBR,
|
||||
'pt': pt,
|
||||
'ru': ru,
|
||||
'ro': ro,
|
||||
'sv-se': svSE,
|
||||
'zh-cn': zhCN,
|
||||
'zh-tw': zhTW
|
||||
'es': removeEmpty(es),
|
||||
'fr': removeEmpty(fr),
|
||||
'is': removeEmpty(is),
|
||||
'it': removeEmpty(it),
|
||||
'ja': removeEmpty(ja),
|
||||
'ko': removeEmpty(ko),
|
||||
'nl-be': removeEmpty(nlBE),
|
||||
'pl': removeEmpty(pl),
|
||||
'pt-br': removeEmpty(ptBR),
|
||||
'pt': removeEmpty(pt),
|
||||
'ru': removeEmpty(ru),
|
||||
'ro': removeEmpty(ro),
|
||||
'sv-se': removeEmpty(svSE),
|
||||
'zh-cn': removeEmpty(zhCN),
|
||||
'zh-tw': removeEmpty(zhTW)
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Varanlegt",
|
||||
"buttons": {
|
||||
"shell": "Sýna skipanaglugga",
|
||||
"cancel": "Hætta við",
|
||||
"close": "Loka",
|
||||
"copy": "Afrita",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Búa til",
|
||||
"delete": "Eyða",
|
||||
"download": "Sækja",
|
||||
"hideDotfiles": "",
|
||||
"info": "Upplýsingar",
|
||||
"more": "Meira",
|
||||
"move": "Færa",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Nýtt",
|
||||
"next": "Næsta",
|
||||
"ok": "OK",
|
||||
"replace": "Skipta út",
|
||||
"permalink": "Sækja fastan hlekk",
|
||||
"previous": "Fyrri",
|
||||
"publish": "Gefa út",
|
||||
"rename": "Endurnefna",
|
||||
"replace": "Skipta út",
|
||||
"reportIssue": "Tilkynna vandamál",
|
||||
"save": "Vista",
|
||||
"schedule": "Áætlun",
|
||||
"search": "Leita",
|
||||
"select": "Velja",
|
||||
"share": "Deila",
|
||||
"publish": "Gefa út",
|
||||
"selectMultiple": "Velja mörg",
|
||||
"schedule": "Áætlun",
|
||||
"share": "Deila",
|
||||
"shell": "Sýna skipanaglugga",
|
||||
"switchView": "Skipta um útlit",
|
||||
"toggleSidebar": "Sýna hliðarstiku",
|
||||
"update": "Vista",
|
||||
"upload": "Hlaða upp",
|
||||
"permalink": "Sækja fastan hlekk"
|
||||
"upload": "Hlaða upp"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Hlekkur afritaður!"
|
||||
"download": {
|
||||
"downloadFile": "Sækja skjal",
|
||||
"downloadFolder": "Sækja möppu",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "Þú hefur ekki aðgang að þessari síðu.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "Ekki er hægt að opna þessa síðu."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Möppur",
|
||||
"files": "Skjöl",
|
||||
"body": "Meginmál",
|
||||
"clear": "Hreinsa",
|
||||
"closePreview": "Loka forskoðun",
|
||||
"files": "Skjöl",
|
||||
"folders": "Möppur",
|
||||
"home": "Heim",
|
||||
"lastModified": "Seinast breytt",
|
||||
"loading": "Hleð...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "Hægt að velja mörg skjöl/möppur",
|
||||
"name": "Nafn",
|
||||
"size": "Stærð",
|
||||
"sortByLastModified": "Flokka eftir Seinast breytt",
|
||||
"sortByName": "Flokka eftir nafni",
|
||||
"sortBySize": "Flokka eftir stærð",
|
||||
"sortByLastModified": "Flokka eftir Seinast breytt"
|
||||
"sortBySize": "Flokka eftir stærð"
|
||||
},
|
||||
"help": {
|
||||
"click": "velja skjal eða möppu",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "endurnefna skjal",
|
||||
"help": "Hjálp"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Lykilorð",
|
||||
"passwordConfirm": "Staðfesting lykilorðs",
|
||||
"submit": "Innskráning",
|
||||
"createAnAccount": "Búa til nýjan aðgang",
|
||||
"loginInstead": "Þú ert þegar með aðgang",
|
||||
"password": "Lykilorð",
|
||||
"passwordConfirm": "Staðfesting lykilorðs",
|
||||
"passwordsDontMatch": "Lykilorð eru mismunandi",
|
||||
"usernameTaken": "Þetta norendanafn er þegar í notkun",
|
||||
"signup": "Nýskráning",
|
||||
"submit": "Innskráning",
|
||||
"username": "Notendanafn",
|
||||
"usernameTaken": "Þetta norendanafn er þegar í notkun",
|
||||
"wrongCredentials": "Rangar notendaupplýsingar"
|
||||
},
|
||||
"permanent": "Varanlegt",
|
||||
"prompts": {
|
||||
"copy": "Afrita",
|
||||
"copyMessage": "Veldu staðsetningu til að afrita gögn: ",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Seinast breytt",
|
||||
"move": "Færa",
|
||||
"moveMessage": "Velja nýtt hús fyrir skjöl/möppur:",
|
||||
"newArchetype": "Búðu til nýja færslu sem byggir á frumgerð. Skjalið verður búið til í content möppu. ",
|
||||
"newDir": "Ný mappa",
|
||||
"newDirMessage": "Hvað á mappan að heita?",
|
||||
"newFile": "Nýtt skjal",
|
||||
"newFileMessage": "Hvað á skjalið að heita?",
|
||||
"numberDirs": "Fjöldi mappa",
|
||||
"numberFiles": "Fjöldi skjala",
|
||||
"replace": "Skipta út",
|
||||
"replaceMessage": "Eitt af skjölunum sem þú ert að reyna að hlaða upp hefur sama nafn og annað skjal. Viltu skipta nýja skjalinu út fyrir það gamla?\n",
|
||||
"rename": "Endurnefna",
|
||||
"renameMessage": "Settu inn nýtt nafn fyrir",
|
||||
"show": "Sýna",
|
||||
"size": "Stærð",
|
||||
"replace": "Skipta út",
|
||||
"replaceMessage": "Eitt af skjölunum sem þú ert að reyna að hlaða upp hefur sama nafn og annað skjal. Viltu skipta nýja skjalinu út fyrir það gamla?\n",
|
||||
"schedule": "Áætlun",
|
||||
"scheduleMessage": "Veldu dagsetningu og tíma fyrir áætlaða útgáfu. ",
|
||||
"newArchetype": "Búðu til nýja færslu sem byggir á frumgerð. Skjalið verður búið til í content möppu. "
|
||||
"show": "Sýna",
|
||||
"size": "Stærð",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Myndir",
|
||||
"music": "Tónlist",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Ýttu á Enter til að leita...",
|
||||
"search": "Leita...",
|
||||
"typeToSearch": "Skrifaðu til að leita...",
|
||||
"types": "Skrárgerðir",
|
||||
"video": "Myndbönd"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Nafn tilviks",
|
||||
"brandingDirectoryPath": "Mappa fyrir branding-skjöl",
|
||||
"documentation": "leiðbeiningar",
|
||||
"branding": "Útlit",
|
||||
"disableExternalLinks": "Sýna ytri-hlekki (fyrir utan leiðbeiningar)",
|
||||
"brandingHelp": "Þú getur breytt því hvernig File Browser lítur út með því að breyta nafninu, setja inn nýtt lógó, búa til þína eigin stíla og tekið út GitHub-hlekki. \nTil að lesa meira um custom-branding, kíktu á {0}.",
|
||||
"admin": "Stjórnandi",
|
||||
"administrator": "Stjórnandi",
|
||||
"allowCommands": "Senda skipanir",
|
||||
"allowEdit": "Breyta, endurnefna og eyða skjölum eða möppum",
|
||||
"allowNew": "Búa til ný skjöl og möppur",
|
||||
"allowPublish": "Gefa út nýjar færslur og síður",
|
||||
"allowSignup": "Leyfa nýjum notendum að skrá sig",
|
||||
"avoidChanges": "(engar breytingar ef ekkert er skrifað)",
|
||||
"branding": "Útlit",
|
||||
"brandingDirectoryPath": "Mappa fyrir branding-skjöl",
|
||||
"brandingHelp": "Þú getur breytt því hvernig File Browser lítur út með því að breyta nafninu, setja inn nýtt lógó, búa til þína eigin stíla og tekið út GitHub-hlekki. \nTil að lesa meira um custom-branding, kíktu á {0}.",
|
||||
"changePassword": "Breyta lykilorði",
|
||||
"commandRunner": "Skipanagluggi",
|
||||
"commandRunnerHelp": "Hér geturðu sett inn skipanir sem eru keyrðar eftir því sem þú tilgreinir. Skrifaðu eina skipun í hverja línu. Umhverfisbreyturnar {0} og {1} verða aðgengilegar ({0} miðast við {1}). Til að lesa meira og sjá lista yfir þær skipanir sem eru í boði, vinsamlegast lestu {2}. ",
|
||||
"commandsUpdated": "Skipanastillingar vistaðar!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "Custom Stylesheet",
|
||||
"defaultUserDescription": "Þetta eru sjálfgefnar stillingar fyrir nýja notendur.",
|
||||
"disableExternalLinks": "Sýna ytri-hlekki (fyrir utan leiðbeiningar)",
|
||||
"documentation": "leiðbeiningar",
|
||||
"examples": "Dæmi",
|
||||
"executeOnShell": "Keyra í skel",
|
||||
"executeOnShellDescription": "Sjálfgefnar stillingar File Browser eru að keyra skipanir beint með því að sækja binaries. Ef þú villt keyra skipanir í skel (t.d. í Bash eða PowerShell), þá geturðu skilgreint það hér með nauðsynlegum arguments og flags. Ef þetta er stillt, þá verður skipuninni bætt fyrir aftan sem argument. Þetta gildir bæði um skipanir notenda og event hooks.",
|
||||
"globalRules": "Þetta eru sjálfgegnar aðgangsreglur. Þær gilda um alla notendur. Þú getur tilgreint sérstakar reglur í stillingum fyrir hvern notenda til að ógilda þessar reglur. ",
|
||||
"globalSettings": "Global stillingar",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Settu inn slóð",
|
||||
"insertRegex": "Setja inn reglulega segð",
|
||||
"instanceName": "Nafn tilviks",
|
||||
"language": "Tungumál",
|
||||
"lockPassword": "Koma í veg fyrir að notandi breyti lykilorðinu",
|
||||
"newPassword": "Nýja lykilorðið þitt",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Nýr notandi",
|
||||
"password": "Lykilorð",
|
||||
"passwordUpdated": "Lykilorð vistað!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Búa til sköl og möppur",
|
||||
"delete": "Eyða skjölum og möppum",
|
||||
"download": "Sækja",
|
||||
"execute": "Keyra skipanir",
|
||||
"modify": "Breyta skjölum",
|
||||
"rename": "Endurnefna eða færa skjöl og möppur",
|
||||
"share": "Deila skjölum"
|
||||
},
|
||||
"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",
|
||||
"profileSettings": "Stilla prófíl",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Hér getur þú skilgreint hvaða reglur gilda um notandann. Skjölin sem hann hefur ekki aðgang að eru óaðgengileg og hann sér þau ekki. Stuðst er við reglulegar segðir og slóðir sem miðast við sýn notandans. ",
|
||||
"scope": "Sýn notandans",
|
||||
"settingsUpdated": "Stillingar vistaðar!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Notandi",
|
||||
"userCommands": "Skipanir",
|
||||
"userCommandsHelp": "Listi þar sem gildum er skipt upp með bili og inniheldur tiltækar skipanir fyrir þennan notanda. Til dæmis:\n",
|
||||
"userCreated": "Notandi stofnaður!",
|
||||
"userDefaults": "Sjálfgefnar notendastillingar",
|
||||
"userDeleted": "Notanda eytt!",
|
||||
"userManagement": "Notendastýring",
|
||||
"username": "Notendanafn",
|
||||
"users": "Notendur",
|
||||
"globalRules": "Þetta eru sjálfgegnar aðgangsreglur. Þær gilda um alla notendur. Þú getur tilgreint sérstakar reglur í stillingum fyrir hvern notenda til að ógilda þessar reglur. ",
|
||||
"allowSignup": "Leyfa nýjum notendum að skrá sig",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Setja inn reglulega segð",
|
||||
"insertPath": "Settu inn slóð",
|
||||
"userUpdated": "Notandastillingar vistaðar!",
|
||||
"userDefaults": "Sjálfgefnar notendastillingar",
|
||||
"defaultUserDescription": "Þetta eru sjálfgefnar stillingar fyrir nýja notendur.",
|
||||
"executeOnShell": "Keyra í skel",
|
||||
"executeOnShellDescription": "Sjálfgefnar stillingar File Browser eru að keyra skipanir beint með því að sækja binaries. Ef þú villt keyra skipanir í skel (t.d. í Bash eða PowerShell), þá geturðu skilgreint það hér með nauðsynlegum arguments og flags. Ef þetta er stillt, þá verður skipuninni bætt fyrir aftan sem argument. Þetta gildir bæði um skipanir notenda og event hooks.",
|
||||
"perm": {
|
||||
"create": "Búa til sköl og möppur",
|
||||
"delete": "Eyða skjölum og möppum",
|
||||
"download": "Sækja",
|
||||
"modify": "Breyta skjölum",
|
||||
"execute": "Keyra skipanir",
|
||||
"rename": "Endurnefna eða færa skjöl og möppur",
|
||||
"share": "Deila skjölum"
|
||||
}
|
||||
"username": "Notendanafn",
|
||||
"users": "Notendur"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Hjálp",
|
||||
"hugoNew": "Hugo New",
|
||||
"login": "Innskráning",
|
||||
"signup": "Nýskráning",
|
||||
"logout": "Útskráning",
|
||||
"myFiles": "Gögnin mín",
|
||||
"newFile": "Nýtt skjal",
|
||||
"newFolder": "Ný mappa",
|
||||
"preview": "Sýnishorn",
|
||||
"settings": "Stillingar",
|
||||
"siteSettings": "Stillingar síðu",
|
||||
"hugoNew": "Hugo New",
|
||||
"preview": "Sýnishorn"
|
||||
"signup": "Nýskráning",
|
||||
"siteSettings": "Stillingar síðu"
|
||||
},
|
||||
"search": {
|
||||
"images": "Myndir",
|
||||
"music": "Tónlist",
|
||||
"pdf": "PDF",
|
||||
"types": "Skrárgerðir",
|
||||
"video": "Myndbönd",
|
||||
"search": "Leita...",
|
||||
"typeToSearch": "Skrifaðu til að leita...",
|
||||
"pressToSearch": "Ýttu á Enter til að leita..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "Hlekkur afritaður!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Tímastilling",
|
||||
"seconds": "Sekúndur",
|
||||
"minutes": "Mínútur",
|
||||
"days": "Dagar",
|
||||
"hours": "Klukkutímar",
|
||||
"days": "Dagar"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Sækja skjal",
|
||||
"downloadFolder": "Sækja möppu"
|
||||
"minutes": "Mínútur",
|
||||
"seconds": "Sekúndur",
|
||||
"unit": "Tímastilling"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanente",
|
||||
"buttons": {
|
||||
"shell": "Toggle shell",
|
||||
"cancel": "Annulla",
|
||||
"close": "Chiudi",
|
||||
"copy": "Copia",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Crea",
|
||||
"delete": "Elimina",
|
||||
"download": "Scarica",
|
||||
"hideDotfiles": "",
|
||||
"info": "Informazioni",
|
||||
"more": "Altro",
|
||||
"move": "Sposta",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Nuovo",
|
||||
"next": "Successivo",
|
||||
"ok": "OK",
|
||||
"replace": "Sostituisci",
|
||||
"permalink": "Ottieni link permanente",
|
||||
"previous": "Precedente",
|
||||
"publish": "Publica",
|
||||
"rename": "Rinomina",
|
||||
"replace": "Sostituisci",
|
||||
"reportIssue": "Segnala un problema",
|
||||
"save": "Salva",
|
||||
"schedule": "Programma",
|
||||
"search": "Cerca",
|
||||
"select": "Seleziona",
|
||||
"share": "Condividi",
|
||||
"publish": "Publica",
|
||||
"selectMultiple": "Seleziona molteplici",
|
||||
"schedule": "Programma",
|
||||
"share": "Condividi",
|
||||
"shell": "Toggle shell",
|
||||
"switchView": "Cambia vista",
|
||||
"toggleSidebar": "Mostra/nascondi la barra laterale",
|
||||
"update": "Aggiorna",
|
||||
"upload": "Carica",
|
||||
"permalink": "Ottieni link permanente"
|
||||
"upload": "Carica"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Link copiato!"
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "You don't have permissions to access this.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "Questo percorso non può essere raggiunto."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Cartelle",
|
||||
"files": "Files",
|
||||
"body": "Contenuto",
|
||||
"clear": "Cancella",
|
||||
"closePreview": "Chiudi anteprima",
|
||||
"files": "Files",
|
||||
"folders": "Cartelle",
|
||||
"home": "Home",
|
||||
"lastModified": "Ultima modifica",
|
||||
"loading": "Caricamento...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "Selezione multipla attivata",
|
||||
"name": "Nome",
|
||||
"size": "Grandezza",
|
||||
"sortByLastModified": "Ordina per ultima modifica",
|
||||
"sortByName": "Ordina per nome",
|
||||
"sortBySize": "Ordina per dimensione",
|
||||
"sortByLastModified": "Ordina per ultima modifica"
|
||||
"sortBySize": "Ordina per dimensione"
|
||||
},
|
||||
"help": {
|
||||
"click": "seleziona un file o una cartella",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "rinomina un file",
|
||||
"help": "Aiuto"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Password",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"submit": "Entra",
|
||||
"createAnAccount": "Create an account",
|
||||
"loginInstead": "Already have an account",
|
||||
"password": "Password",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"passwordsDontMatch": "Passwords don't match",
|
||||
"usernameTaken": "Username already taken",
|
||||
"signup": "Signup",
|
||||
"submit": "Entra",
|
||||
"username": "Nome utente",
|
||||
"usernameTaken": "Username already taken",
|
||||
"wrongCredentials": "Credenziali errate"
|
||||
},
|
||||
"permanent": "Permanente",
|
||||
"prompts": {
|
||||
"copy": "Copia",
|
||||
"copyMessage": "Seleziona la cartella in cui copiare i file:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Ultima modifica",
|
||||
"move": "Sposta",
|
||||
"moveMessage": "Seleziona la nuova posizione per i tuoi file e/o cartella/e:",
|
||||
"newArchetype": "Crea un nuovo post basato su un modello. Il tuo file verrà creato nella cartella.",
|
||||
"newDir": "Nuova cartella",
|
||||
"newDirMessage": "Scrivi il nome della nuova cartella.",
|
||||
"newFile": "Nuovo file",
|
||||
"newFileMessage": "Scrivi il nome del nuovo file.",
|
||||
"numberDirs": "Numero di cartelle",
|
||||
"numberFiles": "Numero di files",
|
||||
"replace": "Sostituisci",
|
||||
"replaceMessage": "Uno dei file che stai cercando di caricare sta generando un conflitto per via del suo nome. Desideri sostituire il file già esistente?\n",
|
||||
"rename": "Rinomina",
|
||||
"renameMessage": "Inserisci un nuovo nome per",
|
||||
"show": "Mostra",
|
||||
"size": "Grandezza",
|
||||
"replace": "Sostituisci",
|
||||
"replaceMessage": "Uno dei file che stai cercando di caricare sta generando un conflitto per via del suo nome. Desideri sostituire il file già esistente?\n",
|
||||
"schedule": "Pianifica",
|
||||
"scheduleMessage": "Seleziona data e ora per programmare la pubbilicazione di questo post",
|
||||
"newArchetype": "Crea un nuovo post basato su un modello. Il tuo file verrà creato nella cartella."
|
||||
"show": "Mostra",
|
||||
"size": "Grandezza",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Immagini",
|
||||
"music": "Musica",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Press enter to search...",
|
||||
"search": "Cerca...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"types": "Tipi",
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instance name",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "documentation",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Amministratore",
|
||||
"allowCommands": "Esegui comandi",
|
||||
"allowEdit": "Modifica, rinomina ed elimina file o cartelle",
|
||||
"allowNew": "Crea nuovi files o cartelle",
|
||||
"allowPublish": "Pubblica nuovi post e pagine",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"avoidChanges": "(lascia vuoto per evitare cambiamenti)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"changePassword": "Modifica password",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "Comandi aggiornati!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "Folgio di stile personalizzato",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"documentation": "documentation",
|
||||
"examples": "Esempi",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "Impostazioni Globali",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Insert the path",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "Lingua",
|
||||
"lockPassword": "Impedisci all'utente di modificare la password",
|
||||
"newPassword": "La tua nuova password",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Nuovo utente",
|
||||
"password": "Password",
|
||||
"passwordUpdated": "Password aggiornata!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"execute": "Execute commands",
|
||||
"modify": "Edit files",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
},
|
||||
"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",
|
||||
"profileSettings": "Impostazioni del profilo",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Qui è possibile definire una serie di regole e permessi per questo specifico utente. I file bloccati non appariranno negli elenchi e non saranno accessibili dagli utenti. all'utente. Sia regex che i percorsi relativi all'ambito di applicazione degli utenti sono supportati.\n",
|
||||
"scope": "Scopo",
|
||||
"settingsUpdated": "Impostazioni aggiornate!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Utente",
|
||||
"userCommands": "Comandi",
|
||||
"userCommandsHelp": "Una lista separata dal spazi con i comandi disponibili per questo utente. Example:\n",
|
||||
"userCreated": "Utente creato!",
|
||||
"userDefaults": "User default settings",
|
||||
"userDeleted": "Utente eliminato!",
|
||||
"userManagement": "Gestione degli utenti",
|
||||
"username": "Nome utente",
|
||||
"users": "Utenti",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"insertPath": "Insert the path",
|
||||
"userUpdated": "Utente aggiornato!",
|
||||
"userDefaults": "User default settings",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"modify": "Edit files",
|
||||
"execute": "Execute commands",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
}
|
||||
"username": "Nome utente",
|
||||
"users": "Utenti"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Aiuto",
|
||||
"hugoNew": "Hugo New",
|
||||
"login": "Login",
|
||||
"signup": "Signup",
|
||||
"logout": "Esci",
|
||||
"myFiles": "I miei file",
|
||||
"newFile": "Nuovo file",
|
||||
"newFolder": "Nuova cartella",
|
||||
"preview": "Anteprima",
|
||||
"settings": "Impostazioni",
|
||||
"siteSettings": "Impostaizoni del sito",
|
||||
"hugoNew": "Hugo New",
|
||||
"preview": "Anteprima"
|
||||
"signup": "Signup",
|
||||
"siteSettings": "Impostaizoni del sito"
|
||||
},
|
||||
"search": {
|
||||
"images": "Immagini",
|
||||
"music": "Musica",
|
||||
"pdf": "PDF",
|
||||
"types": "Tipi",
|
||||
"video": "Video",
|
||||
"search": "Cerca...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"pressToSearch": "Press enter to search..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "Link copiato!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Unità di tempo",
|
||||
"seconds": "Secondi",
|
||||
"minutes": "Minuti",
|
||||
"days": "Giorni",
|
||||
"hours": "Ore",
|
||||
"days": "Giorni"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"minutes": "Minuti",
|
||||
"seconds": "Secondi",
|
||||
"unit": "Unità di tempo"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "永久",
|
||||
"buttons": {
|
||||
"shell": "Toggle shell",
|
||||
"cancel": "キャンセル",
|
||||
"close": "閉じる",
|
||||
"copy": "コピー",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "作成",
|
||||
"delete": "削除",
|
||||
"download": "ダウンロード",
|
||||
"hideDotfiles": "",
|
||||
"info": "情報",
|
||||
"more": "More",
|
||||
"move": "移動",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "新規",
|
||||
"next": "次",
|
||||
"ok": "OK",
|
||||
"replace": "置き換える",
|
||||
"permalink": "固定リンク",
|
||||
"previous": "前",
|
||||
"publish": "発表",
|
||||
"rename": "名前を変更",
|
||||
"replace": "置き換える",
|
||||
"reportIssue": "問題を報告",
|
||||
"save": "保存",
|
||||
"schedule": "スケジュール",
|
||||
"search": "検索",
|
||||
"select": "選択",
|
||||
"share": "シェア",
|
||||
"publish": "発表",
|
||||
"selectMultiple": "複数選択",
|
||||
"schedule": "スケジュール",
|
||||
"share": "シェア",
|
||||
"shell": "Toggle shell",
|
||||
"switchView": "表示を切り替わる",
|
||||
"toggleSidebar": "サイドバーを表示する",
|
||||
"update": "更新",
|
||||
"upload": "アップロード",
|
||||
"permalink": "固定リンク"
|
||||
"upload": "アップロード"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "リンクがコピーされました!"
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "You don't have permissions to access this.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "リソースが見つからなりませんでした。"
|
||||
},
|
||||
"files": {
|
||||
"folders": "フォルダ",
|
||||
"files": "ファイル",
|
||||
"body": "本文",
|
||||
"clear": "クリアー",
|
||||
"closePreview": "プレビューを閉じる",
|
||||
"files": "ファイル",
|
||||
"folders": "フォルダ",
|
||||
"home": "ホーム",
|
||||
"lastModified": "最終変更",
|
||||
"loading": "ローディング...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "複数選択有効",
|
||||
"name": "名前",
|
||||
"size": "サイズ",
|
||||
"sortByLastModified": "最終変更日付によるソート",
|
||||
"sortByName": "名前によるソート",
|
||||
"sortBySize": "サイズによるソート",
|
||||
"sortByLastModified": "最終変更日付によるソート"
|
||||
"sortBySize": "サイズによるソート"
|
||||
},
|
||||
"help": {
|
||||
"click": "ファイルやディレクトリを選択",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "ファイルの名前を変更",
|
||||
"help": "ヘルプ"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "パスワード",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"submit": "ログイン",
|
||||
"createAnAccount": "Create an account",
|
||||
"loginInstead": "Already have an account",
|
||||
"password": "パスワード",
|
||||
"passwordConfirm": "Password Confirmation",
|
||||
"passwordsDontMatch": "Passwords don't match",
|
||||
"usernameTaken": "Username already taken",
|
||||
"signup": "Signup",
|
||||
"submit": "ログイン",
|
||||
"username": "ユーザ名",
|
||||
"usernameTaken": "Username already taken",
|
||||
"wrongCredentials": "ユーザ名またはパスワードが間違っています。"
|
||||
},
|
||||
"permanent": "永久",
|
||||
"prompts": {
|
||||
"copy": "コピー",
|
||||
"copyMessage": "コピーの目標ディレクトリを選択してください:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "最終変更",
|
||||
"move": "移動",
|
||||
"moveMessage": "移動の目標ディレクトリを選択してください:",
|
||||
"newArchetype": "ある元型に基づいて新しいポストを作成します。ファイルは コンテンツフォルダに作成されます。",
|
||||
"newDir": "新しいディレクトリを作成",
|
||||
"newDirMessage": "新しいディレクトリの名前を入力してください。",
|
||||
"newFile": "新しいファイルを作成",
|
||||
"newFileMessage": "新しいファイルの名前を入力してください。",
|
||||
"numberDirs": "ディレクトリ個数",
|
||||
"numberFiles": "ファイル個数",
|
||||
"replace": "置き換える",
|
||||
"replaceMessage": "アップロードするファイルの中でかち合う名前が一つあります。 既存のファイルを置き換えりませんか。\n",
|
||||
"rename": "名前を変更",
|
||||
"renameMessage": "名前を変更しようファイルは:",
|
||||
"show": "表示",
|
||||
"size": "サイズ",
|
||||
"replace": "置き換える",
|
||||
"replaceMessage": "アップロードするファイルの中でかち合う名前が一つあります。 既存のファイルを置き換えりませんか。\n",
|
||||
"schedule": "スケジュール",
|
||||
"scheduleMessage": "このポストの発表日付をスケジュールしてください。",
|
||||
"newArchetype": "ある元型に基づいて新しいポストを作成します。ファイルは コンテンツフォルダに作成されます。"
|
||||
"show": "表示",
|
||||
"size": "サイズ",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "画像",
|
||||
"music": "音楽",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Press enter to search...",
|
||||
"search": "検索...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"types": "種類",
|
||||
"video": "ビデオ"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instance name",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "documentation",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"brandingHelp": "You can costumize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"admin": "管理者",
|
||||
"administrator": "管理者",
|
||||
"allowCommands": "コマンドの実行",
|
||||
"allowEdit": "ファイルやディレクトリの編集、名前変更と削除",
|
||||
"allowNew": "ファイルとディレクトリの作成",
|
||||
"allowPublish": "ポストとぺーじの発表",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"avoidChanges": "(変更を避けるために空白にしてください)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "You can customize how your File Browser instance looks and feels by changing its name, replacing the logo, adding custom styles and even disable external links to GitHub.\nFor more information about custom branding, please check out the {0}.",
|
||||
"changePassword": "パスワードを変更",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Here you can set commands that are executed in the named events. You must write one per line. The environment variables {0} and {1} will be available, being {0} relative to {1}. For more information about this feature and the available environment variables, please read the {2}.",
|
||||
"commandsUpdated": "コマンドは更新されました!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "カスタムスタイルシ ート",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"disableExternalLinks": "Disable external links (except documentation)",
|
||||
"documentation": "documentation",
|
||||
"examples": "例",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"globalSettings": "グローバル設定",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Insert the path",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"instanceName": "Instance name",
|
||||
"language": "言語",
|
||||
"lockPassword": "新しいパスワードを変更に禁止",
|
||||
"newPassword": "新しいパスワード",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "新しいユーザー",
|
||||
"password": "パスワード",
|
||||
"passwordUpdated": "パスワードは更新されました!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"execute": "Execute commands",
|
||||
"modify": "Edit files",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
},
|
||||
"permissions": "権限",
|
||||
"permissionsHelp": "あなたはユーザーを管理者に設定し、または権限を個々に設定しできます。\"管理者\"を選択する場合、その他のすべての選択肢は自動的に設定されます。ユーザーの管理は管理者の権限として保留されました。",
|
||||
"profileSettings": "プロファイル設定",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "ここに、あなたはこのユーザーの許可または拒否規則を設定できます。ブロックされたファイルはリストに表示されません、それではアクセスも制限されます。正規表現(regex)のサポートと範囲に相対のパスが提供されています。",
|
||||
"scope": "範囲",
|
||||
"settingsUpdated": "設定は更新されました!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "ユーザー",
|
||||
"userCommands": "ユーザーのコマンド",
|
||||
"userCommandsHelp": "空白区切りの有効のコマンドのリストを指定してください。例:",
|
||||
"userCreated": "ユーザーは作成されました!",
|
||||
"userDefaults": "User default settings",
|
||||
"userDeleted": "ユーザーは削除されました!",
|
||||
"userManagement": "ユーザー管理",
|
||||
"username": "ユーザー名",
|
||||
"users": "ユーザー",
|
||||
"globalRules": "This is a global set of allow and disallow rules. They apply to every user. You can define specific rules on each user's settings to override this ones.",
|
||||
"allowSignup": "Allow users to signup",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "Insert regex expression",
|
||||
"insertPath": "Insert the path",
|
||||
"userUpdated": "ユーザーは更新されました!",
|
||||
"userDefaults": "User default settings",
|
||||
"defaultUserDescription": "This are the default settings for new users.",
|
||||
"executeOnShell": "Execute on shell",
|
||||
"executeOnShellDescription": "By default, File Browser executes the commands by calling their binaries directly. If you want to run them on a shell instead (such as Bash or PowerShell), you can define it here with the required arguments and flags. If set, the command you execute will be appended as an argument. This apply to both user commands and event hooks.",
|
||||
"perm": {
|
||||
"create": "Create files and directories",
|
||||
"delete": "Delete files and directories",
|
||||
"download": "Download",
|
||||
"modify": "Edit files",
|
||||
"execute": "Execute commands",
|
||||
"rename": "Rename or move files and directories",
|
||||
"share": "Share files"
|
||||
}
|
||||
"username": "ユーザー名",
|
||||
"users": "ユーザー"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "ヘルプ",
|
||||
"hugoNew": "Hugo New",
|
||||
"login": "Login",
|
||||
"signup": "Signup",
|
||||
"logout": "ログアウト",
|
||||
"myFiles": "私のファイル",
|
||||
"newFile": "新しいファイルを作成",
|
||||
"newFolder": "新しいフォルダを作成",
|
||||
"preview": "プレビュー",
|
||||
"settings": "設定",
|
||||
"siteSettings": "サイト設定",
|
||||
"hugoNew": "Hugo New",
|
||||
"preview": "プレビュー"
|
||||
"signup": "Signup",
|
||||
"siteSettings": "サイト設定"
|
||||
},
|
||||
"search": {
|
||||
"images": "画像",
|
||||
"music": "音楽",
|
||||
"pdf": "PDF",
|
||||
"types": "種類",
|
||||
"video": "ビデオ",
|
||||
"search": "検索...",
|
||||
"typeToSearch": "Type to search...",
|
||||
"pressToSearch": "Press enter to search..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "リンクがコピーされました!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "時間単位",
|
||||
"seconds": "秒",
|
||||
"minutes": "分",
|
||||
"days": "日",
|
||||
"hours": "時間",
|
||||
"days": "日"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Download File",
|
||||
"downloadFolder": "Download Folder"
|
||||
"minutes": "分",
|
||||
"seconds": "秒",
|
||||
"unit": "時間単位"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "영구",
|
||||
"buttons": {
|
||||
"shell": "쉘 전환",
|
||||
"cancel": "취소",
|
||||
"close": "닫기",
|
||||
"copy": "복사",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "생성",
|
||||
"delete": "삭제",
|
||||
"download": "다운로드",
|
||||
"hideDotfiles": "",
|
||||
"info": "정보",
|
||||
"more": "더보기",
|
||||
"move": "이동",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "신규",
|
||||
"next": "다음",
|
||||
"ok": "확인",
|
||||
"replace": "대체",
|
||||
"permalink": "링크 얻기",
|
||||
"previous": "이전",
|
||||
"publish": "게시",
|
||||
"rename": "이름 바꾸기",
|
||||
"replace": "대체",
|
||||
"reportIssue": "이슈 보내기",
|
||||
"save": "저장",
|
||||
"schedule": "일정",
|
||||
"search": "검색",
|
||||
"select": "선택",
|
||||
"share": "공유",
|
||||
"publish": "게시",
|
||||
"selectMultiple": "다중 선택",
|
||||
"schedule": "일정",
|
||||
"share": "공유",
|
||||
"shell": "쉘 전환",
|
||||
"switchView": "보기 전환",
|
||||
"toggleSidebar": "사이드바 전환",
|
||||
"update": "업데이트",
|
||||
"upload": "업로드",
|
||||
"permalink": "링크 얻기"
|
||||
"upload": "업로드"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "링크가 복사되었습니다!"
|
||||
"download": {
|
||||
"downloadFile": "파일 다운로드",
|
||||
"downloadFolder": "폴더 다운로드",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "접근 권한이 없습니다.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "해당 경로를 찾을 수 없습니다."
|
||||
},
|
||||
"files": {
|
||||
"folders": "폴더",
|
||||
"files": "파일",
|
||||
"body": "본문",
|
||||
"clear": "지우기",
|
||||
"closePreview": "미리보기 닫기",
|
||||
"files": "파일",
|
||||
"folders": "폴더",
|
||||
"home": "홈",
|
||||
"lastModified": "최종 수정",
|
||||
"loading": "로딩중...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "다중 선택 켜짐",
|
||||
"name": "이름",
|
||||
"size": "크기",
|
||||
"sortByLastModified": "수정시간순 정렬",
|
||||
"sortByName": "이름순",
|
||||
"sortBySize": "크기순",
|
||||
"sortByLastModified": "수정시간순 정렬"
|
||||
"sortBySize": "크기순"
|
||||
},
|
||||
"help": {
|
||||
"click": "파일이나 디렉토리를 선택해주세요.",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "파일 이름 변경",
|
||||
"help": "도움말"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"de": "Deutsch",
|
||||
"en": "English",
|
||||
"es": "Español",
|
||||
"fr": "Français",
|
||||
"is": "",
|
||||
"it": "Italiano",
|
||||
"ja": "日本語",
|
||||
"ko": "한국어",
|
||||
"nlBE": "",
|
||||
"pl": "Polski",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ro": "",
|
||||
"ru": "Русский",
|
||||
"svSE": "",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)"
|
||||
},
|
||||
"login": {
|
||||
"password": "비밀번호",
|
||||
"passwordConfirm": "비밀번호 확인",
|
||||
"submit": "로그인",
|
||||
"createAnAccount": "계정 생성",
|
||||
"loginInstead": "이미 계정이 있습니다",
|
||||
"password": "비밀번호",
|
||||
"passwordConfirm": "비밀번호 확인",
|
||||
"passwordsDontMatch": "비밀번호가 일치하지 않습니다",
|
||||
"usernameTaken": "사용자 이름이 존재합니다",
|
||||
"signup": "가입하기",
|
||||
"submit": "로그인",
|
||||
"username": "사용자 이름",
|
||||
"usernameTaken": "사용자 이름이 존재합니다",
|
||||
"wrongCredentials": "사용자 이름 또는 비밀번호를 확인하십시오"
|
||||
},
|
||||
"permanent": "영구",
|
||||
"prompts": {
|
||||
"copy": "복사",
|
||||
"copyMessage": "복사할 디렉토리:",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "최종 수정",
|
||||
"move": "이동",
|
||||
"moveMessage": "이동할 화일 또는 디렉토리를 선택하세요:",
|
||||
"newArchetype": "원형을 유지하는 포스트를 생성합니다. 파일은 컨텐트 폴더에 생성됩니다.",
|
||||
"newDir": "새 디렉토리",
|
||||
"newDirMessage": "새 디렉토리 이름을 입력해주세요.",
|
||||
"newFile": "새 파일",
|
||||
"newFileMessage": "새 파일 이름을 입력해주세요.",
|
||||
"numberDirs": "디렉토리 수",
|
||||
"numberFiles": "파일 수",
|
||||
"replace": "대체하기",
|
||||
"replaceMessage": "동일한 파일 이름이 존재합니다. 현재 파일을 덮어쓸까요?\n",
|
||||
"rename": "이름 변경",
|
||||
"renameMessage": "새로운 이름을 입력하세요.",
|
||||
"show": "보기",
|
||||
"size": "크기",
|
||||
"replace": "대체하기",
|
||||
"replaceMessage": "동일한 파일 이름이 존재합니다. 현재 파일을 덮어쓸까요?\n",
|
||||
"schedule": "일정",
|
||||
"scheduleMessage": "이 글을 공개할 시간을 알려주세요.",
|
||||
"newArchetype": "원형을 유지하는 포스트를 생성합니다. 파일은 컨텐트 폴더에 생성됩니다."
|
||||
"show": "보기",
|
||||
"size": "크기",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "이미지",
|
||||
"music": "음악",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "검색하려면 엔터를 입력하세요",
|
||||
"search": "검색...",
|
||||
"typeToSearch": "검색어 입력...",
|
||||
"types": "Types",
|
||||
"video": "비디오"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "인스턴스 이름",
|
||||
"brandingDirectoryPath": "브랜드 디렉토리 경로",
|
||||
"documentation": "문서",
|
||||
"branding": "브랜딩",
|
||||
"disableExternalLinks": "외부 링크 감추기",
|
||||
"brandingHelp": "File Browser 인스턴스는 이름, 로고, 스타일 등을 변경할 수 있습니다. 자세한 사항은 여기{0}에서 확인하세요.",
|
||||
"admin": "관리자",
|
||||
"administrator": "관리자",
|
||||
"allowCommands": "명령 실행",
|
||||
"allowEdit": "파일/디렉토리의 수정/변경/삭제 허용",
|
||||
"allowNew": "파일/디렉토리 생성 허용",
|
||||
"allowPublish": "새 포스트/페이지 생성 허용",
|
||||
"allowSignup": "사용자 가입 허용",
|
||||
"avoidChanges": "(수정하지 않으면 비워두세요)",
|
||||
"branding": "브랜딩",
|
||||
"brandingDirectoryPath": "브랜드 디렉토리 경로",
|
||||
"brandingHelp": "File Browser 인스턴스는 이름, 로고, 스타일 등을 변경할 수 있습니다. 자세한 사항은 여기{0}에서 확인하세요.",
|
||||
"changePassword": "비밀번호 변경",
|
||||
"commandRunner": "명령 실행기",
|
||||
"commandRunnerHelp": "이벤트에 해당하는 명령을 설정하세요. 줄당 1개의 명령을 적으세요. 환경 변수{0} 와 {1}이 사용가능하며, {0} 은 {1}에 상대 경로 입니다. 자세한 사항은 {2} 를 참조하세요.",
|
||||
"commandsUpdated": "명령 수정됨!",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"customStylesheet": "커스텀 스타일시트",
|
||||
"defaultUserDescription": "아래 사항은 신규 사용자들에 대한 기본 설정입니다.",
|
||||
"disableExternalLinks": "외부 링크 감추기",
|
||||
"documentation": "문서",
|
||||
"examples": "예",
|
||||
"executeOnShell": "쉘에서 실행",
|
||||
"executeOnShellDescription": "기본적으로 File Browser 는 바이너리를 명령어로 호출하여 실행합니다. 쉘을 통해 실행하기를 원한다면, Bash 또는 PowerShell 에 필요한 인수와 플래그를 설정하세요. 사용자 명령어와 이벤트 훅에 모두 적용됩니다.",
|
||||
"globalRules": "규칙에 대한 전역설정으로 모든 사용자에게 적용됩니다. 지정된 규칙은 사용자 설정을 덮어쓰기 합니다.",
|
||||
"globalSettings": "전역 설정",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "경로 입력",
|
||||
"insertRegex": "정규식 입력",
|
||||
"instanceName": "인스턴스 이름",
|
||||
"language": "언어",
|
||||
"lockPassword": "사용자에 의한 비밀번호 변경을 허용하지 않음",
|
||||
"newPassword": "새로운 비밀번호",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "새로운 사용자",
|
||||
"password": "비밀번호",
|
||||
"passwordUpdated": "비밀번호 수정 완료!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "파일이나 디렉토리 생성하기",
|
||||
"delete": "화일이나 디렉토리 삭제하기",
|
||||
"download": "다운로드",
|
||||
"execute": "명령 실행",
|
||||
"modify": "파일 편집",
|
||||
"rename": "파일 이름 변경 또는 디렉토리 이동",
|
||||
"share": "파일 공유하기"
|
||||
},
|
||||
"permissions": "권한",
|
||||
"permissionsHelp": "사용자를 관리자로 만들거나 권한을 부여할 수 있습니다. 관리자를 선택하면, 모든 옵션이 자동으로 선택됩니다. 사용자 관리는 현재 관리자만 할 수 있습니다.\n",
|
||||
"profileSettings": "프로필 설정",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "사용자별로 규칙을 허용/방지를 지정할 수 있습니다. 방지된 파일은 보이지 않고 사용자들은 접근할 수 없습니다. 사용자의 접근 허용 범위와 관련해 정규표현식(regex)과 경로를 지원합니다.\n",
|
||||
"scope": "범위",
|
||||
"settingsUpdated": "설정 수정됨!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "사용자",
|
||||
"userCommands": "명령어",
|
||||
"userCommandsHelp": "사용에게 허용할 명령어를 공백으로 구분하여 입력하세요. 예:\n",
|
||||
"userCreated": "사용자 생성됨!",
|
||||
"userDefaults": "사용자 기본 설정",
|
||||
"userDeleted": "사용자 삭제됨!",
|
||||
"userManagement": "사용자 관리",
|
||||
"username": "사용자 이름",
|
||||
"users": "사용자",
|
||||
"globalRules": "규칙에 대한 전역설정으로 모든 사용자에게 적용됩니다. 지정된 규칙은 사용자 설정을 덮어쓰기 합니다.",
|
||||
"allowSignup": "사용자 가입 허용",
|
||||
"createUserDir": "Auto create user home dir while adding new user",
|
||||
"insertRegex": "정규식 입력",
|
||||
"insertPath": "경로 입력",
|
||||
"userUpdated": "사용자 수정됨!",
|
||||
"userDefaults": "사용자 기본 설정",
|
||||
"defaultUserDescription": "아래 사항은 신규 사용자들에 대한 기본 설정입니다.",
|
||||
"executeOnShell": "쉘에서 실행",
|
||||
"executeOnShellDescription": "기본적으로 File Browser 는 바이너리를 명령어로 호출하여 실행합니다. 쉘을 통해 실행하기를 원한다면, Bash 또는 PowerShell 에 필요한 인수와 플래그를 설정하세요. 사용자 명령어와 이벤트 훅에 모두 적용됩니다.",
|
||||
"perm": {
|
||||
"create": "파일이나 디렉토리 생성하기",
|
||||
"delete": "화일이나 디렉토리 삭제하기",
|
||||
"download": "다운로드",
|
||||
"modify": "파일 편집",
|
||||
"execute": "명령 실행",
|
||||
"rename": "파일 이름 변경 또는 디렉토리 이동",
|
||||
"share": "파일 공유하기"
|
||||
}
|
||||
"username": "사용자 이름",
|
||||
"users": "사용자"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "도움말",
|
||||
"hugoNew": "Hugo New",
|
||||
"login": "로그인",
|
||||
"signup": "가입하기",
|
||||
"logout": "로그아웃",
|
||||
"myFiles": "내 파일",
|
||||
"newFile": "새로운 파일",
|
||||
"newFolder": "새로운 폴더",
|
||||
"preview": "미리보기",
|
||||
"settings": "설정",
|
||||
"siteSettings": "사이트 설정",
|
||||
"hugoNew": "Hugo New",
|
||||
"preview": "미리보기"
|
||||
"signup": "가입하기",
|
||||
"siteSettings": "사이트 설정"
|
||||
},
|
||||
"search": {
|
||||
"images": "이미지",
|
||||
"music": "음악",
|
||||
"pdf": "PDF",
|
||||
"types": "Types",
|
||||
"video": "비디오",
|
||||
"search": "검색...",
|
||||
"typeToSearch": "검색어 입력...",
|
||||
"pressToSearch": "검색하려면 엔터를 입력하세요"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "العربية",
|
||||
"en": "English",
|
||||
"it": "Italiano",
|
||||
"fr": "Français",
|
||||
"pt": "Português",
|
||||
"ptBR": "Português (Brasil)",
|
||||
"ja": "日本語",
|
||||
"zhCN": "中文 (简体)",
|
||||
"zhTW": "中文 (繁體)",
|
||||
"es": "Español",
|
||||
"de": "Deutsch",
|
||||
"ru": "Русский",
|
||||
"pl": "Polski",
|
||||
"ko": "한국어"
|
||||
"success": {
|
||||
"linkCopied": "링크가 복사되었습니다!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Time Unit",
|
||||
"seconds": "초",
|
||||
"minutes": "분",
|
||||
"days": "일",
|
||||
"hours": "시",
|
||||
"days": "일"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "파일 다운로드",
|
||||
"downloadFolder": "폴더 다운로드"
|
||||
"minutes": "분",
|
||||
"seconds": "초",
|
||||
"unit": "Time Unit"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
{
|
||||
"permanent": "Permanent",
|
||||
"buttons": {
|
||||
"shell": "Open shell",
|
||||
"cancel": "Annuleren",
|
||||
"close": "Sluiten",
|
||||
"copy": "Kopiëren",
|
||||
@@ -10,6 +8,7 @@
|
||||
"create": "Aanmaken",
|
||||
"delete": "Verwijderen",
|
||||
"download": "Downloaden",
|
||||
"hideDotfiles": "",
|
||||
"info": "Info",
|
||||
"more": "Meer",
|
||||
"move": "Verplaatsen",
|
||||
@@ -17,25 +16,28 @@
|
||||
"new": "Nieuw",
|
||||
"next": "Volgende",
|
||||
"ok": "OK",
|
||||
"replace": "Vervangen",
|
||||
"permalink": "Maak permanente link",
|
||||
"previous": "Vorige",
|
||||
"publish": "Publiceren",
|
||||
"rename": "Hernoemen",
|
||||
"replace": "Vervangen",
|
||||
"reportIssue": "Fout rapporteren",
|
||||
"save": "Opslaan",
|
||||
"schedule": "Plannen",
|
||||
"search": "Zoeken",
|
||||
"select": "Selecteren",
|
||||
"share": "Delen",
|
||||
"publish": "Publiceren",
|
||||
"selectMultiple": "Meerdere selecteren",
|
||||
"schedule": "Plannen",
|
||||
"share": "Delen",
|
||||
"shell": "Open shell",
|
||||
"switchView": "Beeld wisselen",
|
||||
"toggleSidebar": "Zijbalk tonen",
|
||||
"update": "Updaten",
|
||||
"upload": "Uploaden",
|
||||
"permalink": "Maak permanente link"
|
||||
"upload": "Uploaden"
|
||||
},
|
||||
"success": {
|
||||
"linkCopied": "Link gekopieerd!"
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
"downloadFolder": "Map downloaden",
|
||||
"downloadSelected": ""
|
||||
},
|
||||
"errors": {
|
||||
"forbidden": "U hebt geen rechten om hier toegang toe te krijgen.",
|
||||
@@ -43,11 +45,11 @@
|
||||
"notFound": "Deze locatie kan niet worden bereikt."
|
||||
},
|
||||
"files": {
|
||||
"folders": "Mappen",
|
||||
"files": "Bestanden",
|
||||
"body": "Body",
|
||||
"clear": "Wissen",
|
||||
"closePreview": "Voorvertoon sluiten",
|
||||
"files": "Bestanden",
|
||||
"folders": "Mappen",
|
||||
"home": "Home",
|
||||
"lastModified": "Laatst bewerkt",
|
||||
"loading": "Laden...",
|
||||
@@ -56,9 +58,9 @@
|
||||
"multipleSelectionEnabled": "Meerdere items selecteren ingeschakeld",
|
||||
"name": "Naam",
|
||||
"size": "Grootte",
|
||||
"sortByLastModified": "Sorteren op laatst bewerkt",
|
||||
"sortByName": "Sorteren op naam",
|
||||
"sortBySize": "Sorteren op grootte",
|
||||
"sortByLastModified": "Sorteren op laatst bewerkt"
|
||||
"sortBySize": "Sorteren op grootte"
|
||||
},
|
||||
"help": {
|
||||
"click": "selecteer bestand of map",
|
||||
@@ -74,18 +76,39 @@
|
||||
"f2": "bestand herbenoemen",
|
||||
"help": "Help"
|
||||
},
|
||||
"languages": {
|
||||
"ar": "Arabisch",
|
||||
"de": "Duits",
|
||||
"en": "Engels",
|
||||
"es": "Spaans",
|
||||
"fr": "Frans",
|
||||
"is": "",
|
||||
"it": "Italiaans",
|
||||
"ja": "Japans",
|
||||
"ko": "Koreaans",
|
||||
"nlBE": "",
|
||||
"pl": "Pools",
|
||||
"pt": "Portugees",
|
||||
"ptBR": "Portugees (Brazilië)",
|
||||
"ro": "",
|
||||
"ru": "Russisch",
|
||||
"svSE": "",
|
||||
"zhCN": "Chinees (vereenvoudigd)",
|
||||
"zhTW": "Chinees (traditioneel)"
|
||||
},
|
||||
"login": {
|
||||
"password": "Wachtwoord",
|
||||
"passwordConfirm": "Wachtwoordbevestiging ",
|
||||
"submit": "Log in",
|
||||
"createAnAccount": "Account aanmaken",
|
||||
"loginInstead": "Heeft al een account",
|
||||
"password": "Wachtwoord",
|
||||
"passwordConfirm": "Wachtwoordbevestiging ",
|
||||
"passwordsDontMatch": "Wachtwoorden komen niet overeen",
|
||||
"usernameTaken": "Gebruikersnaam reeds in gebruik",
|
||||
"signup": "Registeren",
|
||||
"submit": "Log in",
|
||||
"username": "Gebruikersnaam",
|
||||
"usernameTaken": "Gebruikersnaam reeds in gebruik",
|
||||
"wrongCredentials": "Verkeerde inloggegevens"
|
||||
},
|
||||
"permanent": "Permanent",
|
||||
"prompts": {
|
||||
"copy": "Kopiëren",
|
||||
"copyMessage": "Kies een locatie om uw bestanden te kopiëren: ",
|
||||
@@ -102,43 +125,64 @@
|
||||
"lastModified": "Laatst Bewerkt",
|
||||
"move": "Verplaatsen",
|
||||
"moveMessage": "Kies een nieuwe locatie voor je bestand(en)/map(pen)",
|
||||
"newArchetype": "Maak een nieuw bericht op basis van een archetype. Uw bestand wordt aangemaakt in de inhoudsmap.",
|
||||
"newDir": "Nieuwe map",
|
||||
"newDirMessage": "Schrijf de naam van de nieuwe map",
|
||||
"newFile": "Nieuw bestand",
|
||||
"newFileMessage": "Schrijf de naam van het nieuwe bestand",
|
||||
"numberDirs": "Aantal mappen",
|
||||
"numberFiles": "Aantal bestanden",
|
||||
"replace": "Vervangen",
|
||||
"replaceMessage": "Een van de bestanden die u probeert te uploaden, geeft conflicten i.v.m. de naamgeving. Wilt u de bestaande bestanden vervangen?\n",
|
||||
"rename": "Hernoemen",
|
||||
"renameMessage": "Voer een nieuwe naam in voor",
|
||||
"show": "Tonen",
|
||||
"size": "Grootte",
|
||||
"replace": "Vervangen",
|
||||
"replaceMessage": "Een van de bestanden die u probeert te uploaden, geeft conflicten i.v.m. de naamgeving. Wilt u de bestaande bestanden vervangen?\n",
|
||||
"schedule": "Plannen",
|
||||
"scheduleMessage": "Kies een datum en tijd om de publicatie van dit bericht in te plannen.",
|
||||
"newArchetype": "Maak een nieuw bericht op basis van een archetype. Uw bestand wordt aangemaakt in de inhoudsmap."
|
||||
"show": "Tonen",
|
||||
"size": "Grootte",
|
||||
"upload": "",
|
||||
"uploadMessage": ""
|
||||
},
|
||||
"search": {
|
||||
"images": "Afbeeldingen",
|
||||
"music": "Muziek",
|
||||
"pdf": "PDF",
|
||||
"pressToSearch": "Druk op enter om te zoeken...",
|
||||
"search": "Zoeken...",
|
||||
"typeToSearch": "Typ om te zoeken...",
|
||||
"types": "Types",
|
||||
"video": "Video"
|
||||
},
|
||||
"settings": {
|
||||
"instanceName": "Instantienaam",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"documentation": "Documentatie",
|
||||
"branding": "Branding",
|
||||
"disableExternalLinks": "Schakel externe links uit (behalve documentatie)",
|
||||
"brandingHelp": "U kunt de looks en feels hoe File Browser wordt getoond wijzigen door de naam aan te passen, het logo te vervangen, een aangepast stylesheet toe te voegen en/of de externe links naar GitHub uit te schakelen.\nVoor meer informatie over custom branding, bekijk {0}.",
|
||||
"admin": "Admin",
|
||||
"administrator": "Administrator",
|
||||
"allowCommands": "Commando's uitvoeren",
|
||||
"allowEdit": "Bestanden of mappen aanpassen, hernoemen of verwijderen",
|
||||
"allowNew": "Nieuwe bestanden of mappen aanmaken",
|
||||
"allowPublish": "Publiceer nieuwe berichten en pagina's",
|
||||
"allowSignup": "Sta gebruikers toe om zich te registreren",
|
||||
"avoidChanges": "(laat leeg om wijzigingen te voorkomen)",
|
||||
"branding": "Branding",
|
||||
"brandingDirectoryPath": "Branding directory path",
|
||||
"brandingHelp": "U kunt de looks en feels hoe File Browser wordt getoond wijzigen door de naam aan te passen, het logo te vervangen, een aangepast stylesheet toe te voegen en/of de externe links naar GitHub uit te schakelen.\nVoor meer informatie over custom branding, bekijk {0}.",
|
||||
"changePassword": "Wijzig Wachtwoord",
|
||||
"commandRunner": "Command runner",
|
||||
"commandRunnerHelp": "Hier kunt u opdrachten instellen die worden uitgevoerd in de benoemde gebeurtenissen. U moet er één per regel schrijven. De omgevingsvariabelen {0} en {1} zijn beschikbaar, zijnde {0} relatief ten opzichte van {1}. Raadpleeg {2} voor meer informatie over deze functie en de beschikbare omgevingsvariabelen.",
|
||||
"commandsUpdated": "Commando's bijgewerkt!",
|
||||
"createUserDir": "Maak automatisch een thuismap aan wanneer een nieuwe gebruiker wordt aangemaakt",
|
||||
"customStylesheet": "Aangepast Stylesheet",
|
||||
"defaultUserDescription": "Dit zijn de standaardinstellingen voor nieuwe gebruikers.",
|
||||
"disableExternalLinks": "Schakel externe links uit (behalve documentatie)",
|
||||
"documentation": "Documentatie",
|
||||
"examples": "Voorbeelden",
|
||||
"executeOnShell": "Uitvoeren in de shell",
|
||||
"executeOnShellDescription": "File Browser voert de opdrachten standaard uit door hun binaire bestanden rechtstreeks op te roepen. Als u ze in plaats daarvan wilt uitvoeren op een shell (zoals Bash of PowerShell), kunt u dit hier definiëren met de vereiste argumenten en vlaggen. Indien ingesteld, wordt de opdracht die u uitvoert, toegevoegd als een argument. Dit is van toepassing op zowel gebruikersopdrachten als event hooks.",
|
||||
"globalRules": "Dit is een algemene reeks toegestane en niet toegestane regels. Ze zijn van toepassing op elke gebruiker. U kunt specifieke regels voor de instellingen van elke gebruiker definiëren om deze te overschrijven.",
|
||||
"globalSettings": "Algemene Instellingen",
|
||||
"hideDotfiles": "",
|
||||
"insertPath": "Voeg een pad toe",
|
||||
"insertRegex": "Regex expressie invoeren",
|
||||
"instanceName": "Instantienaam",
|
||||
"language": "Taal",
|
||||
"lockPassword": "Voorkom dat de gebruiker het wachtwoord wijzigt",
|
||||
"newPassword": "Uw nieuw wachtwoord",
|
||||
@@ -146,6 +190,16 @@
|
||||
"newUser": "Nieuwe gebruiker",
|
||||
"password": "Wachtwoord",
|
||||
"passwordUpdated": "Wachtwoord bijgewerkt!",
|
||||
"path": "",
|
||||
"perm": {
|
||||
"create": "Bestanden en mappen aanmaken",
|
||||
"delete": "Bestanden en mappen verwijderen",
|
||||
"download": "Downloaden",
|
||||
"execute": "Commando's uitvoeren",
|
||||
"modify": "Bestanden aanpassen",
|
||||
"rename": "Bestanden of mappen hernoemen of verplaatsen",
|
||||
"share": "Bestanden delen"
|
||||
},
|
||||
"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",
|
||||
"profileSettings": "Profielinstellingen",
|
||||
@@ -155,82 +209,46 @@
|
||||
"rulesHelp": "Hier kunt u een reeks regels voor toestaan en niet toestaan voor deze specifieke gebruiker definiëren. De geblokkeerde bestanden verschijnen niet in de lijsten en zijn niet toegankelijk voor de gebruiker. We ondersteunen regex en paden relatief ten opzichte van het bereik van gebruikers. \n",
|
||||
"scope": "Scope",
|
||||
"settingsUpdated": "Instellingen bijgewerkt!",
|
||||
"shareDuration": "",
|
||||
"shareManagement": "",
|
||||
"singleClick": "",
|
||||
"themes": {
|
||||
"dark": "",
|
||||
"light": "",
|
||||
"title": ""
|
||||
},
|
||||
"user": "Gebruiker",
|
||||
"userCommands": "Commando's",
|
||||
"userCommandsHelp": "Een lijst met beschikbare commando's voor de gebruiker gescheiden door spaties. Voorbeeld: \n",
|
||||
"userCreated": "Gebruiker aangemaakt!",
|
||||
"userDefaults": "Standaardinstellingen gebruiker",
|
||||
"userDeleted": "Gebruiker verwijderd!",
|
||||
"userManagement": "Gebruikersbeheer",
|
||||
"username": "Gebruikersnaam",
|
||||
"users": "Gebruikers",
|
||||
"globalRules": "Dit is een algemene reeks toegestane en niet toegestane regels. Ze zijn van toepassing op elke gebruiker. U kunt specifieke regels voor de instellingen van elke gebruiker definiëren om deze te overschrijven.",
|
||||
"allowSignup": "Sta gebruikers toe om zich te registreren",
|
||||
"createUserDir": "Maak automatisch een thuismap aan wanneer een nieuwe gebruiker wordt aangemaakt",
|
||||
"insertRegex": "Regex expressie invoeren",
|
||||
"insertPath": "Voeg een pad toe",
|
||||
"userUpdated": "Gebruiker bijgewerkt!",
|
||||
"userDefaults": "Standaardinstellingen gebruiker",
|
||||
"defaultUserDescription": "Dit zijn de standaardinstellingen voor nieuwe gebruikers.",
|
||||
"executeOnShell": "Uitvoeren in de shell",
|
||||
"executeOnShellDescription": "File Browser voert de opdrachten standaard uit door hun binaire bestanden rechtstreeks op te roepen. Als u ze in plaats daarvan wilt uitvoeren op een shell (zoals Bash of PowerShell), kunt u dit hier definiëren met de vereiste argumenten en vlaggen. Indien ingesteld, wordt de opdracht die u uitvoert, toegevoegd als een argument. Dit is van toepassing op zowel gebruikersopdrachten als event hooks.",
|
||||
"perm": {
|
||||
"create": "Bestanden en mappen aanmaken",
|
||||
"delete": "Bestanden en mappen verwijderen",
|
||||
"download": "Downloaden",
|
||||
"modify": "Bestanden aanpassen",
|
||||
"execute": "Commando's uitvoeren",
|
||||
"rename": "Bestanden of mappen hernoemen of verplaatsen",
|
||||
"share": "Bestanden delen"
|
||||
}
|
||||
"username": "Gebruikersnaam",
|
||||
"users": "Gebruikers"
|
||||
},
|
||||
"sidebar": {
|
||||
"help": "Help",
|
||||
"hugoNew": "Hugo nieuw",
|
||||
"login": "Log in",
|
||||
"signup": "Registeren",
|
||||
"logout": "Uitloggen",
|
||||
"myFiles": "Mijn bestanden",
|
||||
"newFile": "Nieuw bestand",
|
||||
"newFolder": "Nieuwe map",
|
||||
"preview": "Voorbeeld",
|
||||
"settings": "Instellingen",
|
||||
"siteSettings": "Site-instellingen",
|
||||
"hugoNew": "Hugo nieuw",
|
||||
"preview": "Voorbeeld"
|
||||
"signup": "Registeren",
|
||||
"siteSettings": "Site-instellingen"
|
||||
},
|
||||
"search": {
|
||||
"images": "Afbeeldingen",
|
||||
"music": "Muziek",
|
||||
"pdf": "PDF",
|
||||
"types": "Types",
|
||||
"video": "Video",
|
||||
"search": "Zoeken...",
|
||||
"typeToSearch": "Typ om te zoeken...",
|
||||
"pressToSearch": "Druk op enter om te zoeken..."
|
||||
},
|
||||
"languages": {
|
||||
"ar": "Arabisch",
|
||||
"en": "Engels",
|
||||
"it": "Italiaans",
|
||||
"fr": "Frans",
|
||||
"pt": "Portugees",
|
||||
"ptBR": "Portugees (Brazilië)",
|
||||
"ja": "Japans",
|
||||
"zhCN": "Chinees (vereenvoudigd)",
|
||||
"zhTW": "Chinees (traditioneel)",
|
||||
"es": "Spaans",
|
||||
"de": "Duits",
|
||||
"ru": "Russisch",
|
||||
"pl": "Pools",
|
||||
"ko": "Koreaans"
|
||||
"success": {
|
||||
"linkCopied": "Link gekopieerd!"
|
||||
},
|
||||
"time": {
|
||||
"unit": "Tijdseenheid",
|
||||
"seconds": "Seconden",
|
||||
"minutes": "Minuten",
|
||||
"days": "Dagen",
|
||||
"hours": "Uren",
|
||||
"days": "Dagen"
|
||||
},
|
||||
"download": {
|
||||
"downloadFile": "Bestand downloaden",
|
||||
"downloadFolder": "Map downloaden"
|
||||
"minutes": "Minuten",
|
||||
"seconds": "Seconden",
|
||||
"unit": "Tijdseenheid"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user