Merge branch 'main' into prometheus

* main: (27 commits)
  gui, man, authors: Update docs, translations, and contributors
  cmd/syncthing: Mention STVERSIONEXTRA in --help output (ref #8980)
  gui, lib/api: Add possibility to feed through extra version information (#8980)
  cmd/ursrv: Update map tile URL
  cmd/strelaypoolsrv: Update map tile URL (#8985)
  cmd/stcrashreceiver: Correct parsing of current version string
  build: Update dependencies
  cmd/ursrv: Remove old, unused user movement code
  cmd/ursrv: Merge ursrv and uraggregate as subcommands
  cmd/ursrv: Remove useless static TLS cert handling
  cmd/ursrv: Embed static assets
  cmd/ursrv: Refactor to use CLI options, fewer global vars
  gui: Show xattr filter editor when send xattrs checked (fixes #8958) (#8959)
  gui, man, authors: Update docs, translations, and contributors
  build: Build Docker image for plain 32 bit arm (fixes #8973)
  lib/fs: Clarify errors for Windows filenames (fixes #8968) (#8969)
  gui: Avoid spurious comma in shared-with device list (fixes #8967) (#8970)
  cmd/ursrv: Summarize tiny fraction items into Other
  cmd/ursrv: Update distributions list
  build: Only push releases to cloud storage, and also use `latest`
  ...
This commit is contained in:
Jakob Borg 2023-07-17 11:47:34 +02:00
commit 0c7a479ca0
63 changed files with 1561 additions and 1440 deletions

View File

@ -0,0 +1,54 @@
name: Build Infrastructure Images
on:
push:
branches:
- infrastructure
env:
GO_VERSION: "^1.20.5"
CGO_ENABLED: "0"
BUILD_USER: docker
BUILD_HOST: github.syncthing.net
jobs:
docker-syncthing:
name: Build and push Docker images
runs-on: ubuntu-latest
environment: docker
strategy:
matrix:
pkg:
- stcrashreceiver
- strelaypoolsrv
- stupgrades
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Login to Docker Hub
uses: docker/login-action@v2
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
- name: Build binaries
run: |
for arch in arm64 amd64; do
go run build.go -goos linux -goarch "$arch" build ${{ matrix.pkg }}
mv ${{ matrix.pkg }} ${{ matrix.pkg }}-linux-"$arch"
done
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- name: Build and push
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile.${{ matrix.pkg }}
platforms: linux/amd64,linux/arm64
push: true
tags: syncthing/${{ matrix.pkg }}:latest,syncthing/${{ matrix.pkg }}:${{ github.sha }}

View File

@ -602,7 +602,7 @@ jobs:
publish-release-files:
name: Publish release files
if: github.event_name == 'push' && startsWith(github.ref, 'refs/heads/release')
if: github.event_name == 'push' && github.ref == 'refs/heads/release'
environment: signing
needs:
- sign-for-upgrade
@ -630,7 +630,7 @@ jobs:
version=$(go run build.go version)
echo "VERSION=$version" >> $GITHUB_ENV
- name: Push to Spaces
- name: Push to Spaces (${{ env.VERSION }})
uses: docker://docker.io/rclone/rclone:latest
env:
RCLONE_CONFIG_SPACES_TYPE: s3
@ -642,11 +642,43 @@ jobs:
with:
args: sync packages spaces:syncthing/release/${{ env.VERSION }}
- name: Push to Spaces (latest)
uses: docker://docker.io/rclone/rclone:latest
env:
RCLONE_CONFIG_SPACES_TYPE: s3
RCLONE_CONFIG_SPACES_PROVIDER: DigitalOcean
RCLONE_CONFIG_SPACES_ACCESS_KEY_ID: ${{ secrets.SPACES_KEY }}
RCLONE_CONFIG_SPACES_SECRET_ACCESS_KEY: ${{ secrets.SPACES_SECRET }}
RCLONE_CONFIG_SPACES_ENDPOINT: ams3.digitaloceanspaces.com
RCLONE_CONFIG_SPACES_ACL: public-read
with:
args: sync spaces:syncthing/release/${{ env.VERSION }} spaces:syncthing/release/latest
#
# Build and push to Docker Hub
#
docker-syncthing:
name: Build and push Docker images
runs-on: ubuntu-latest
if: github.event_name == 'push' && (github.ref == 'refs/heads/release' || github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/heads/release-'))
environment: docker
strategy:
matrix:
pkg:
- syncthing
- strelaysrv
- stdiscosrv
include:
- pkg: syncthing
dockerfile: Dockerfile
image: syncthing/syncthing
- pkg: strelaysrv
dockerfile: Dockerfile.strelaysrv
image: syncthing/relaysrv
- pkg: stdiscosrv
dockerfile: Dockerfile.stdiscosrv
image: syncthing/discosrv
steps:
- uses: actions/checkout@v3
with:
@ -663,20 +695,27 @@ jobs:
path: |
~/.cache/go-build
~/go/pkg/mod
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-docker-${{ hashFiles('**/go.sum') }}
key: ${{ runner.os }}-go-${{ env.GO_VERSION }}-docker-${{ matrix.pkg }}-${{ hashFiles('**/go.sum') }}
- name: Build binaries
run: |
for arch in arm64 amd64; do
go run build.go -goos linux -goarch "$arch" -no-upgrade build syncthing
mv syncthing syncthing-linux-"$arch"
for arch in amd64 arm64 arm; do
go run build.go -goos linux -goarch "$arch" -no-upgrade build ${{ matrix.pkg }}
mv ${{ matrix.pkg }} ${{ matrix.pkg }}-linux-"$arch"
done
env:
CGO_ENABLED: "0"
BUILD_USER: docker
- name: Check if we will be able to push images
run: |
if [[ "${{ secrets.DOCKERHUB_TOKEN }}" != "" ]]; then
echo "DOCKER_PUSH=true" >> $GITHUB_ENV;
fi
- name: Login to Docker Hub
uses: docker/login-action@v2
if: env.DOCKER_PUSH == 'true'
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_TOKEN }}
@ -692,21 +731,21 @@ jobs:
echo Release version, pushing to :latest and version tags
major=${version%.*.*}
minor=${version%.*}
tags=syncthing/syncthing:$version,syncthing/syncthing:$major,syncthing/syncthing:$minor,syncthing/syncthing:latest
tags=${{ matrix.image }}:$version,${{ matrix.image }}:$major,${{ matrix.image }}:$minor,${{ matrix.image }}:latest
elif [[ $version == *-rc.@([0-9]|[0-9][0-9]) ]] ; then
echo Release candidate, pushing to :rc
tags=syncthing/syncthing:rc
tags=${{ matrix.image }}:rc
else
echo Development version, pushing to :edge
tags=syncthing/syncthing:edge
tags=${{ matrix.image }}:edge
fi
echo "DOCKER_TAGS=$tags" >> $GITHUB_ENV
- name: Build and push syncthing
- name: Build and push Docker image
uses: docker/build-push-action@v4
with:
context: .
file: ./Dockerfile
platforms: linux/amd64,linux/arm64
push: true
file: ${{ matrix.dockerfile }}
platforms: linux/amd64,linux/arm64,linux/arm/7
push: ${{ env.DOCKER_PUSH == 'true' }}
tags: ${{ env.DOCKER_TAGS }}

View File

@ -220,6 +220,7 @@ Michael Ploujnikov (plouj) <ploujj@gmail.com>
Michael Rienstra <mrienstra@gmail.com>
Michael Tilli (pyfisch) <pyfisch@gmail.com>
MichaIng <micha@dietpi.com>
Migelo <miha@filetki.si>
Mike Boone <mike@boonedocks.net>
MikeLund <MikeLund@users.noreply.github.com>
MikolajTwarog <43782609+MikolajTwarog@users.noreply.github.com>

View File

@ -1,18 +1,8 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f stcrashreceiver && go run build.go build stcrashreceiver
FROM alpine
ARG TARGETARCH
EXPOSE 8080
COPY --from=builder /src/stcrashreceiver /bin/stcrashreceiver
COPY stcrashreceiver-linux-${TARGETARCH} /bin/stcrashreceiver
ENTRYPOINT [ "/bin/stcrashreceiver" ]

View File

@ -1,15 +1,20 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
ARG BUILD_USER
ARG BUILD_HOST
ARG TARGETARCH
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f stdiscosrv && go run build.go -no-upgrade build stdiscosrv
RUN if [ ! -f stdiscosrv-linux-$TARGETARCH ] ; then \
go run build.go -no-upgrade build stdiscosrv ; \
mv stdiscosrv stdiscosrv-linux-$TARGETARCH ; \
fi
FROM alpine
ARG TARGETARCH
EXPOSE 19200 8443
@ -17,7 +22,7 @@ VOLUME ["/var/stdiscosrv"]
RUN apk add --no-cache ca-certificates su-exec
COPY --from=builder /src/stdiscosrv /bin/stdiscosrv
COPY --from=builder /src/stdiscosrv-linux-$TARGETARCH /bin/stdiscosrv
COPY --from=builder /src/script/docker-entrypoint.sh /bin/entrypoint.sh
ENV PUID=1000 PGID=1000 HOME=/var/stdiscosrv

View File

@ -1,15 +1,5 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f strelaysrv && go run build.go -no-upgrade build strelaypoolsrv
FROM alpine
ARG TARGETARCH
EXPOSE 8080
@ -19,8 +9,8 @@ ENV PUID=1000 PGID=1000 MAXMIND_KEY=
RUN mkdir /var/strelaypoolsrv && chown 1000 /var/strelaypoolsrv
USER 1000
COPY --from=builder /src/strelaypoolsrv /bin/strelaypoolsrv
COPY --from=builder /src/script/strelaypoolsrv-entrypoint.sh /bin/entrypoint.sh
COPY strelaypoolsrv-linux-${TARGETARCH} /bin/strelaypoolsrv
COPY script/strelaypoolsrv-entrypoint.sh /bin/entrypoint.sh
WORKDIR /var/strelaypoolsrv
ENTRYPOINT ["/bin/entrypoint.sh", "/bin/strelaypoolsrv", "-listen", ":8080"]

View File

@ -1,15 +1,20 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
ARG BUILD_USER
ARG BUILD_HOST
ARG TARGETARCH
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f strelaysrv && go run build.go -no-upgrade build strelaysrv
RUN if [ ! -f strelaysrv-linux-$TARGETARCH ] ; then \
go run build.go -no-upgrade build strelaysrv ; \
mv strelaysrv strelaysrv-linux-$TARGETARCH ; \
fi
FROM alpine
ARG TARGETARCH
EXPOSE 22067 22070
@ -17,7 +22,7 @@ VOLUME ["/var/strelaysrv"]
RUN apk add --no-cache ca-certificates su-exec
COPY --from=builder /src/strelaysrv /bin/strelaysrv
COPY --from=builder /src/strelaysrv-linux-$TARGETARCH /bin/strelaysrv
COPY --from=builder /src/script/docker-entrypoint.sh /bin/entrypoint.sh
ENV PUID=1000 PGID=1000 HOME=/var/strelaysrv

View File

@ -1,18 +1,8 @@
ARG GOVERSION=latest
FROM golang:$GOVERSION AS builder
WORKDIR /src
COPY . .
ENV CGO_ENABLED=0
ENV BUILD_HOST=syncthing.net
ENV BUILD_USER=docker
RUN rm -f stupgrades && go run build.go build stupgrades
FROM alpine
ARG TARGETARCH
EXPOSE 8080
COPY --from=builder /src/stupgrades /bin/stupgrades
COPY stupgrades-linux-${TARGETARCH} /bin/stupgrades
ENTRYPOINT [ "/bin/stupgrades" ]

View File

@ -2,9 +2,6 @@
---
[![Latest Linux & Cross Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildLinuxCross.svg?style=flat-square&label=linux+%26+cross+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildLinuxCross&guest=1)
[![Latest Windows Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildWindows.svg?style=flat-square&label=windows+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildWindows&guest=1)
[![Latest Mac Build](https://img.shields.io/teamcity/https/build.syncthing.net/s/Syncthing_BuildMac.svg?style=flat-square&label=mac+build)](https://build.syncthing.net/viewType.html?buildTypeId=Syncthing_BuildMac&guest=1)
[![MPLv2 License](https://img.shields.io/badge/license-MPLv2-blue.svg?style=flat-square)](https://www.mozilla.org/MPL/2.0/)
[![CII Best Practices](https://bestpractices.coreinfrastructure.org/projects/88/badge)](https://bestpractices.coreinfrastructure.org/projects/88)
[![Go Report Card](https://goreportcard.com/badge/github.com/syncthing/syncthing)](https://goreportcard.com/report/github.com/syncthing/syncthing)

View File

@ -214,11 +214,17 @@ var targets = map[string]target{
binaryName: "stupgrades",
},
"stcrashreceiver": {
name: "stupgrastcrashreceiverdes",
name: "stcrashreceiver",
description: "Syncthing Crash Server",
buildPkgs: []string{"github.com/syncthing/syncthing/cmd/stcrashreceiver"},
binaryName: "stcrashreceiver",
},
"ursrv": {
name: "ursrv",
description: "Syncthing Usage Reporting Server",
buildPkgs: []string{"github.com/syncthing/syncthing/cmd/ursrv"},
binaryName: "ursrv",
},
}
func initTargets() {

View File

@ -69,6 +69,9 @@ func main() {
}
mux.Handle("/", cr)
mux.HandleFunc("/ping", func(w http.ResponseWriter, req *http.Request) {
w.Write([]byte("OK"))
})
if params.DSN != "" {
mux.HandleFunc("/newcrash/failure", handleFailureFn(params.DSN, filepath.Join(params.Dir, "failure_reports")))

View File

@ -215,7 +215,13 @@ func crashReportFingerprint(message string) []string {
}
// syncthing v1.1.4-rc.1+30-g6aaae618-dirty-crashrep "Erbium Earthworm" (go1.12.5 darwin-amd64) jb@kvin.kastelo.net 2019-05-23 16:08:14 UTC [foo, bar]
var longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
// or, somewhere along the way the "+" in the version tag disappeared:
// syncthing v1.23.7-dev.26.gdf7b56ae.dirty-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]
var (
longVersionRE = regexp.MustCompile(`syncthing\s+(v[^\s]+)\s+"([^"]+)"\s\(([^\s]+)\s+([^-]+)-([^)]+)\)\s+([^\s]+)[^\[]*(?:\[(.+)\])?$`)
gitExtraRE = regexp.MustCompile(`\.\d+\.g[0-9a-f]+`) // ".1.g6aaae618"
gitExtraSepRE = regexp.MustCompile(`[.-]`) // dot or dash
)
type version struct {
version string // "v1.1.4-rc.1+30-g6aaae618-dirty-crashrep"
@ -257,10 +263,21 @@ func parseVersion(line string) (version, error) {
builder: m[6],
}
parts := strings.Split(v.version, "+")
// Split the version tag into tag and commit. This is old style
// v1.2.3-something.4+11-g12345678 or newer with just dots
// v1.2.3-something.4.11.g12345678 or v1.2.3-dev.11.g12345678.
parts := []string{v.version}
if strings.Contains(v.version, "+") {
parts = strings.Split(v.version, "+")
} else {
idxs := gitExtraRE.FindStringIndex(v.version)
if len(idxs) > 0 {
parts = []string{v.version[:idxs[0]], v.version[idxs[0]+1:]}
}
}
v.tag = parts[0]
if len(parts) > 1 {
fields := strings.Split(parts[1], "-")
fields := gitExtraSepRE.Split(parts[1], -1)
if len(fields) >= 2 && strings.HasPrefix(fields[1], "g") {
v.commit = fields[1][1:]
}

View File

@ -44,6 +44,20 @@ func TestParseVersion(t *testing.T) {
extra: []string{"foo", "bar"},
},
},
{
longVersion: `syncthing v1.23.7-dev.26.gdf7b56ae-stversionextra "Fermium Flea" (go1.20.5 darwin-arm64) jb@ok.kastelo.net 2023-07-12 06:55:26 UTC [Some Wrapper, purego, stnoupgrade]`,
parsed: version{
version: "v1.23.7-dev.26.gdf7b56ae-stversionextra",
tag: "v1.23.7-dev",
commit: "df7b56ae",
codename: "Fermium Flea",
runtime: "go1.20.5",
goos: "darwin",
goarch: "arm64",
builder: "jb@ok.kastelo.net",
extra: []string{"Some Wrapper", "purego", "stnoupgrade"},
},
},
}
for _, tc := range cases {

View File

@ -237,7 +237,7 @@
uptimeSeconds: 0,
};
$scope.map = L.map('map').setView([40.90296, 1.90925], 2);
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png',
{
attribution: 'Leaflet',
maxZoom: 17

View File

@ -99,6 +99,11 @@ above.
"minio" for the github.com/minio/sha256-simd implementation,
and blank (the default) for auto detection.
STVERSIONEXTRA Add extra information to the version string in logs and the
version line in the GUI. Can be set to the name of a wrapper
or tool controlling syncthing to communicate this to the end
user.
GOMAXPROCS Set the maximum number of CPU cores to use. Defaults to all
available CPU cores.

View File

@ -4,10 +4,11 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package aggregate
import (
"database/sql"
"fmt"
"log"
"os"
"time"
@ -15,26 +16,21 @@ import (
_ "github.com/lib/pq"
)
var dbConn = getEnvDefault("UR_DB_URL", "postgres://user:password@localhost/ur?sslmode=disable")
func getEnvDefault(key, def string) string {
if val := os.Getenv(key); val != "" {
return val
}
return def
type CLI struct {
DBConn string `env:"UR_DB_URL" default:"postgres://user:password@localhost/ur?sslmode=disable"`
}
func main() {
func (cli *CLI) Run() error {
log.SetFlags(log.Ltime | log.Ldate)
log.SetOutput(os.Stdout)
db, err := sql.Open("postgres", dbConn)
db, err := sql.Open("postgres", cli.DBConn)
if err != nil {
log.Fatalln("database:", err)
return fmt.Errorf("database: %w", err)
}
err = setupDB(db)
if err != nil {
log.Fatalln("database:", err)
return fmt.Errorf("database: %w", err)
}
for {
@ -87,16 +83,6 @@ func setupDB(db *sql.DB) error {
return err
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS UserMovement (
Day TIMESTAMP NOT NULL,
Added INTEGER NOT NULL,
Bounced INTEGER NOT NULL,
Removed INTEGER NOT NULL
)`)
if err != nil {
return err
}
_, err = db.Exec(`CREATE TABLE IF NOT EXISTS Performance (
Day TIMESTAMP NOT NULL,
TotFiles INTEGER NOT NULL,
@ -136,11 +122,6 @@ func setupDB(db *sql.DB) error {
_, _ = db.Exec(`CREATE INDEX VersionDayIndex ON VersionSummary (Day)`)
}
row = db.QueryRow(`SELECT 'MovementDayIndex'::regclass`)
if err := row.Scan(&t); err != nil {
_, _ = db.Exec(`CREATE INDEX MovementDayIndex ON UserMovement (Day)`)
}
row = db.QueryRow(`SELECT 'PerformanceDayIndex'::regclass`)
if err := row.Scan(&t); err != nil {
_, _ = db.Exec(`CREATE INDEX PerformanceDayIndex ON Performance (Day)`)
@ -185,87 +166,6 @@ func aggregateVersionSummary(db *sql.DB, since time.Time) (int64, error) {
return res.RowsAffected()
}
func aggregateUserMovement(db *sql.DB) (int64, error) {
rows, err := db.Query(`SELECT
DATE_TRUNC('day', Received) AS Day,
Report->>'uniqueID'
FROM ReportsJson
WHERE
Report->>'uniqueID' IS NOT NULL
AND Received < DATE_TRUNC('day', NOW())
AND Report->>'version' like 'v_.%'
ORDER BY Day
`)
if err != nil {
return 0, err
}
defer rows.Close()
firstSeen := make(map[string]time.Time)
lastSeen := make(map[string]time.Time)
var minTs time.Time
minTs = minTs.In(time.UTC)
for rows.Next() {
var ts time.Time
var id string
if err := rows.Scan(&ts, &id); err != nil {
return 0, err
}
if minTs.IsZero() {
minTs = ts
}
if _, ok := firstSeen[id]; !ok {
firstSeen[id] = ts
}
lastSeen[id] = ts
}
type sumRow struct {
day time.Time
added int
removed int
bounced int
}
var sumRows []sumRow
for t := minTs; t.Before(time.Now().Truncate(24 * time.Hour)); t = t.AddDate(0, 0, 1) {
var added, removed, bounced int
old := t.Before(time.Now().AddDate(0, 0, -30))
for id, first := range firstSeen {
last := lastSeen[id]
if first.Equal(t) && last.Equal(t) && old {
bounced++
continue
}
if first.Equal(t) {
added++
}
if last == t && old {
removed++
}
}
sumRows = append(sumRows, sumRow{t, added, removed, bounced})
}
tx, err := db.Begin()
if err != nil {
return 0, err
}
if _, err := tx.Exec("DELETE FROM UserMovement"); err != nil {
tx.Rollback()
return 0, err
}
for _, r := range sumRows {
if _, err := tx.Exec("INSERT INTO UserMovement (Day, Added, Removed, Bounced) VALUES ($1, $2, $3, $4)", r.day, r.added, r.removed, r.bounced); err != nil {
tx.Rollback()
return 0, err
}
}
return int64(len(sumRows)), tx.Commit()
}
func aggregatePerformance(db *sql.DB, since time.Time) (int64, error) {
res, err := db.Exec(`INSERT INTO Performance (
SELECT

File diff suppressed because it is too large Load Diff

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import (
"regexp"
@ -145,7 +145,7 @@ func statsForFloats(data []float64) [4]float64 {
return res
}
func group(by func(string) string, as []analytic, perGroup int) []analytic {
func group(by func(string) string, as []analytic, perGroup int, otherPct float64) []analytic {
var res []analytic
next:
@ -170,6 +170,25 @@ next:
}
sort.Sort(analyticList(res))
if otherPct > 0 {
// Groups with less than otherPCt go into "Other"
other := analytic{
Key: "Other",
}
for i := 0; i < len(res); i++ {
if res[i].Percentage < otherPct || res[i].Key == "Other" {
other.Count += res[i].Count
other.Percentage += res[i].Percentage
res = append(res[:i], res[i+1:]...)
i--
}
}
if other.Count > 0 {
res = append(res, other)
}
}
return res
}

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import "testing"

View File

@ -4,7 +4,7 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.
package main
package serve
import (
"bytes"

1114
cmd/ursrv/serve/serve.go Normal file

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 61 KiB

View File

@ -197,7 +197,7 @@ found in the LICENSE file.
};
var baseLayer = L.tileLayer(
'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
'https://tile.openstreetmap.org/{z}/{x}/{y}.png',{
attribution: '...',
maxZoom: 18
}
@ -454,13 +454,13 @@ found in the LICENSE file.
<table class="table table-striped">
<thead>
<tr>
<th>Builder</th>
<th>Distribution Channel</th>
<th class="text-right">Devices</th>
<th class="text-right">Share</th>
</tr>
</thead>
<tbody>
{{range .builders}}
{{range .distributions}}
<tr>
<td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td>
@ -475,13 +475,13 @@ found in the LICENSE file.
<table class="table table-striped">
<thead>
<tr>
<th>Distribution Channel</th>
<th>Builder</th>
<th class="text-right">Devices</th>
<th class="text-right">Share</th>
</tr>
</thead>
<tbody>
{{range .distributions}}
{{range .builders}}
<tr>
<td>{{.Key}}</td>
<td class="text-right">{{.Count}}</td>

18
go.mod
View File

@ -42,19 +42,19 @@ require (
github.com/quic-go/quic-go v0.34.0
github.com/rcrowley/go-metrics v0.0.0-20201227073835-cf1acfcdf475
github.com/sasha-s/go-deadlock v0.3.1
github.com/shirou/gopsutil/v3 v3.23.5
github.com/shirou/gopsutil/v3 v3.23.6
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2
github.com/syndtr/goleveldb v1.0.1-0.20220721030215-126854af5e6d
github.com/thejerf/suture/v4 v4.0.2
github.com/urfave/cli v1.22.14
github.com/vitrun/qart v0.0.0-20160531060029-bf64b92db6b0
golang.org/x/crypto v0.10.0
golang.org/x/mod v0.11.0 // indirect
golang.org/x/net v0.11.0
golang.org/x/sys v0.9.0
golang.org/x/text v0.10.0
golang.org/x/crypto v0.11.0
golang.org/x/mod v0.12.0 // indirect
golang.org/x/net v0.12.0
golang.org/x/sys v0.10.0
golang.org/x/text v0.11.0
golang.org/x/time v0.3.0
golang.org/x/tools v0.10.0
golang.org/x/tools v0.11.0
google.golang.org/protobuf v1.31.0
)
@ -65,7 +65,7 @@ require (
github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect
github.com/onsi/ginkgo/v2 v2.11.0 // indirect
github.com/oschwald/maxminddb-golang v1.11.0 // indirect
@ -76,7 +76,7 @@ require (
github.com/quic-go/qtls-go1-20 v0.2.2 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df // indirect
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 // indirect
)
// https://github.com/gobwas/glob/pull/55

37
go.sum
View File

@ -81,8 +81,8 @@ github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/greatroar/blobloom v0.7.2 h1:F30MGLHOcb4zr0pwCPTcKdlTM70rEgkf+LzdUPc5ss8=
github.com/greatroar/blobloom v0.7.2/go.mod h1:mjMJ1hh1wjGVfr93QIHJ6FfDNVrA0IELv8OvMHJxHKs=
github.com/hashicorp/golang-lru/v2 v2.0.4 h1:7GHuZcgid37q8o5i3QI9KMT4nCWQQ3Kx3Ov6bb9MfK0=
@ -172,8 +172,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD
github.com/sasha-s/go-deadlock v0.3.1 h1:sqv7fDNShgjcaxkO0JNcOAlr8B9+cV5Ey/OB71efZx0=
github.com/sasha-s/go-deadlock v0.3.1/go.mod h1:F73l+cr82YSh10GxyRI6qZiCgK64VaZjwesgfQ1/iLM=
github.com/sclevine/spec v1.4.0 h1:z/Q9idDcay5m5irkZ28M7PtQM4aOISzOpj4bUPkDee8=
github.com/shirou/gopsutil/v3 v3.23.5 h1:5SgDCeQ0KW0S4N0znjeM/eFHXXOKyv2dVNgRq/c9P6Y=
github.com/shirou/gopsutil/v3 v3.23.5/go.mod h1:Ng3Maa27Q2KARVJ0SPZF5NdrQSC3XHKP8IIWrHgMeLY=
github.com/shirou/gopsutil/v3 v3.23.6 h1:5y46WPI9QBKBbK7EEccUPNXpJpNrvPuTD0O2zHEHT08=
github.com/shirou/gopsutil/v3 v3.23.6/go.mod h1:j7QX50DrXYggrpN30W0Mo+I4/8U2UUIQrnrhqUeWrAU=
github.com/shoenig/go-m1cpu v0.1.6/go.mod h1:1JJMcUBvfNwpq05QDQVAnx3gUHr9IYF7GNg9SUEw2VQ=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
@ -184,7 +184,6 @@ github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals=
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syncthing/notify v0.0.0-20210616190510-c6b7342338d2 h1:F4snRP//nIuTTW9LYEzVH4HVwDG9T3M4t8y/2nqMbiY=
@ -211,17 +210,17 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df h1:UA2aFVmmsIlefxMk29Dp2juaUSth8Pyn3Tq5Y5mJGME=
golang.org/x/exp v0.0.0-20230626212559-97b1e661b5df/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22 h1:FqrVOBQxQ8r/UwwXibI0KMolVhvFiGobSfdE33deHJM=
golang.org/x/exp v0.0.0-20230711023510-fffb14384f22/go.mod h1:FXUEEKJgO7OQYeo8N01OfiKP8RXMtf6e8aTskBGqWdc=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
@ -236,8 +235,8 @@ golang.org/x/net v0.0.0-20220607020251-c690dde0001d/go.mod h1:XRhObCWvk6IyKnWLug
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -275,9 +274,9 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
@ -288,8 +287,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
@ -300,8 +299,8 @@ golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
golang.org/x/tools v0.11.0 h1:EMCa6U9S2LtZXLAMoWiR/R8dAQFRqbAitmbJ2UKhoi8=
golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -52,6 +52,7 @@
"Cancel": "إلغاء",
"Changelog": "سجل التغيير",
"Clean out after": "نظف بعد",
"Cleaning Versions": "إصدارات نظيفة",
"Cleanup Interval": "الفاصل الزمني للتنظيف",
"Click to see full identification string and QR code.": "انقر لرؤية سلسلة التعريف الكاملة ورمز الاستجابة السريعة QR.",
"Close": "أغلق",
@ -65,6 +66,7 @@
"Connection Error": "خطأ في الإتصال",
"Connection Type": "نوع الاتصال",
"Connections": "اتصالات",
"Connections via relays might be rate limited by the relay": "قد يكون معدل التوصيلات عبر المرحلات محدودًا بواسطة المرحل",
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "مراقبة الملفات بشكل مستمر متوفر في Syncthing. يتم فحص الملفات التي تم تغييرها في المسار فقط. هذا يساعد على تجنب فحص كامل المسار لأداء اسرع. ",
"Copied from elsewhere": "منسوخ من مكان أخر",
"Copied from original": "منسوخ من الأصل",
@ -83,12 +85,18 @@
"Default Ignore Patterns": "أنماط التجاهل الافتراضية",
"Defaults": "الافتراضات",
"Delete": "حذف",
"Delete Unexpected Items": "حذف العناصر غير المتوقعة",
"Deleted {%file%}": "حُذِفت {{file}}",
"Deselect All": "الغاء تحديد الكل",
"Deselect devices to stop sharing this folder with.": "قم بإلغاء تحديد الأجهزة لإيقاف مشاركة هذا المجلد معها.",
"Deselect folders to stop sharing with this device.": "قم بإلغاء تحديد المجلدات لإيقاف المشاركة مع هذا الجهاز.",
"Device": "جهاز",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "الجهاز \"{{الاسم}}\" ({{الجهاز}} في {{العنوان}}) يرغب في الاتصال، إضافة جهاز جديد؟",
"Device Certificate": "شهادة الجهاز",
"Device ID": "هوية الجهاز",
"Device Identification": "هوية الجهاز",
"Device Name": "أسم الجهاز",
"Device is untrusted, enter encryption password": "الجهاز غير موثوق به، أدخل كلمة مرور التشفير",
"Device rate limits": "حدود معدل نقل البيانات",
"Device that last modified the item": "اخر جهاز جهاز عدل على العنصر",
"Devices": "الأجهزة",
@ -97,11 +105,17 @@
"Disabled periodic scanning and disabled watching for changes": "تعطيل المسح الدوري ومشاهدة التغييرات",
"Disabled periodic scanning and enabled watching for changes": "تعطيل المسح الدوري وتفعيل مشاهدة التغييرات",
"Disabled periodic scanning and failed setting up watching for changes, retrying every 1m:": "تعطيل المسح الدوري وفشل إعداد مشاهدة التغييرات، إعادة المحاولة كل 1 دقيقة:",
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "تعطيل مقارنة أذونات الملفات ومزامنتها. مفيد على الأنظمة ذات الأذونات غير الموجودة أو المخصصة (مثل FAT و exFAT و Synology و Android).",
"Discard": "تجاهل",
"Disconnected": "غير متصل",
"Disconnected (Inactive)": "غير متصل (غير نشط)",
"Disconnected (Unused)": "غير متصل (غير مستخدم)",
"Discovered": "مكتشفة",
"Discovery": "اكتشاف",
"Discovery Failures": "فشل الاكتشاف",
"Discovery Status": "حالة الاكتشاف",
"Dismiss": "رفض",
"Do not add it to the ignore list, so this notification may recur.": "لا تقم بإضافته إلى قائمة التجاهل، لذلك قد يتكرر هذا الإشعار.",
"Do not restore": "الغاء الاستعادة",
"Do not restore all": "الغاء استعادة الكل",
"Do you want to enable watching for changes for all your folders?": "هل تريد تفعيل مراقبة التغيرات على كل المجلدات؟",
@ -111,6 +125,7 @@
"Downloading": "جاري التحميل",
"Edit": "تعديل",
"Edit Device": "تعديل الجهاز",
"Edit Device Defaults": "تحرير الإعدادات الافتراضية للجهاز",
"Edit Folder": "تعديل المجلد",
"Editing {%path%}.": "تعديل {{path}}.",
"Enable Crash Reporting": "تفعيل التبليغ عن الاخطاء",

View File

@ -2,7 +2,7 @@
"A device with that ID is already added.": "Устройство с този идентификатор вече е добавено.",
"A negative number of days doesn't make sense.": "Отрицателният брой дни е безсмислен.",
"A new major version may not be compatible with previous versions.": "Ново значимо издание, което може да е несъвместимо с предните издания.",
"API Key": "Ключ за ППИ",
"API Key": "API Ключ",
"About": "Относно",
"Action": "Действие",
"Actions": "Действия",
@ -94,7 +94,7 @@
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "Устройство \"{{name}}\" ({{device}}) с адрес {{address}} желае да се свърже. Да бъде ли добавено?",
"Device Certificate": "Сертификат на устройството",
"Device ID": "Идентификатор на устройство",
"Device Identification": "Идентификатор на устройство",
"Device Identification": "Идентификация на устройство",
"Device Name": "Име на устройството",
"Device is untrusted, enter encryption password": "Устройството е недоверено, въведете парола за шифроване",
"Device rate limits": "Ограничаване на скоростта",

View File

@ -6,7 +6,7 @@
"About": "À propos",
"Action": "Action",
"Actions": "Actions",
"Active filter rules": "Règles de filtrage actives",
"Active filter rules": "Filtres enregistrés",
"Add": "Ajouter",
"Add Device": "Ajouter l'appareil",
"Add Folder": "Ajouter un partage",
@ -135,8 +135,8 @@
"Enabled": "Activée",
"Enables sending extended attributes to other devices, and applying incoming extended attributes. May require running with elevated privileges.": "Active la synchronisation des attributs étendus. Cette option peut nécessiter d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending extended attributes to other devices, but not applying incoming extended attributes. This can have a significant performance impact. Always enabled when \"Sync Extended Attributes\" is enabled.": "Active l'envoi des attributs étendus mais ignore leur réception. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser les attributs étendus\".",
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Active la synchronisation de l'attribut \"Propriétaire\". Cette option nécessite habituellement d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Active l'envoi de l'attribut \"Propriétaire\" mais ignore sa réception. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser le propriétaire\".",
"Enables sending ownership information to other devices, and applying incoming ownership information. Typically requires running with elevated privileges.": "Active la synchronisation bidirectionnelle de l'attribut \"Propriétaire\". Cette option nécessite habituellement d'exécuter Syncthing avec élévation de privilèges.",
"Enables sending ownership information to other devices, but not applying incoming ownership information. This can have a significant performance impact. Always enabled when \"Sync Ownership\" is enabled.": "Active l'envoi de l'attribut local \"Propriétaire\" mais ignore sa réception de la part des autres appareils. Cette option peut provoquer une dégradation notable des performances. L'envoi est toujours activé si on choisit l'option \"Synchroniser l'appartenance\".",
"Enter a non-negative number (e.g., \"2.35\") and select a unit. Percentages are as part of the total disk size.": "Nombre positif (p.ex, \"2.35\") et unité. Pourcentage de l'espace disque total.",
"Enter a non-privileged port number (1024 - 65535).": "Entrez un numéro de port non-privilégié (1024 - 65535).",
"Enter comma separated (\"tcp://ip:port\", \"tcp://host:port\") addresses or \"dynamic\" to perform automatic discovery of the address.": "Entrer les adresses (\"tcp://ip:port\" ou \"tcp://hôte:port\") séparées par une virgule, ou \"dynamic\" afin d'activer la recherche automatique de l'adresse.",
@ -144,7 +144,7 @@
"Enter up to three octal digits.": "Entrez jusqu'à 3 chiffres octaux.",
"Error": "Erreur",
"Extended Attributes": "Attributs étendus",
"Extended Attributes Filter": "Filtre d'attributs étendus",
"Extended Attributes Filter": "Filtres d'attributs étendus",
"External": "Gestion externe",
"External File Versioning": "Gestion externe des versions de fichiers",
"Failed Items": "Éléments en échec",
@ -186,7 +186,7 @@
"Global Discovery Servers": "Serveurs de découverte globale",
"Global State": "État global",
"Help": "Aide (en anglais)",
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Remarque : quand la règle par défaut est le rejet, seules les règles de rejet sont prises en compte. Envisagez d'ajouter * (Accepter tout) comme dernière règle.",
"Hint: only deny-rules detected while the default is deny. Consider adding \"permit any\" as last rule.": "Remarque : vous n'avez indiqué que des filtres de refus alors que le comportement par défaut est déjà le refus. Envisagez d'ajouter * (Partager tout le reste) comme dernier filtre (coché) pour inverser le comportement par défaut.",
"Home page": "Page d'accueil",
"However, your current settings indicate you might not want it enabled. We have disabled automatic crash reporting for you.": "Cependant, vos réglages indiquent que vous pourriez souhaiter ne pas l'activer. Nous avons désactivé pour vous l'envoi automatique des rapports.",
"Identification": "Identifiant abrégé",
@ -253,7 +253,7 @@
"No": "Non",
"No File Versioning": "Sans",
"No files will be deleted as a result of this operation.": "Aucun fichier ne sera supprimé à la suite de cette opération.",
"No rules set": "Aucune règle définie (accepter tout)",
"No rules set": "Aucun filtre défini (partager tous les attributs)",
"No upgrades": "Pas de mises à jour",
"Not shared": "Non partagé",
"Notice": "Notification",
@ -336,7 +336,7 @@
"Send & Receive": "Envoi & réception",
"Send Extended Attributes": "Envoyer les attributs étendus",
"Send Only": "Envoi (lecture seule)",
"Send Ownership": "Envoyer le propriétaire",
"Send Ownership": "Envoyer l'appartenance",
"Set Ignores on Added Folder": "Définir des exclusions pour le nouveau partage",
"Settings": "Configuration",
"Share": "Partager",
@ -378,7 +378,7 @@
"Support": "Forum",
"Support Bundle": "Kit d'assistance",
"Sync Extended Attributes": "Synchroniser les attributs étendus",
"Sync Ownership": "Synchroniser le propriétaire",
"Sync Ownership": "Synchroniser l'appartenance",
"Sync Protocol Listen Addresses": "Adresses d'écoute du protocole de synchronisation",
"Sync Status": "État de la synchronisation",
"Syncing": "Synchronisation en cours",
@ -444,7 +444,7 @@
"Time": "Heure",
"Time the item was last modified": "Dernière modification de l'élément",
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "Pour connecter votre appareil avec celui nommé \"{{devicename}}\", ajoutez ce nouvel appareil distant portant cet identifiant de votre côté :",
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Activez les règles souhaitées en cochant la case. Laissez décoché pour ignorer la règle.",
"To permit a rule, have the checkbox checked. To deny a rule, leave it unchecked.": "Partagez l'attribut spécifié en cochant la case. Laissez décoché pour refuser (comportement par défaut dès la première règle pour les attributs non spécifiés).",
"Today": "Aujourd'hui",
"Trash Can": "Corbeille",
"Trash Can File Versioning": "Style poubelle",
@ -519,7 +519,7 @@
"full documentation": "Documentation complète ici (en anglais)",
"items": "élément(s)",
"modified": "modifié",
"permit": "accepter",
"permit": "partager tous les attributs",
"seconds": "secondes",
"theme-name-black": "Noir",
"theme-name-dark": "Sombre",

View File

@ -12,6 +12,7 @@
"Add Folder": "බහාලුමක් යොදන්න",
"Add Remote Device": "දුරස්ථ උපාංගයක් යොදන්න",
"Add devices from the introducer to our device list, for mutually shared folders.": "අන්‍යෝන්‍ය වශයෙන් බෙදා ගත් ෆෝල්ඩර සඳහා, අපගේ උපාංග ලැයිස්තුවට හඳුන්වා දෙන්නා වෙතින් උපාංග එක් කරන්න.",
"Add filter entry": "පෙරීමේ නිවේශිතයක් යොදන්න",
"Add ignore patterns": "නොසලකා හැරීමේ රටා එක් කරන්න",
"Add new folder?": "නව බහාලුම යොදනවාද?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "අතිරේකව සම්පූර්ණ නැවත පරිලෝකනය කිරීමේ පරතරය වැඩි වනු ඇත (වාර 60, එනම් 1h හි නව පෙරනිමිය). අංක තේරීමෙන් පසුව ඔබට සෑම ෆෝල්ඩරයක් සඳහාම එය අතින් වින්‍යාසගත කළ හැක.",
@ -37,14 +38,16 @@
"Are you sure you want to restore {%count%} files?": "ඔබට ගොනු {{count}} ක් ප්‍රත්‍යර්පණය කිරීමට වුවමනාද?",
"Are you sure you want to revert all local changes?": "ඔබට සියලු දේශීය වෙනස්කම් ප්‍රතිවර්තනය කිරීමට අවශ්‍ය බව විශ්වාසද?",
"Are you sure you want to upgrade?": "ඔබට උත්ශ්‍රේණි කිරීමට වුවමනාද?",
"Authors": "කතුවරුන්",
"Auto Accept": "ස්වයං පිළිගැනීම",
"Automatic Crash Reporting": "ස්වයංක්‍රීය බිඳවැටීම් වාර්තා කිරීම",
"Automatic Crash Reporting": "ස්වයංක්‍රීය බිඳවැටීම් වාර්තාකරණය",
"Automatic upgrade now offers the choice between stable releases and release candidates.": "ස්වයංක්‍රීය උත්ශ්‍රේණිගත කිරීම දැන් ස්ථායී නිකුතු සහ නිදහස් අපේක්ෂකයින් අතර තේරීම ඉදිරිපත් කරයි.",
"Automatic upgrades": "ස්වයංක්‍රීය උත්ශ්‍රේණි",
"Automatic upgrades are always enabled for candidate releases.": "අපේක්ෂක නිකුතු සඳහා ස්වයංක්‍රීය උත්ශ්‍රේණි කිරීම් සැමවිටම සක්‍රීය වේ.",
"Automatically create or share folders that this device advertises at the default path.": "මෙම උපාංගය පෙරනිමි මාර්ගයේ ප්‍රචාරණය කරන ෆෝල්ඩර ස්වයංක්‍රීයව සාදන්න හෝ බෙදාගන්න.",
"Available debug logging facilities:": "පවතින දෝශ නිරාකරණය කිරීමේ පහසුකම්:",
"Be careful!": "පරෙස්සම් වෙන්න!",
"Body:": "අන්තර්ගතය:",
"Bugs": "දෝෂ",
"Cancel": "අවලංගු",
"Changelog": "වෙනස්කම්",
@ -56,6 +59,8 @@
"Command": "විධානය",
"Comment, when used at the start of a line": "පේළියක ආරම්භයේ භාවිතා කරන විට අදහස් දක්වන්න",
"Compression": "සම්පීඩනය",
"Configuration Directory": "වින්‍යාස නාමාවලිය",
"Configuration File": "වින්‍යාස ගොනුව",
"Configured": "වින්‍යාසගතයි",
"Connected (Unused)": "සම්බන්ධයි (භාවිතයේ නැත)",
"Connection Error": "සම්බන්ධතාවයේ දෝෂයකි",
@ -64,10 +69,15 @@
"Continuously watching for changes is now available within Syncthing. This will detect changes on disk and issue a scan on only the modified paths. The benefits are that changes are propagated quicker and that less full scans are required.": "වෙනස්කම් සඳහා අඛණ්ඩව නැරඹීම දැන් සමමුහුර්තකරණය තුළ පවතී. මෙය තැටියේ වෙනස්කම් හඳුනාගෙන වෙනස් කරන ලද මාර්ගවල පමණක් ස්කෑන් කිරීමක් නිකුත් කරයි. ප්‍රතිලාභ නම් වෙනස්කම් ඉක්මනින් ප්‍රචාරණය වීම සහ අඩු සම්පූර්ණ ස්කෑන් අවශ්‍ය වීමයි.",
"Copied from elsewhere": "වෙනත් තැනකින් පිටපත් කර ඇත",
"Copied from original": "මුල් පිටපතෙන් පිටපත් කර ඇත",
"Copied!": "පිටපත් විය!",
"Copy": "පිටපතක්",
"Copy failed! Try to select and copy manually.": "පිටපත් වීමට අසමත් විය! අතින් තෝරා පිටපත් කිරීමට බලන්න.",
"Currently Shared With Devices": "දැනට උපාංග සමඟ බෙදාගෙන ඇත",
"Custom Range": "අභිරුචි පරාසය",
"Danger!": "අනතුර!",
"Database Location": "දත්ත සමුදායේ ස්ථානය",
"Debugging Facilities": "නිදොස්කරණ පහසුකම්",
"Default": "පෙරනිමි",
"Default Configuration": "පෙරනිමි වින්‍යාසය",
"Default Device": "පෙරනිමි උපාංගය",
"Default Folder": "පෙරනිමි බහාලුම",
@ -81,6 +91,7 @@
"Deselect folders to stop sharing with this device.": "මෙම උපාංගය සමඟ බෙදා ගැනීම නැවැත්වීමට ෆෝල්ඩර තේරීම ඉවත් කරන්න.",
"Device": "උපාංගය",
"Device \"{%name%}\" ({%device%} at {%address%}) wants to connect. Add new device?": "උපාංගය \"{{name}}\" ({{device}} ට {{address}}) සම්බන්ධ වීමට අවශ්‍යයි. නව උපාංගයක් එක් කරන්නද?",
"Device Certificate": "උපාංගයේ සහතිකය",
"Device ID": "උපාංගයේ හැඳු.",
"Device Identification": "උපාංගයේ හැඳුනුම",
"Device Name": "උපාංගයේ නම",
@ -96,26 +107,27 @@
"Disables comparing and syncing file permissions. Useful on systems with nonexistent or custom permissions (e.g. FAT, exFAT, Synology, Android).": "ගොනු අවසර සංසන්දනය කිරීම සහ සමමුහුර්ත කිරීම අබල කරයි. නොපවතින හෝ අභිරුචි අවසර සහිත පද්ධති මත ප්‍රයෝජනවත් වේ (උදා: FAT, exFAT, Synology, Android).",
"Discard": "ඉවතලන්න",
"Disconnected": "විසන්ධියි",
"Disconnected (Inactive)": "විසන්ධියි (අක්‍රිය)",
"Disconnected (Unused)": "විසන්ධියි (භාවිතයේ නැත)",
"Discovered": "සොයා ගන්නා ලදී",
"Discovery": "සොයාගැනීම",
"Discovery Failures": "සොයාගැනීමේ අසාර්ථකත්වය",
"Discovery Status": "සොයාගැනීමේ තත්ත්වය",
"Discovery Status": "සොයාගැනීමේ තත්වය",
"Dismiss": "අහකට",
"Do not add it to the ignore list, so this notification may recur.": "එය නොසලකා හැරීමේ ලැයිස්තුවට එක් නොකරන්න, එබැවින් මෙම දැනුම්දීම නැවත සිදු විය හැක.",
"Do not restore": "ප්‍රත්‍යර්පණය නොකරන්න",
"Do not restore all": "සියල්ල ප්‍රත්‍යර්පණය නොකරන්න",
"Do you want to enable watching for changes for all your folders?": "ඔබට ඔබගේ සියලුම ෆෝල්ඩර සඳහා වෙනස්කම් නැරඹීම සබල කිරීමට අවශ්‍යද?",
"Documentation": "ප්‍රලේඛනය",
"Download Rate": "බාගත කිරීමේ අනුපාතය",
"Download Rate": "බාගැනීමේ අනුපාතය",
"Downloaded": "බාගත වී ඇත",
"Downloading": "බාගැනෙමින්",
"Edit": "සංස්කරණය",
"Edit Device": "උපාංගය සංස්කරණය",
"Edit Device Defaults": "උපාංග පෙරනිමි සංස්කරණය කරන්න",
"Edit Device Defaults": "පෙරනිමි සංස්කරණය කරන්න",
"Edit Folder": "බහාලුම සංස්කරණය",
"Edit Folder Defaults": "ෆෝල්ඩර පෙරනිමි සංස්කරණය කරන්න",
"Editing {%path%}.": "සංස්කරණය {{path}}.",
"Editing {%path%}.": "{{path}} සංශෝධනය.",
"Enable Crash Reporting": "බිඳවැටීම් වාර්තා කිරීම සබල කරන්න",
"Enable NAT traversal": "NAT සංක්‍රමණය සබල කරන්න",
"Enable Relaying": "Relaying සබල කරන්න",
@ -127,11 +139,11 @@
"Enter up to three octal digits.": "අෂ්ටක ඉලක්කම් තුනක් දක්වා ඇතුළු කරන්න.",
"Error": "දෝෂයකි",
"External": "බාහිර",
"External File Versioning": "බාහිර ගොනු අනුවාදය",
"External File Versioning": "බාහිර ගොනු අනුවාදය",
"Failed Items": "අසාර්ථක අයිතම",
"Failed to load file versions.": "ගොනු අනුවාද පූරණය කිරීමට අසමත් විය.",
"Failed to load ignore patterns.": "නොසලකා හැරීමේ රටා පූරණය කිරීමට අසමත් විය.",
"Failed to setup, retrying": "පිහිටුවීමට අසමත් විය, නැවත උත්සාහ කරමින්",
"Failed to setup, retrying": "පිහිටුවීමට අසමත් විය, උත්සාහ කරමින්",
"Failure to connect to IPv6 servers is expected if there is no IPv6 connectivity.": "IPv6 සම්බන්ධතාවක් නොමැති නම් IPv6 සේවාදායක වෙත සම්බන්ධ වීමට අසමත් වීම අපේක්ෂා කෙරේ.",
"File Pull Order": "ගොනු ඇදීමේ නියෝගය",
"File Versioning": "ගොනු අනුවාදය",
@ -151,12 +163,15 @@
"Folder type \"{%receiveEncrypted%}\" cannot be changed after adding the folder. You need to remove the folder, delete or decrypt the data on disk, and add the folder again.": "ෆෝල්ඩරය එකතු කිරීමෙන් පසු \"{{receiveEncrypted}}\" ෆෝල්ඩර වර්ගය වෙනස් කළ නොහැක. ඔබට ෆෝල්ඩරය ඉවත් කිරීම, තැටියේ ඇති දත්ත මකා දැමීම හෝ විකේතනය කිරීම සහ ෆෝල්ඩරය නැවත එක් කිරීම අවශ්ය වේ.",
"Folders": "බහාලුම්",
"For the following folders an error occurred while starting to watch for changes. It will be retried every minute, so the errors might go away soon. If they persist, try to fix the underlying issue and ask for help if you can't.": "පහත ෆෝල්ඩර සඳහා වෙනස්කම් නැරඹීමට පටන් ගැනීමේදී දෝෂයක් ඇති විය. එය සෑම මිනිත්තුවකම නැවත උත්සාහ කරනු ඇත, එබැවින් දෝෂ ඉක්මනින් පහව යනු ඇත. ඒවා දිගටම පවතින්නේ නම්, යටින් පවතින ගැටලුව විසඳීමට උත්සාහ කර ඔබට නොහැකි නම් උදව් ඉල්ලන්න.",
"Full Rescan Interval (s)": "සම්පූර්ණ නැවත ස්කෑන් පරතරය (ය)",
"Forever": "සදහටම",
"Full Rescan Interval (s)": "පූර්ණ සුපිරික්සීමේ පරතරය (ත.)",
"GUI": "GUI",
"GUI / API HTTPS Certificate": "GUI / යෙ.ක්‍ර.මු. HTTPS සහතිකය",
"GUI Authentication Password": "GUI සත්‍යාපන මුරපදය",
"GUI Authentication User": "GUI සත්‍යාපන පරිශ්‍රීලක",
"GUI Authentication: Set User and Password": "GUI සත්‍යාපනය: පරිශ්‍රීලක හා මුරපදය සකසන්න",
"GUI Listen Address": "GUI සවන්දීමේ ලිපිනය",
"GUI Override Directory": "GUI අභිබවන නාමාවලිය",
"GUI Theme": "GUI තේමාව",
"General": "සාමාන්‍ය",
"Generate": "උත්පාදනය",
@ -174,7 +189,7 @@
"Ignore Permissions": "අවසර නොසලකන්න",
"Ignore patterns can only be added after the folder is created. If checked, an input field to enter ignore patterns will be presented after saving.": "නොසලකා හැරීමේ රටා එකතු කළ හැක්කේ ෆෝල්ඩරය නිර්මාණය කිරීමෙන් පසුව පමණි. පරීක්ෂා කළහොත්, නොසලකා හැරීමේ රටා ඇතුළු කිරීමට ආදාන ක්ෂේත්‍රයක් සුරැකීමෙන් පසුව ඉදිරිපත් කෙරේ.",
"Ignored Devices": "නොසැලකූ උපාංග",
"Ignored Folders": "නොසැලකූ බහාලුම්",
"Ignored Folders": "නොසලකන බහාලුම්",
"Ignored at": "දී නොසලකා හරින ලදී",
"Incoming Rate Limit (KiB/s)": "එන අනුපාත සීමාව (KiB/s)",
"Incorrect configuration may damage your folder contents and render Syncthing inoperable.": "වැරදි වින්‍යාසය ඔබගේ ෆෝල්ඩර අන්තර්ගතයට හානි කළ හැකි අතර සමමුහුර්ත කිරීම අක්‍රිය කරයි.",
@ -191,6 +206,7 @@
"Last seen": "අවසන දුටුවේ",
"Latest Change": "නවතම වෙනස",
"Learn more": "තව දැනගන්න",
"Learn more at {%url%}": "{{url}} හරහා තව දැනගන්න",
"Limit": "සීමාව",
"Listener Failures": "සවන්දෙන්නන්ගේ අසාර්ථකත්වය",
"Listener Status": "සවන්දෙන්නන්ගේ තත්ත්වය",
@ -198,49 +214,58 @@
"Loading data...": "දත්ත පූරණය වෙමින්...",
"Loading...": "පූරණය වෙමින්...",
"Local Additions": "දේශීය එකතු කිරීම්",
"Local Discovery": "ස්ථානීය සොයාගැනීම",
"Local Discovery": "ස්ථානීය සොයාගැනීම",
"Local State": "ස්ථානීය තත්‍වය",
"Local State (Total)": "ස්ථානීය තත්‍වය (මුළු)",
"Locally Changed Items": "දේශීයව වෙනස් කරන ලද අයිතම",
"Log": "සටහන",
"Log File": "සටහන් ගොනුව",
"Log tailing paused. Scroll to the bottom to continue.": "ලොග් වලිගය විරාම කරන ලදී. ඉදිරියට යාමට පහළට අනුචලනය කරන්න.",
"Logs": "සටහන්",
"Major Upgrade": "ප්රධාන උත්ශ්රේණි කිරීම",
"Major Upgrade": "ප්රධාන උත්ශ්රේණි කිරීම",
"Mass actions": "මහා ක්‍රියා",
"Maximum Age": "උපරිම වයස",
"Maximum single entry size": "තනි නිවේශිතයක උපරිම ප්‍රමාණය",
"Maximum total size": "උපරිම මුළු ප්‍රමාණය",
"Metadata Only": "පාරදත්ත පමණි",
"Minimum Free Disk Space": "අවම තැටියේ ඉඩ",
"Mod. Device": "mod. උපාංගය",
"Mod. Time": "mod. කාලය",
"More than a month ago": "මාසයකට පෙර",
"More than a week ago": "සතියකට පෙර",
"More than a year ago": "වසරකට පෙර",
"Move to top of queue": "පෝලිමේ මුලට ගෙනයන්න",
"Multi level wildcard (matches multiple directory levels)": "බහු මට්ටමේ වයිල්ඩ්කාඩ් (බහු ඩිරෙක්ටරි මට්ටම් වලට ගැලපේ)",
"Never": "කවදාවත්",
"New Device": "නව උපාංගය",
"New Folder": "නව බහාලුම",
"Newest First": "අලුත්ම මුලින්ම",
"Newest First": "නව දෑ පළමුව",
"No": "නැහැ",
"No File Versioning": "ගොනු අනුවාදනයක් නැත",
"No files will be deleted as a result of this operation.": "මෙම මෙහෙයුමේ ප්‍රතිඵලයක් ලෙස කිසිදු ගොනුවක් මකා නොදමනු ඇත.",
"No rules set": "නීති සකසා නැත",
"No upgrades": "උත්ශ්‍රේණි නැත",
"Not shared": "බෙදාගෙන නැත",
"Notice": "දැන්වීම",
"OK": "හරි",
"Off": "අක්‍රියයි",
"Oldest First": "පැරණිතම පළමු",
"Oldest First": "පරණ දෑ පළමුව",
"Optional descriptive label for the folder. Can be different on each device.": "ෆෝල්ඩරය සඳහා විකල්ප විස්තර ලේබලය. එක් එක් උපාංගය මත වෙනස් විය හැක.",
"Options": "විකල්ප",
"Out of Sync": "සමමුහර්ත නොවේ",
"Out of Sync Items": "අයිතම සමමුහුර්ත නොවේ",
"Out of Sync": "සමමුහර්ත නොවේ",
"Out of Sync Items": "සමමුහූර්ත නොවන අථක",
"Outgoing Rate Limit (KiB/s)": "පිටතට යන ගාස්තු සීමාව (KiB/s)",
"Override": "අභිබවන්න",
"Override Changes": "වෙනස්කම් අභිබවන්න",
"Ownership": "අයිතිය",
"Path": "මාර්ගය",
"Path to the folder on the local computer. Will be created if it does not exist. The tilde character (~) can be used as a shortcut for": "දේශීය පරිගණකයේ ෆෝල්ඩරය වෙත මාර්ගය. එය නොමැති නම් නිර්මාණය වනු ඇත. tilde අක්ෂරය (~) සඳහා කෙටි මගක් ලෙස භාවිතා කළ හැක",
"Path where versions should be stored (leave empty for the default .stversions directory in the shared folder).": "අනුවාද ගබඩා කළ යුතු මාර්ගය (බෙදාගත් ෆෝල්ඩරයේ පෙරනිමි .stversions නාමාවලිය සඳහා හිස්ව තබන්න).",
"Pause": "විරාමය",
"Pause All": "සියල්ල විරාමය",
"Paused": "විරාමයි",
"Paused (Unused)": "විරාමයි (භාවිතා නොකළ)",
"Paths": "මාර්ග",
"Pause": "විරාමයක්",
"Pause All": "සියල්ලට විරාමයක්",
"Paused": "විරාමයකි",
"Paused (Unused)": "විරාමයකි (භාවිතා නොකළ)",
"Pending changes": "පොරොත්තු වෙනස්කම්",
"Periodic scanning at given interval and disabled watching for changes": "ලබා දී ඇති කාල සීමාව තුළ වරින් වර ස්කෑන් කිරීම සහ වෙනස්කම් සඳහා අබල කර බැලීම",
"Periodic scanning at given interval and enabled watching for changes": "ලබා දී ඇති කාල සීමාව තුළ වරින් වර ස්කෑන් කිරීම සහ වෙනස්කම් සඳහා නැරඹීම සබල කර ඇත",
@ -251,9 +276,12 @@
"Please wait": "රැඳෙන්න",
"Prefix indicating that the file can be deleted if preventing directory removal": "නාමාවලිය ඉවත් කිරීම වළක්වන්නේ නම් ගොනුව මකා දැමිය හැකි බව පෙන්නුම් කරන උපසර්ගය",
"Prefix indicating that the pattern should be matched without case sensitivity": "සංවේදිතාවකින් තොරව රටාව ගැලපිය යුතු බව පෙන්නුම් කරන උපසර්ගය",
"Preparing to Sync": "සමමුහූර්තයට සූදානම් ස්ථානයේ",
"Preparing to Sync": "සමමුහූර්තයට සූදානම් වෙමින්",
"Preview": "පෙරදසුන",
"Preview Usage Report": "භාවිත වාර්තාවේ පෙරදසුන",
"QR code": "QR කේතය",
"QUIC LAN": "QUIC LAN",
"QUIC WAN": "QUIC WAN",
"Quick guide to supported patterns": "සහාය දක්වන රටා සඳහා ඉක්මන් මාර්ගෝපදේශය",
"Random": "අහඹු",
"Receive Encrypted": "සංකේතිිතව ලබන්න",
@ -269,15 +297,15 @@
"Remove Device": "උපාංගය ඉවත් කරන්න",
"Remove Folder": "බහාලුම ඉවත් කරන්න",
"Required identifier for the folder. Must be the same on all cluster devices.": "ෆෝල්ඩරය සඳහා අවශ්‍ය හඳුනාගැනීම. සියලුම පොකුරු උපාංග මත සමාන විය යුතුය.",
"Rescan": "නැවත ස්කෑන් කරන්න",
"Rescan All": "සියල්ල නැවත ස්කෑන් කරන්න",
"Rescan": "යළි සුපිරික්සන්න",
"Rescan All": "සියල්ල යළි සුපිරික්සන්න",
"Rescans": "නැවත ස්කෑන් කරයි",
"Restart": "යළි අරඹන්න",
"Restart Needed": "නැවත ආරම්භ කිරීම අවශ්‍යයි",
"Restarting": "යළි ඇරඹෙමින්",
"Restore": "ප්‍රත්‍යර්පණය",
"Restore Versions": "අනුවාද ප්‍රත්‍යර්පණය",
"Resume": "අරඹන්",
"Resume": "ැවතත්",
"Resume All": "සියල්ල නැවතත්",
"Reused": "යළි භාවිත",
"Revert": "ආපසු හරවන්න",
@ -294,10 +322,13 @@
"Select oldest version": "පරණම අනුවාදය තෝරන්න",
"Send & Receive": "යැවීම සහ ලැබීම",
"Send Only": "යැවීම පමණි",
"Send Ownership": "අයිතිය යවන්න",
"Set Ignores on Added Folder": "එකතු කළ ෆෝල්ඩරයේ නොසලකා හැරීම් සකසන්න",
"Settings": "සැකසුම්",
"Share": "බෙදාගන්න",
"Share Folder": "බහාලුම බෙදාගන්න",
"Share by Email": "වි-තැපෑලෙන් බෙදාගන්න",
"Share by SMS": "කෙටි පණිවුඩ මගින් බෙදාගන්න",
"Share this folder?": "මෙම බහාලුම බෙදා ගන්නද?",
"Shared Folders": "බෙදාගත් බහාලුම්",
"Shared With": "සමඟ බෙදාගෙන ඇත",
@ -329,10 +360,14 @@
"Statistics": "සංඛ්‍යාලේඛන",
"Stopped": "නැවැත්තුවා",
"Stores and syncs only encrypted data. Folders on all connected devices need to be set up with the same password or be of type \"{%receiveEncrypted%}\" too.": "සංකේතනය කළ දත්ත පමණක් ගබඩා කර සමමුහුර්ත කරයි. සියලුම සම්බන්ධිත උපාංගවල ඇති ෆෝල්ඩර එකම මුරපදයකින් හෝ \"{{receiveEncrypted}}\" වර්ගයට අයත් විය යුතුය.",
"Subject:": "මාතෘකාව:",
"Support": "සහාය",
"Support Bundle": "ආධාරක බණ්ඩලය",
"Sync Ownership": "සමමුහූර්ත අයිතිය",
"Sync Protocol Listen Addresses": "ප්‍රොටෝකෝලය සවන්දීමේ ලිපින සමමුහුර්ත කරන්න",
"Sync Status": "සමමුහූර්ත තත්‍වය",
"Syncing": "සමමුහූර්තය",
"Syncthing device ID for \"{%devicename%}\"": "\"{{devicename}}\" සඳහා සයින්තින් උපාංගයේ හැඳු.",
"Syncthing has been shut down.": "සමමුහුර්ත කිරීම වසා ඇත.",
"Syncthing includes the following software or portions thereof:": "සමමුහුර්තකරණයට පහත මෘදුකාංග හෝ එහි කොටස් ඇතුළත් වේ:",
"Syncthing is Free and Open Source Software licensed as MPL v2.0.": "සමමුහුර්ත කිරීම MPL v2.0 ලෙස බලපත්‍ර ලබා ඇති නිදහස් සහ විවෘත මූලාශ්‍ර මෘදුකාංගයකි.",
@ -343,6 +378,8 @@
"Syncthing now supports automatically reporting crashes to the developers. This feature is enabled by default.": "සමමුහුර්තකරණය දැන් සංවර්ධකයින්ට බිඳවැටීම් ස්වයංක්‍රීයව වාර්තා කිරීමට සහය දක්වයි. මෙම විශේෂාංගය පෙරනිමියෙන් සක්රිය කර ඇත.",
"Syncthing seems to be down, or there is a problem with your Internet connection. Retrying…": "සමමුහුර්ත කිරීම අක්‍රිය වී ඇති බවක් පෙනේ, නැතහොත් ඔබගේ අන්තර්ජාල සම්බන්ධතාවයේ ගැටලුවක් තිබේ. නැවත උත්සාහ කරමින්…",
"Syncthing seems to be experiencing a problem processing your request. Please refresh the page or restart Syncthing if the problem persists.": "සමමුහුර්ත කිරීම ඔබගේ ඉල්ලීම සැකසීමේ ගැටලුවක් අත්විඳින බව පෙනේ. ගැටලුව දිගටම පවතින්නේ නම් කරුණාකර පිටුව නැවුම් කරන්න හෝ සමමුහුර්ත කිරීම නැවත ආරම්භ කරන්න.",
"TCP LAN": "TCP LAN",
"TCP WAN": "TCP WAN",
"Take me back": "මාව ආපසු ගන්න",
"The GUI address is overridden by startup options. Changes here will not take effect while the override is in place.": "GUI ලිපිනය ආරම්භක විකල්ප මගින් අභිබවා යයි. ප්‍රතික්‍ෂේප කිරීම ක්‍රියාත්මක වන විට මෙහි වෙනස්කම් බල නොපායි.",
"The Syncthing Authors": "සයින්තින් කතුවරුන්",
@ -363,6 +400,7 @@
"The following items could not be synchronized.": "පහත අථක සමමුහූර්ත කිරීමට නොහැකිය.",
"The following items were changed locally.": "පහත අථක ස්ථානීයව වෙනස් කර ඇත.",
"The following methods are used to discover other devices on the network and announce this device to be found by others:": "ජාලයේ වෙනත් උපාංග සොයා ගැනීමට සහ මෙම උපාංගය අන් අය විසින් සොයා ගන්නා ලෙස නිවේදනය කිරීමට පහත ක්‍රම භාවිතා කරයි:",
"The following text will automatically be inserted into a new message.": "පහත පෙළ නව පණිවිඩයකට ස්වයංක්‍රීයව ඇතුළු කෙරේ.",
"The following unexpected items were found.": "පහත අනපේක්‍ෂිත අථක හමු විය.",
"The interval must be a positive number of seconds.": "පරතරය ධනාත්මක තත්පර ගණනක් විය යුතුය.",
"The interval, in seconds, for running cleanup in the versions directory. Zero to disable periodic cleaning.": "අනුවාද නාමාවලිය තුළ පිරිසිදු කිරීම ධාවනය කිරීම සඳහා තත්පර කිහිපයකින් පරතරය. ආවර්තිතා පිරිසිදු කිරීම අක්රිය කිරීමට ශුන්ය.",
@ -389,6 +427,7 @@
"This setting controls the free space required on the home (i.e., index database) disk.": "මෙම සිටුවම නිවසේ (එනම්, දර්ශක දත්ත ගබඩාව) තැටියේ අවශ්‍ය නිදහස් ඉඩ පාලනය කරයි.",
"Time": "කාලය",
"Time the item was last modified": "අයිතමය අවසන් වරට වෙනස් කළ වේලාව",
"To connect with the Syncthing device named \"{%devicename%}\", add a new remote device on your end with this ID:": "\"{{devicename}}\" සයින්තින් උපාංගය සමඟ සම්බන්ධ වීමට, මෙම හැඳු. සහිත නව දුරස්ථ උපාංගයක් ඔබගේ පසට එක් කරන්න:",
"Today": "අද",
"Trash Can": "කසල බඳුන",
"Trash Can File Versioning": "කුණු කූඩය ගොනු අනුවාදය",
@ -417,6 +456,10 @@
"Use HTTPS for GUI": "GUI සඳහා HTTPS භාවිතා කරන්න",
"Use notifications from the filesystem to detect changed items.": "වෙනස් කළ අයිතම හඳුනා ගැනීමට ගොනු පද්ධතියෙන් දැනුම්දීම් භාවිතා කරන්න.",
"Username/Password has not been set for the GUI authentication. Please consider setting it up.": "GUI සත්‍යාපනය සඳහා පරිශීලක නාමය/මුරපදය සකසා නොමැත. කරුණාකර එය පිහිටුවීම සලකා බලන්න.",
"Using a QUIC connection over LAN": "LAN හරහා QUIC සම්බන්ධතාවයක් භාවිතය",
"Using a QUIC connection over WAN": "WAN හරහා QUIC සම්බන්ධතාවයක් භාවිතය",
"Using a direct TCP connection over LAN": "LAN හරහා සෘජු TCP සම්බන්ධතාවයක් භාවිතය",
"Using a direct TCP connection over WAN": "WAN හරහා සෘජු TCP සම්බන්ධතාවයක් භාවිතය",
"Version": "අනුවාදය",
"Versions": "අනුවාද",
"Versions Path": "අනුවාද මාර්ගය",
@ -437,19 +480,28 @@
"When adding a new folder, keep in mind that the Folder ID is used to tie folders together between devices. They are case sensitive and must match exactly between all devices.": "නව ෆෝල්ඩරයක් එකතු කරන විට, උපාංග අතර ෆෝල්ඩර එකට ගැටගැසීමට ෆෝල්ඩර හැඳුනුම්පත භාවිතා කරන බව මතක තබා ගන්න. ඒවා සිද්ධි සංවේදී වන අතර සියලුම උපාංග අතර හරියටම ගැළපිය යුතුය.",
"Yes": "ඔව්",
"Yesterday": "ඊයේ",
"You can also copy and paste the text into a new message manually.": "ඔබට අතින් නව පණිවිඩයකට පෙළ පිටපත් කර ඇලවීමට හැකිය.",
"You can also select one of these nearby devices:": "මෙම ආසන්න උපාංග වලින් එකක් ද තේරීමට හැකිය:",
"You can change your choice at any time in the Settings dialog.": "සැකසුම් තුළ ඕනෑම විටෙක ඔබගේ තේරීම වෙනස් කිරීමට හැකිය.",
"You can read more about the two release channels at the link below.": "පහත සබැඳියෙන් නිකුතු නාලිකා දෙක ගැන තවත් කියවීමට හැකිය.",
"You have no ignored devices.": "නොසලකා හරින ලද උපාංග නැත.",
"You have no ignored folders.": "නොසලකා හරි ලද බහාලුම් නැත.",
"You have no ignored folders.": "නොසලකන බහාලුම් නැත.",
"You have unsaved changes. Do you really want to discard them?": "ඔබ සතුව නොසුරැකි වෙනස්කම් ඇත. ඒවා ඉවතලීමට වුවමනාද?",
"You must keep at least one version.": "අවම වශයෙන් එක් අනුවාදයක් තබා ගත යුතුය.",
"You should never add or change anything locally in a \"{%receiveEncrypted%}\" folder.": "ඔබ කිසිවිටෙක \"{{receiveEncrypted}}\" ෆෝල්ඩරයකට දේශීයව කිසිවක් එකතු කිරීම හෝ වෙනස් කිරීම නොකළ යුතුය.",
"Your SMS app should open to let you choose the recipient and send it from your own number.": "ලබන්නා තේරීමට සහ එය ඔබගේම අංකයෙන් යැවීමට කෙටි පණිවිඩ යෙදුම විවෘත විය යුතුය.",
"Your email app should open to let you choose the recipient and send it from your own address.": "ලබන්නා තේරීමට සහ එය ඔබගේම ලිපිනයෙන් යැවීමට වි-තැපැල් යෙදුම විවෘත විය යුතුය.",
"days": "දවස්",
"deleted": "මකා ඇත",
"deny": "ප්‍රතිෂේධනය",
"directories": "නාමාවලි",
"file": "ගොනුව",
"files": "ගොනු",
"folder": "බහාලුම",
"full documentation": "පූර්ණ ප්‍රලේඛනය",
"items": "අථක",
"modified": "සංශෝධිතයි",
"permit": "අවසරය",
"seconds": "තත්පර",
"theme-name-black": "කළු",
"theme-name-dark": "අඳුරු",

View File

@ -11,6 +11,7 @@
"Add Folder": "添加資料夾",
"Add Remote Device": "新增遠端裝置",
"Add devices from the introducer to our device list, for mutually shared folders.": "對於共享的資料夾,匯入引入者的裝置清單。",
"Add ignore patterns": "新增忽略模式",
"Add new folder?": "新增資料夾?",
"Additionally the full rescan interval will be increased (times 60, i.e. new default of 1h). You can also configure it manually for every folder later after choosing No.": "另外,完整地重新掃瞄的間隔將增大(時間 60例如新的預設值為 1 小時)。您也可以在選擇「否」後,手動配置每個資料夾的時間間隔。",
"Address": "位址",
@ -18,6 +19,7 @@
"Advanced": "進階",
"Advanced Configuration": "進階配置",
"All Data": "全部資料",
"All Time": "所有時間",
"All folders shared with this device must be protected by a password, such that all sent data is unreadable without the given password.": "所有與此裝置分享的資料夾必須使用密碼保護起來,如此一來,沒有提供密碼將無法閱覽資料。",
"Allow Anonymous Usage Reporting?": "允許回報匿名數據?",
"Allowed Networks": "允許的網路",

View File

@ -555,8 +555,8 @@
<tr>
<th><span class="fas fa-fw fa-share-alt"></span>&nbsp;<span translate>Shared With</span></th>
<td class="text-right no-overflow-ellipse word-break-all">
<span ng-repeat="device in folder.devices">
<span ng-if="device.deviceID != myID" ng-switch="completion[device.deviceID][folder.id].remoteState">
<span ng-repeat="device in otherDevices(folder.devices)">
<span ng-switch="completion[device.deviceID][folder.id].remoteState">
<span ng-switch-when="notSharing" data-original-title="{{'The remote device has not accepted sharing this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>1</sup><span ng-if="!$last">,</span></span>
<span ng-switch-when="paused" data-original-title="{{'The remote device has paused this folder.' | translate}}" tooltip>{{deviceName(devices[device.deviceID])}}<sup>2</sup><span ng-if="!$last">,</span></span>
<span ng-switch-default>{{deviceName(devices[device.deviceID])}}<span ng-if="!$last">,</span></span>

View File

@ -26,7 +26,7 @@
<h4 class="text-center" translate>The Syncthing Authors</h4>
<div class="row">
<div class="col-md-12" id="contributor-list">
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Tomasz Wilczyński, Wulf Weich, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, Eric Lesiuta, Eric P, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, bt90, chenrui, chucic, cui fliter, derekriemer, desbma, entity0xfe, georgespatton, ghjklw, guangwu, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, luzpaz, marco-m, mclang, mv1005, otbutz, overkill, perewa, red_led, rubenbe, sec65, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
Jakob Borg, Audrius Butkevicius, Jesse Lucas, Simon Frei, Alexander Graf, Alexandre Viau, Anderson Mesquita, André Colomb, Antony Male, Ben Schulz, Caleb Callaway, Daniel Harte, Evgeny Kuznetsov, Lars K.W. Gohlke, Lode Hoste, Michael Ploujnikov, Nate Morrison, Philippe Schommers, Ryan Sullivan, Sergey Mishin, Stefan Tatschner, Tomasz Wilczyński, Wulf Weich, greatroar, Aaron Bieber, Adam Piggott, Adel Qalieh, Alan Pope, Alberto Donato, Aleksey Vasenev, Alessandro G., Alex Lindeman, Alex Xu, Alexander Seiler, Alexandre Alves, Aman Gupta, Andreas Sommer, Andrew Dunham, Andrew Meyer, Andrew Rabert, Andrey D, Anjan Momi, Anthony Goeckner, Antoine Lamielle, Anur, Aranjedeath, Arkadiusz Tymiński, Aroun, Arthur Axel fREW Schmidt, Artur Zubilewicz, Aurélien Rainone, BAHADIR YILMAZ, Bart De Vries, Ben Curthoys, Ben Shepherd, Ben Sidhom, Benedikt Heine, Benedikt Morbach, Benjamin Nater, Benno Fünfstück, Benny Ng, Boqin Qin, Boris Rybalkin, Brandon Philips, Brendan Long, Brian R. Becker, Carsten Hagemann, Cathryne Linenweaver, Cedric Staniewski, Chih-Hsuan Yen, Choongkyu, Chris Howie, Chris Joel, Chris Tonkinson, Christian Prescott, Colin Kennedy, Cromefire_, Cyprien Devillez, Dale Visser, Dan, Daniel Barczyk, Daniel Bergmann, Daniel Martí, Darshil Chanpura, David Rimmer, Denis A., Dennis Wilson, Devon G. Redekopp, Dimitri Papadopoulos Orfanos, Dmitry Saveliev, Domenic Horner, Dominik Heidler, Elias Jarlebring, Elliot Huffman, Emil Hessman, Eng Zer Jun, Eric Lesiuta, Eric P, Erik Meitner, Evan Spensley, Federico Castagnini, Felix, Felix Ableitner, Felix Lampe, Felix Unterpaintner, Francois-Xavier Gsell, Frank Isemann, Gahl Saraf, Gilli Sigurdsson, Gleb Sinyavskiy, Graham Miln, Greg, Han Boetes, HansK-p, Harrison Jones, Heiko Zuerker, Hugo Locurcio, Iain Barnett, Ian Johnson, Ikko Ashimine, Ilya Brin, Iskander Sharipov, Jaakko Hannikainen, Jacek Szafarkiewicz, Jack Croft, Jacob, Jake Peterson, James O'Beirne, James Patterson, Jaroslav Lichtblau, Jaroslav Malec, Jauder Ho, Jaya Chithra, Jaya Kumar, Jeffery To, Jens Diemer, Jerry Jacobs, Jochen Voss, Johan Andersson, Johan Vromans, John Rinehart, Jonas Thelemann, Jonathan, Jonathan Cross, Jonta, Jose Manuel Delicado, Jörg Thalheim, Jędrzej Kula, K.B.Dharun Krishna, Kalle Laine, Karol Różycki, Kebin Liu, Keith Turner, Kelong Cong, Ken'ichi Kamada, Kevin Allen, Kevin Bushiri, Kevin White, Jr., Kurt Fitzner, LSmithx2, Lars Lehtonen, Laurent Arnoud, Laurent Etiemble, Leo Arias, Liu Siyuan, Lord Landon Agahnim, Lukas Lihotzki, Majed Abdulaziz, Marc Laporte, Marc Pujol, Marcin Dziadus, Marcus Legendre, Mario Majila, Mark Pulford, Martchus, Mateusz Naściszewski, Mateusz Ż, Matic Potočnik, Matt Burke, Matt Robenolt, Matteo Ruina, Maurizio Tomasi, Max, Max Schulze, MaximAL, Maxime Thirouin, MichaIng, Michael Jephcote, Michael Rienstra, Michael Tilli, Migelo, Mike Boone, MikeLund, MikolajTwarog, Mingxuan Lin, Naveen, Nicholas Rishel, Nick Busey, Nico Stapelbroek, Nicolas Braud-Santoni, Nicolas Perraut, Niels Peter Roest, Nils Jakobi, NinoM4ster, Nitroretro, NoLooseEnds, Oliver Freyermuth, Otiel, Oyebanji Jacob Mayowa, Pablo, Pascal Jungblut, Paul Brit, Pawel Palenica, Paweł Rozlach, Peter Badida, Peter Dave Hello, Peter Hoeg, Peter Marquardt, Phani Rithvij, Phil Davis, Phill Luby, Pier Paolo Ramon, Piotr Bejda, Pramodh KP, Quentin Hibon, Rahmi Pruitt, Richard Hartmann, Robert Carosi, Roberto Santalla, Robin Schoonover, Roman Zaynetdinov, Ross Smith II, Ruslan Yevdokymov, Ryan Qian, Sacheendra Talluri, Scott Klupfel, Shaarad Dalvi, Simon Mwepu, Sly_tom_cat, Stefan Kuntz, Steven Eckhoff, Suhas Gundimeda, Taylor Khan, Thomas Hipp, Tim Abell, Tim Howes, Tobias Klauser, Tobias Nygren, Tobias Tom, Tom Jakubowski, Tommy Thorn, Tully Robinson, Tyler Brazier, Tyler Kropp, Unrud, Veeti Paananen, Victor Buinsky, Vik, Vil Brekin, Vladimir Rusinov, Will Rouesnel, William A. Kennington III, Xavier O., Yannic A., andresvia, andyleap, boomsquared, bt90, chenrui, chucic, cui fliter, derekriemer, desbma, entity0xfe, georgespatton, ghjklw, guangwu, ignacy123, janost, jaseg, jelle van der Waa, jtagcat, klemens, luzpaz, marco-m, mclang, mv1005, otbutz, overkill, perewa, red_led, rubenbe, sec65, villekalliomaki, wangguoliang, wouter bolsterlee, xarx00, xjtdy888, 佛跳墙, 落心
</div>
</div>
</div>

View File

@ -1892,8 +1892,11 @@ angular.module('syncthing.core')
}
};
$scope.otherDevices = function () {
return $scope.deviceList().filter(function (n) {
$scope.otherDevices = function (devices) {
if (devices === undefined) {
devices = $scope.deviceList();
}
return devices.filter(function (n) {
return n.deviceID !== $scope.myID;
});
};
@ -3048,7 +3051,11 @@ angular.module('syncthing.core')
arch += " Container";
}
return $scope.version.version + ', ' + os + ' (' + arch + ')';
var verStr = $scope.version.version;
if ($scope.version.extra) {
verStr += ' (' + $scope.version.extra + ')';
}
return verStr + ', ' + os + ' (' + arch + ')';
};
$scope.versionBase = function () {

View File

@ -324,7 +324,7 @@
</div>
</div>
<div class="row" ng-if="currentFolder.syncXattrs">
<div class="row" ng-if="currentFolder.syncXattrs || currentFolder.sendXattrs">
<div class="col-md-12">
<p>
<label translate>Extended Attributes Filter</label>

View File

@ -723,6 +723,7 @@ func (*service) getSystemVersion(w http.ResponseWriter, _ *http.Request) {
"version": build.Version,
"codename": build.Codename,
"longVersion": build.LongVersion,
"extra": build.Extra,
"os": runtime.GOOS,
"arch": runtime.GOARCH,
"isBeta": build.IsBeta,

View File

@ -35,6 +35,7 @@ var (
IsCandidate bool
IsBeta bool
LongVersion string
Extra string
allowedVersionExp = regexp.MustCompile(`^v\d+\.\d+\.\d+(-[a-z0-9]+)*(\.\d+)*(\+\d+-g[0-9a-f]+)?(-[^\s]+)?$`)
@ -46,6 +47,8 @@ var (
}
)
const versionExtraAllowedChars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-. "
func init() {
if Version != "unknown-dev" {
// If not a generic dev build, version string should come from git describe
@ -75,6 +78,7 @@ func setBuildData() {
IsRelease = exp.MatchString(Version)
IsCandidate = strings.Contains(Version, "-rc.")
IsBeta = strings.Contains(Version, "-")
Extra = filterString(os.Getenv("STVERSIONEXTRA"), versionExtraAllowedChars)
stamp, _ := strconv.Atoi(Stamp)
Date = time.Unix(int64(stamp), 0)
@ -103,7 +107,22 @@ func TagsList() []string {
tags = append(tags, strings.ToLower(envVar))
}
}
if Extra != "" {
tags = append(tags, Extra)
}
sort.Strings(tags)
return tags
}
// filterString returns a copy of s with all characters not in allowedChars
// removed.
func filterString(s, allowedChars string) string {
var res strings.Builder
for _, c := range s {
if strings.ContainsRune(allowedChars, c) {
res.WriteRune(c)
}
}
return res.String()
}

View File

@ -35,3 +35,23 @@ func TestAllowedVersions(t *testing.T) {
}
}
}
func TestFilterString(t *testing.T) {
cases := []struct {
input string
filter string
output string
}{
{"abcba", "abc", "abcba"},
{"abcba", "ab", "abba"},
{"abcba", "c", "c"},
{"abcba", "!", ""},
{"Foo (v1.5)", versionExtraAllowedChars, "Foo v1.5"},
}
for i, c := range cases {
if out := filterString(c.input, c.filter); out != c.output {
t.Errorf("%d: %q != %q", i, out, c.output)
}
}
}

View File

@ -22,8 +22,8 @@ import (
var (
errInvalidFilenameEmpty = errors.New("name is invalid, must not be empty")
errInvalidFilenameWindowsSpacePeriod = errors.New("name is invalid, must not end in space or period on Windows")
errInvalidFilenameWindowsReservedName = errors.New("name is invalid, contains Windows reserved name (NUL, COM1, etc.)")
errInvalidFilenameWindowsReservedChar = errors.New("name is invalid, contains Windows reserved character (?, *, etc.)")
errInvalidFilenameWindowsReservedName = errors.New("name is invalid, contains Windows reserved name")
errInvalidFilenameWindowsReservedChar = errors.New("name is invalid, contains Windows reserved character")
)
type OptionJunctionsAsDirs struct{}

View File

@ -54,8 +54,8 @@ const windowsDisallowedCharacters = (`<>:"|?*` +
func WindowsInvalidFilename(name string) error {
// The path must not contain any disallowed characters.
if strings.ContainsAny(name, windowsDisallowedCharacters) {
return errInvalidFilenameWindowsReservedChar
if idx := strings.IndexAny(name, windowsDisallowedCharacters); idx != -1 {
return fmt.Errorf("%w: %q", errInvalidFilenameWindowsReservedChar, name[idx:idx+1])
}
// None of the path components should end in space or period, or be a
@ -72,8 +72,8 @@ func WindowsInvalidFilename(name string) error {
// Names ending in space or period are not valid.
return errInvalidFilenameWindowsSpacePeriod
}
if windowsIsReserved(part) {
return errInvalidFilenameWindowsReservedName
if reserved := windowsReservedNamePart(part); reserved != "" {
return fmt.Errorf("%w: %q", errInvalidFilenameWindowsReservedName, reserved)
}
}
@ -117,13 +117,13 @@ func SanitizePath(path string) string {
}
path = strings.TrimSpace(b.String())
if windowsIsReserved(path) {
if reserved := windowsReservedNamePart(path); reserved != "" {
path = "-" + path
}
return path
}
func windowsIsReserved(part string) bool {
func windowsReservedNamePart(part string) string {
// nul.txt.jpg is also disallowed.
dot := strings.IndexByte(part, '.')
if dot != -1 {
@ -132,7 +132,7 @@ func windowsIsReserved(part string) bool {
// Check length to skip allocating ToUpper.
if len(part) != 3 && len(part) != 4 {
return false
return ""
}
// COM0 and LPT0 are missing from the Microsoft docs,
@ -144,9 +144,9 @@ func windowsIsReserved(part string) bool {
"COM5", "COM6", "COM7", "COM8", "COM9",
"LPT0", "LPT1", "LPT2", "LPT3", "LPT4",
"LPT5", "LPT6", "LPT7", "LPT8", "LPT9":
return true
return part
}
return false
return ""
}
// IsParent compares paths purely lexicographically, meaning it returns false

View File

@ -7,6 +7,7 @@
package fs
import (
"errors"
"math/rand"
"testing"
"unicode"
@ -69,9 +70,10 @@ func TestWindowsInvalidFilename(t *testing.T) {
for _, tc := range cases {
err := WindowsInvalidFilename(tc.name)
if err != tc.err {
if !errors.Is(err, tc.err) {
t.Errorf("For %q, got %v, expected %v", tc.name, err, tc.err)
}
t.Logf("%s: %v", tc.name, err)
}
}
@ -124,9 +126,11 @@ func benchmarkWindowsInvalidFilename(b *testing.B, name string) {
WindowsInvalidFilename(name)
}
}
func BenchmarkWindowsInvalidFilenameValid(b *testing.B) {
benchmarkWindowsInvalidFilename(b, "License.txt.gz")
}
func BenchmarkWindowsInvalidFilenameNUL(b *testing.B) {
benchmarkWindowsInvalidFilename(b, "nul.txt.gz")
}

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "STDISCOSRV" "1" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "STDISCOSRV" "1" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
stdiscosrv \- Syncthing Discovery Server
.SH SYNOPSIS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "STRELAYSRV" "1" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "STRELAYSRV" "1" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
strelaysrv \- Syncthing Relay Server
.SH SYNOPSIS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-BEP" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-BEP" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-bep \- Block Exchange Protocol v1
.SH INTRODUCTION AND DEFINITIONS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-CONFIG" "5" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-CONFIG" "5" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-config \- Syncthing Configuration
.SH SYNOPSIS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-DEVICE-IDS" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-DEVICE-IDS" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-device-ids \- Understanding Device IDs
.sp

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-EVENT-API" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-EVENT-API" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-event-api \- Event API
.SH DESCRIPTION

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-FAQ" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-FAQ" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-faq \- Frequently Asked Questions
.INDENT 0.0

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-GLOBALDISCO" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-GLOBALDISCO" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-globaldisco \- Global Discovery Protocol v3
.SH ANNOUNCEMENTS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-LOCALDISCO" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-LOCALDISCO" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-localdisco \- Local Discovery Protocol v4
.SH MODE OF OPERATION

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-NETWORKING" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-NETWORKING" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-networking \- Firewall Setup
.SH ROUTER SETUP

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-RELAY" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-RELAY" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-relay \- Relay Protocol v1
.SH WHAT IS A RELAY?

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-REST-API" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-REST-API" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-rest-api \- REST API
.sp

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-SECURITY" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-SECURITY" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-security \- Security Principles
.sp

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-STIGNORE" "5" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-STIGNORE" "5" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-stignore \- Prevent files from being synchronized to other nodes
.SH SYNOPSIS

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING-VERSIONING" "7" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING-VERSIONING" "7" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing-versioning \- Keep automatic backups of deleted files by other nodes
.sp

View File

@ -27,7 +27,7 @@ level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
..
.TH "SYNCTHING" "1" "Jun 12, 2023" "v1.23.5" "Syncthing"
.TH "SYNCTHING" "1" "Jul 08, 2023" "v1.23.6" "Syncthing"
.SH NAME
syncthing \- Syncthing
.SH SYNOPSIS