Compare commits
230 Commits
0.6.0
...
ldap-non-anon
| Author | SHA1 | Date | |
|---|---|---|---|
| 6ef8ace025 | |||
| c26f2623a8 | |||
| 451c3b5c88 | |||
| af5674074d | |||
| 28380021a7 | |||
| 37cbf537bb | |||
| 9345a1b7a9 | |||
| d18f1d6d1d | |||
| 621258481d | |||
| ce285bac17 | |||
| a7e45bee11 | |||
| 73e075e216 | |||
| b7c7b6da9f | |||
| 703328601c | |||
| b2e7664339 | |||
| ed22c6b103 | |||
| 94ccbd6190 | |||
| 77edc4849f | |||
| 07da97f434 | |||
| 89dd6be7dd | |||
| 60c1a4264e | |||
| c4c177c530 | |||
| 4a5bffbd57 | |||
| 49b2296015 | |||
| 0ef4a06565 | |||
| 16b1337d67 | |||
| 6599179174 | |||
| f2411f4607 | |||
| 2c3d429b8e | |||
| 7562cf1e75 | |||
| de1c3f3245 | |||
| 5d38c3ad70 | |||
| b55c2ff2f0 | |||
| 056d68804a | |||
| 347bc653d8 | |||
| 6fcece3bc0 | |||
| e119c5bde9 | |||
| 1bc2749e1b | |||
| 58bb07d11d | |||
| affe24b9c6 | |||
| 0bcf063b05 | |||
| 24ecb15119 | |||
| 208c515d70 | |||
| d0ada7fc53 | |||
| d86bd898cb | |||
| db581a955b | |||
| 0b8b1bf25f | |||
| faab5f6b3b | |||
| 6387a1334b | |||
| 10be055381 | |||
| 24c9c7b5a1 | |||
| ac48744aca | |||
| f2d2ecb247 | |||
| 1d46bf8d50 | |||
| 4353f2a92d | |||
| 1b9aeae53c | |||
| 540b9af873 | |||
| d08d2c6958 | |||
| 348259a14b | |||
| e68ca1151d | |||
| 3c15f5a82f | |||
| 5ba823990a | |||
| c82c38fe52 | |||
| e7ab80d5c8 | |||
| 61b68c3a42 | |||
| 6401cb6fb7 | |||
| 9d37408535 | |||
| ded64e1cf0 | |||
| 3b766fc427 | |||
| ad285898f6 | |||
| 78be49d57d | |||
| 25e52788c5 | |||
| 5d25a64f13 | |||
| 0dc89fbf23 | |||
| 94ed0eec2a | |||
| d70e585b64 | |||
| 8f55e50c6e | |||
| c113c99e1d | |||
| 191239584b | |||
| bd1caaf5da | |||
| 76f7b5e7ac | |||
| afe449b951 | |||
| 29f0712ea1 | |||
| d091c24f79 | |||
| f9e7d2bb23 | |||
| dbf36ddf05 | |||
| 8b00853e88 | |||
| 84a3d53075 | |||
| 7967dd91c2 | |||
| b5eb2628f9 | |||
| 4ef6561cc6 | |||
| 7f54f418a8 | |||
| 8f90ea18bf | |||
| e12528aae4 | |||
| 042a1fd2b0 | |||
| be99fe5f99 | |||
| 4a212e5f9e | |||
| c253bdee54 | |||
| 46fc030df4 | |||
| 02277b1ace | |||
| ac507d1d42 | |||
| 5148349098 | |||
| e817941cc5 | |||
| 06962514fe | |||
| c3c8f6804b | |||
| 6dd730030d | |||
| 6c1dd6608d | |||
| 42fb0cf825 | |||
| 2483303138 | |||
| 47e67d9b64 | |||
| 1d042e1bb2 | |||
| 31418b1079 | |||
| 68d79bfa9c | |||
| a46b718937 | |||
| 5570494a37 | |||
| a0cd9dd6bd | |||
| cd5895d560 | |||
| fc8ee1c3bc | |||
| 2a8cc5f3ba | |||
| 82524c9dca | |||
| 864379fb81 | |||
| aae2073146 | |||
| 69963689f9 | |||
| 6ad3359609 | |||
| 6a2ba2260d | |||
| ccbf2124cb | |||
| a733ece26e | |||
| 16624fd742 | |||
| e18be6ec95 | |||
| 1bfed0294f | |||
| d4d32bcc11 | |||
| 0a148721de | |||
| cfe097edf4 | |||
| 578768d7df | |||
| 996dc309f7 | |||
| 09d9164a1c | |||
| 43f32d30cb | |||
| b1d7b3969d | |||
| 89fa208bec | |||
| a11205324b | |||
| 7d17b12000 | |||
| 885dcf91fe | |||
| 192c0f8efd | |||
| 35e71b0f8a | |||
| 1a24ba44b2 | |||
| 7c00d4a88a | |||
| 476310a217 | |||
| 26ffde726f | |||
| 3fd89e6b48 | |||
| be939cf169 | |||
| 4a15bef34f | |||
| 6eee4b0b65 | |||
| f720dcbe9a | |||
| 33fceddc08 | |||
| dfe83aafc5 | |||
| 0775c8f3f9 | |||
| 4cdc1a3655 | |||
| bbd415c392 | |||
| a236f33269 | |||
| 9b593c76e4 | |||
| 012c8d2026 | |||
| cb05571339 | |||
| 64e4550dea | |||
| ec8c17482d | |||
| f167aad0fb | |||
| 24aac22b89 | |||
| 615a5fe346 | |||
| a6699a7319 | |||
| 0f408bc738 | |||
| 44a7953c20 | |||
| 21069ea18e | |||
| 1e1fd49c8c | |||
| 84621d1d27 | |||
| ba4476bf5a | |||
| f87bc455b7 | |||
| 76ec0d2b13 | |||
| 4d547082e0 | |||
| b9b9af6c44 | |||
| 4a4534d6f3 | |||
| 894c4fee2c | |||
| 27a33c833d | |||
| b52d8e4e26 | |||
| b059fb48fc | |||
| f33b057961 | |||
| 663ca4f530 | |||
| 5892c0b088 | |||
| 044a24eac8 | |||
| b93ebedaf3 | |||
| 8539bdaf72 | |||
| c1abd3d6f9 | |||
| becb40544c | |||
| ee96d2b754 | |||
| 30093d3a9f | |||
| 29f2239e3f | |||
| 7f1b33a567 | |||
| d0dd23a1af | |||
| f8774223d4 | |||
| bca870f1f8 | |||
| 64d38c88e8 | |||
| 3ac94b3e43 | |||
| 254eef6a2a | |||
| f1255f477f | |||
| 6c7b95c1b9 | |||
| e7d17caf9d | |||
| 71dd80f125 | |||
| ed4761e841 | |||
| fe05f9a58e | |||
| 51e5a401a5 | |||
| f1990b782d | |||
| 4e3ed0f4c1 | |||
| fdb58215c0 | |||
| 47c8711933 | |||
| 20a099c16f | |||
| 3824e4ba25 | |||
| b163fc8423 | |||
| b50f723a4d | |||
| b778933c64 | |||
| 12b97ce713 | |||
| 4025a45d52 | |||
| 8a6d832513 | |||
| 0b0b3a158f | |||
| 6b745ca8f0 | |||
| 1f0cb7e05c | |||
| c59821945d | |||
| 1a723b78b7 | |||
| e7ff7e3263 | |||
| 3a6c1aeeef | |||
| 567e011a66 | |||
| eaf63e0b17 | |||
| 63b31a9154 |
@@ -0,0 +1,10 @@
|
|||||||
|
[target.wasm32-unknown-unknown]
|
||||||
|
# required for clippy
|
||||||
|
rustflags = [
|
||||||
|
"--cfg", "web_sys_unstable_apis",
|
||||||
|
]
|
||||||
|
|
||||||
|
[target.x86_64-unknown-linux-gnu]
|
||||||
|
rustflags = [
|
||||||
|
"--cfg", "web_sys_unstable_apis",
|
||||||
|
]
|
||||||
+13
-9
@@ -10,7 +10,7 @@ executors:
|
|||||||
type: boolean
|
type: boolean
|
||||||
default: false
|
default: false
|
||||||
docker:
|
docker:
|
||||||
- image: plumeorg/plume-buildenv:v0.3.0
|
- image: plumeorg/plume-buildenv:v0.4.0
|
||||||
- image: <<#parameters.postgres>>circleci/postgres:9.6-alpine<</parameters.postgres>><<^parameters.postgres>>alpine:latest<</parameters.postgres>>
|
- image: <<#parameters.postgres>>circleci/postgres:9.6-alpine<</parameters.postgres>><<^parameters.postgres>>alpine:latest<</parameters.postgres>>
|
||||||
environment:
|
environment:
|
||||||
POSTGRES_USER: postgres
|
POSTGRES_USER: postgres
|
||||||
@@ -21,6 +21,7 @@ executors:
|
|||||||
RUST_TEST_THREADS: 1
|
RUST_TEST_THREADS: 1
|
||||||
FEATURES: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
FEATURES: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
||||||
DATABASE_URL: <<#parameters.postgres>>postgres://postgres@localhost/plume<</parameters.postgres>><<^parameters.postgres>>plume.sqlite<</parameters.postgres>>
|
DATABASE_URL: <<#parameters.postgres>>postgres://postgres@localhost/plume<</parameters.postgres>><<^parameters.postgres>>plume.sqlite<</parameters.postgres>>
|
||||||
|
ROCKET_SECRET_KEY: VN5xV1DN7XdpATadOCYcuGeR/dV0hHfgx9mx9TarLdM=
|
||||||
|
|
||||||
|
|
||||||
commands:
|
commands:
|
||||||
@@ -71,7 +72,7 @@ commands:
|
|||||||
type: string
|
type: string
|
||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
export RUSTFLAGS="-Zprofile -Zfewer-names -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Zno-landing-pads -Clink-arg=-Xlinker -Clink-arg=--no-keep-memory -Clink-arg=-Xlinker -Clink-arg=--reduce-memory-overheads"
|
export RUSTFLAGS="-Zprofile -Zfewer-names -Ccodegen-units=1 -Cinline-threshold=0 -Clink-dead-code -Coverflow-checks=off -Clink-arg=-Xlinker -Clink-arg=--no-keep-memory -Clink-arg=-Xlinker -Clink-arg=--reduce-memory-overheads"
|
||||||
export CARGO_INCREMENTAL=0
|
export CARGO_INCREMENTAL=0
|
||||||
<< parameters.cmd >>
|
<< parameters.cmd >>
|
||||||
|
|
||||||
@@ -99,7 +100,7 @@ commands:
|
|||||||
steps:
|
steps:
|
||||||
- run: |
|
- run: |
|
||||||
cmd="cargo build <<#parameters.release>>--release<</parameters.release>> --no-default-features --features="${FEATURES}" -p <<parameters.package>> -j"
|
cmd="cargo build <<#parameters.release>>--release<</parameters.release>> --no-default-features --features="${FEATURES}" -p <<parameters.package>> -j"
|
||||||
for i in 36 4 2 1 1; do
|
for i in 16 4 2 1 1; do
|
||||||
$cmd $i && exit 0
|
$cmd $i && exit 0
|
||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
@@ -143,11 +144,14 @@ jobs:
|
|||||||
cache: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
cache: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
||||||
- run_with_coverage:
|
- run_with_coverage:
|
||||||
cmd: |
|
cmd: |
|
||||||
|
cargo build -p plume-cli --no-default-features --features=${FEATURES} -j 4
|
||||||
|
./target/debug/plm migration run
|
||||||
|
./target/debug/plm search init
|
||||||
cmd="cargo test --all --exclude plume-front --exclude plume-macro --no-run --no-default-features --features=${FEATURES} -j"
|
cmd="cargo test --all --exclude plume-front --exclude plume-macro --no-run --no-default-features --features=${FEATURES} -j"
|
||||||
for i in 36 4 2 1 1; do
|
for i in 16 4 2 1 1; do
|
||||||
$cmd $i && break
|
$cmd $i && break
|
||||||
done
|
done
|
||||||
cargo test --all --exclude plume-front --exclude plume-macro --no-default-features --features="${FEATURES}" -j1 -- --test-threads=1
|
cargo test --all --exclude plume-front --exclude plume-macro --no-default-features --features="${FEATURES}" -j1
|
||||||
- upload_coverage:
|
- upload_coverage:
|
||||||
type: unit
|
type: unit
|
||||||
- cache:
|
- cache:
|
||||||
@@ -164,18 +168,18 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- restore_env:
|
- restore_env:
|
||||||
cache: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
cache: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
||||||
- run: cargo web deploy -p plume-front
|
- run: wasm-pack build --target web --release plume-front
|
||||||
- run_with_coverage:
|
- run_with_coverage:
|
||||||
cmd: |
|
cmd: |
|
||||||
cmd="cargo install --debug --no-default-features --features="${FEATURES}",test --force --path . -j"
|
cmd="cargo install --debug --no-default-features --features="${FEATURES}",test --force --path . -j"
|
||||||
for i in 36 4 2 1 1; do
|
for i in 16 4 2 1 1; do
|
||||||
$cmd $i && exit 0
|
$cmd $i && exit 0
|
||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
- run_with_coverage:
|
- run_with_coverage:
|
||||||
cmd: |
|
cmd: |
|
||||||
cmd="cargo install --debug --no-default-features --features="${FEATURES}" --force --path plume-cli -j"
|
cmd="cargo install --debug --no-default-features --features="${FEATURES}" --force --path plume-cli -j"
|
||||||
for i in 36 4 2 1 1; do
|
for i in 16 4 2 1 1; do
|
||||||
$cmd $i && exit 0
|
$cmd $i && exit 0
|
||||||
done
|
done
|
||||||
exit 1
|
exit 1
|
||||||
@@ -199,7 +203,7 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- restore_env:
|
- restore_env:
|
||||||
cache: release-<<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
cache: release-<<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
||||||
- run: cargo web deploy -p plume-front --release
|
- run: wasm-pack build --target web --release plume-front
|
||||||
- build:
|
- build:
|
||||||
package: plume
|
package: plume
|
||||||
release: true
|
release: true
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
FROM debian:buster-20201117
|
FROM debian:buster-20210208
|
||||||
ENV PATH="/root/.cargo/bin:${PATH}"
|
ENV PATH="/root/.cargo/bin:${PATH}"
|
||||||
|
|
||||||
#install native/circleci/build dependancies
|
#install native/circleci/build dependancies
|
||||||
@@ -11,12 +11,12 @@ RUN apt update &&\
|
|||||||
rm -rf /var/lib/apt/lists/*
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
#install and configure rust
|
#install and configure rust
|
||||||
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2020-12-07 -y &&\
|
RUN curl https://sh.rustup.rs -sSf | sh -s -- --default-toolchain nightly-2021-01-15 -y &&\
|
||||||
rustup component add rustfmt clippy &&\
|
rustup component add rustfmt clippy &&\
|
||||||
rustup component add rust-std --target wasm32-unknown-unknown
|
rustup component add rust-std --target wasm32-unknown-unknown
|
||||||
|
|
||||||
#compile some deps
|
#compile some deps
|
||||||
RUN cargo install cargo-web &&\
|
RUN cargo install wasm-pack &&\
|
||||||
cargo install grcov &&\
|
cargo install grcov &&\
|
||||||
strip /root/.cargo/bin/* &&\
|
strip /root/.cargo/bin/* &&\
|
||||||
rm -fr ~/.cargo/registry
|
rm -fr ~/.cargo/registry
|
||||||
|
|||||||
@@ -15,6 +15,9 @@ DATABASE_URL=postgres://plume:plume@localhost/plume
|
|||||||
# The domain of your instance
|
# The domain of your instance
|
||||||
BASE_URL=plu.me
|
BASE_URL=plu.me
|
||||||
|
|
||||||
|
# Log level for each crate
|
||||||
|
RUST_LOG=warn,html5ever=warn,hyper=warn,tantivy=warn
|
||||||
|
|
||||||
# The secret key for private cookies and CSRF protection
|
# The secret key for private cookies and CSRF protection
|
||||||
# You can generate one with `openssl rand -base64 32`
|
# You can generate one with `openssl rand -base64 32`
|
||||||
ROCKET_SECRET_KEY=
|
ROCKET_SECRET_KEY=
|
||||||
|
|||||||
@@ -19,3 +19,4 @@ search_index
|
|||||||
.buildconfig
|
.buildconfig
|
||||||
__pycache__
|
__pycache__
|
||||||
.vscode/
|
.vscode/
|
||||||
|
*-journal
|
||||||
|
|||||||
+22
-1
@@ -4,6 +4,27 @@
|
|||||||
|
|
||||||
## [Unreleased] - ReleaseDate
|
## [Unreleased] - ReleaseDate
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Allow `dir` attributes for LtoR text in RtoL document (#860)
|
||||||
|
- More translation languages (#862)
|
||||||
|
- Proxy support (#829)
|
||||||
|
- Riker a actor system library (#870)
|
||||||
|
- (request-target) and Host header in HTTP Signature (#872)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Upgrade some dependent crates (#858)
|
||||||
|
- Use tracing crate (#868)
|
||||||
|
- Update Rust version to nightly-2021-01-15 (#878)
|
||||||
|
- Upgrade Tantivy to 0.13.3 and lindera-tantivy to 0.7.1 (#878)
|
||||||
|
- Run searcher on actor system (#870)
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Percent-encode URI for remote_interact (#866, #857)
|
||||||
|
- Menu animation not opening on iOS (#876, #897)
|
||||||
|
|
||||||
## [[0.6.0]] - 2020-12-29
|
## [[0.6.0]] - 2020-12-29
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
@@ -34,7 +55,7 @@
|
|||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
- Validate spoofing of Create activity
|
- Validate spoofing of activity
|
||||||
|
|
||||||
## [0.5.0] - 2020-06-21
|
## [0.5.0] - 2020-06-21
|
||||||
|
|
||||||
|
|||||||
Generated
+2450
-2188
File diff suppressed because it is too large
Load Diff
+8
-8
@@ -1,7 +1,7 @@
|
|||||||
[package]
|
[package]
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
name = "plume"
|
name = "plume"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
repository = "https://github.com/Plume-org/Plume"
|
repository = "https://github.com/Plume-org/Plume"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
@@ -10,8 +10,7 @@ activitypub = "0.1.3"
|
|||||||
askama_escape = "0.1"
|
askama_escape = "0.1"
|
||||||
atom_syndication = "0.6"
|
atom_syndication = "0.6"
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
colored = "1.8"
|
dotenv = "0.15.0"
|
||||||
dotenv = "0.14"
|
|
||||||
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
||||||
gettext-macros = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
gettext-macros = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
||||||
gettext-utils = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
gettext-utils = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
||||||
@@ -20,19 +19,20 @@ heck = "0.3.0"
|
|||||||
lettre = "0.9.2"
|
lettre = "0.9.2"
|
||||||
lettre_email = "0.9.2"
|
lettre_email = "0.9.2"
|
||||||
num_cpus = "1.10"
|
num_cpus = "1.10"
|
||||||
rocket = "0.4.5"
|
rocket = "0.4.6"
|
||||||
rocket_contrib = { version = "0.4.5", features = ["json"] }
|
rocket_contrib = { version = "0.4.5", features = ["json"] }
|
||||||
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
||||||
rpassword = "4.0"
|
rpassword = "4.0"
|
||||||
scheduled-thread-pool = "0.2.2"
|
scheduled-thread-pool = "0.2.2"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
serde_qs = "0.5"
|
|
||||||
shrinkwraprs = "0.2.1"
|
shrinkwraprs = "0.2.1"
|
||||||
syntect = "3.3"
|
|
||||||
validator = "0.8"
|
validator = "0.8"
|
||||||
validator_derive = "0.8"
|
validator_derive = "0.8"
|
||||||
webfinger = "0.4.1"
|
webfinger = "0.4.1"
|
||||||
|
tracing = "0.1.22"
|
||||||
|
tracing-subscriber = "0.2.15"
|
||||||
|
riker = "0.4.2"
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "plume"
|
name = "plume"
|
||||||
@@ -48,7 +48,7 @@ version = "3.1.2"
|
|||||||
|
|
||||||
[dependencies.diesel]
|
[dependencies.diesel]
|
||||||
features = ["r2d2", "chrono"]
|
features = ["r2d2", "chrono"]
|
||||||
version = "*"
|
version = "1.4.5"
|
||||||
|
|
||||||
[dependencies.multipart]
|
[dependencies.multipart]
|
||||||
default-features = false
|
default-features = false
|
||||||
@@ -69,7 +69,7 @@ git = "https://github.com/fdb-hiroshima/rocket_csrf"
|
|||||||
rev = "29910f2829e7e590a540da3804336577b48c7b31"
|
rev = "29910f2829e7e590a540da3804336577b48c7b31"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
ructe = "0.9.0"
|
ructe = "0.13.0"
|
||||||
rsass = "0.9"
|
rsass = "0.9"
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
|||||||
+1
-1
@@ -19,7 +19,7 @@ RUN chmod a+x ./wasm-deps.sh && sleep 1 && ./wasm-deps.sh
|
|||||||
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY Cargo.toml Cargo.lock rust-toolchain ./
|
COPY Cargo.toml Cargo.lock rust-toolchain ./
|
||||||
RUN cargo install cargo-web
|
RUN cargo install wasm-pack
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -20,7 +20,7 @@ RUN chmod a+x ./wasm-deps.sh && sleep 1 && ./wasm-deps.sh
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
COPY Cargo.toml Cargo.lock rust-toolchain ./
|
COPY Cargo.toml Cargo.lock rust-toolchain ./
|
||||||
RUN cargo install diesel_cli --no-default-features --features postgres --version '=1.3.0'
|
RUN cargo install diesel_cli --no-default-features --features postgres --version '=1.3.0'
|
||||||
RUN cargo install cargo-web
|
RUN cargo install wasm-pack
|
||||||
|
|
||||||
COPY . .
|
COPY . .
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
* {
|
* {
|
||||||
font-family: monospace;
|
font-family: monospace;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,37 +64,37 @@ main header.article {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main .article-info {
|
main .article-info {
|
||||||
margin: 0 auto 3em;
|
margin: 0 auto 3em;
|
||||||
font-size: 0.95em;
|
font-size: 0.95em;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
.author, .author a {
|
.author, .author a {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The article itself */
|
/* The article itself */
|
||||||
main article {
|
main article {
|
||||||
max-width: $article-width;
|
max-width: $article-width;
|
||||||
margin: 2.5em auto;
|
margin: 2.5em auto;
|
||||||
font-family: $lora;
|
font-family: $lora;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
line-height: 1.7;
|
line-height: 1.7;
|
||||||
|
|
||||||
a:hover {
|
a:hover {
|
||||||
text-decoration: underline;
|
text-decoration: underline;
|
||||||
}
|
}
|
||||||
|
|
||||||
img {
|
img {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 3em auto;
|
margin: 3em auto;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
background: $gray;
|
background: $gray;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockquote {
|
blockquote {
|
||||||
@@ -126,7 +126,7 @@ main .article-meta {
|
|||||||
|
|
||||||
> p {
|
> p {
|
||||||
margin: 2em $horizontal-margin;
|
margin: 2em $horizontal-margin;
|
||||||
font-size: 0.9em;
|
font-size: 0.9em;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Article Tags */
|
/* Article Tags */
|
||||||
@@ -157,15 +157,15 @@ main .article-meta {
|
|||||||
/* Likes & Boosts */
|
/* Likes & Boosts */
|
||||||
.actions {
|
.actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
}
|
}
|
||||||
|
|
||||||
.likes, .reshares {
|
.likes, .reshares {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
padding: 0.5em 0;
|
padding: 0.5em 0;
|
||||||
|
|
||||||
p {
|
p {
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
@@ -175,34 +175,34 @@ main .article-meta {
|
|||||||
|
|
||||||
.action {
|
.action {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: none;
|
background: none;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
border: none;
|
border: none;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
svg.feather {
|
svg.feather {
|
||||||
transition: background 0.1s ease-in;
|
transition: background 0.1s ease-in;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
|
||||||
margin: 0.5em 0;
|
margin: 0.5em 0;
|
||||||
width: 2.5em;
|
width: 2.5em;
|
||||||
height: 2.5em;
|
height: 2.5em;
|
||||||
|
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.reshared, &.liked {
|
&.reshared, &.liked {
|
||||||
svg.feather {
|
svg.feather {
|
||||||
color: $background;
|
color: $background;
|
||||||
font-weight: 900;
|
font-weight: 900;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -213,14 +213,14 @@ main .article-meta {
|
|||||||
|
|
||||||
.action svg.feather {
|
.action svg.feather {
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: $red;
|
color: $red;
|
||||||
fill: none;
|
fill: none;
|
||||||
border: solid $red thin;
|
border: solid $red thin;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action:hover svg.feather {
|
.action:hover svg.feather {
|
||||||
background: transparentize($red, 0.85);
|
background: transparentize($red, 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action.liked svg.feather {
|
.action.liked svg.feather {
|
||||||
@@ -238,22 +238,22 @@ main .article-meta {
|
|||||||
|
|
||||||
.action svg.feather {
|
.action svg.feather {
|
||||||
padding: 0.7em;
|
padding: 0.7em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
color: $primary;
|
color: $primary;
|
||||||
border: solid $primary thin;
|
border: solid $primary thin;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action:hover svg.feather {
|
.action:hover svg.feather {
|
||||||
background: transparentize($primary, 0.85);
|
background: transparentize($primary, 0.85);
|
||||||
}
|
}
|
||||||
|
|
||||||
.action.reshared svg.feather {
|
.action.reshared svg.feather {
|
||||||
background: $primary;
|
background: $primary;
|
||||||
}
|
}
|
||||||
.action.reshared:hover svg.feather {
|
.action.reshared:hover svg.feather {
|
||||||
background: transparentize($primary, 0.75)
|
background: transparentize($primary, 0.75)
|
||||||
color: $primary;
|
color: $primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -262,9 +262,9 @@ main .article-meta {
|
|||||||
margin: 0 $horizontal-margin;
|
margin: 0 $horizontal-margin;
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
color: $primary;
|
color: $primary;
|
||||||
font-size: 1.5em;
|
font-size: 1.5em;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
|
|
||||||
summary {
|
summary {
|
||||||
@@ -279,16 +279,16 @@ main .article-meta {
|
|||||||
|
|
||||||
// Respond & delete comment buttons
|
// Respond & delete comment buttons
|
||||||
a.button, form.inline, form.inline input {
|
a.button, form.inline, form.inline input {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: none;
|
background: none;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
margin-right: 2em;
|
margin-right: 2em;
|
||||||
font-family: $route159;
|
font-family: $route159;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
color: $primary;
|
color: $primary;
|
||||||
padding-right: 0.5em;
|
padding-right: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover { color: $primary; }
|
&:hover { color: $primary; }
|
||||||
@@ -296,8 +296,8 @@ main .article-meta {
|
|||||||
|
|
||||||
.comment {
|
.comment {
|
||||||
margin: 1em 0;
|
margin: 1em 0;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
.content {
|
.content {
|
||||||
background: $gray;
|
background: $gray;
|
||||||
@@ -328,36 +328,36 @@ main .article-meta {
|
|||||||
color: transparentize($text-color, 0.6);
|
color: transparentize($text-color, 0.6);
|
||||||
}
|
}
|
||||||
|
|
||||||
.author {
|
.author {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
|
|
||||||
* {
|
* {
|
||||||
transition: all 0.1s ease-in;
|
transition: all 0.1s ease-in;
|
||||||
}
|
}
|
||||||
|
|
||||||
.display-name {
|
.display-name {
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
.display-name { color: $primary; }
|
.display-name { color: $primary; }
|
||||||
small { opacity: 1; }
|
small { opacity: 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
& > .comment {
|
& > .comment {
|
||||||
padding-left: 2em;
|
padding-left: 2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.text {
|
.text {
|
||||||
padding: 1.25em 0;
|
padding: 1.25em 0;
|
||||||
font-family: $lora;
|
font-family: $lora;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
line-height: 1.4;
|
line-height: 1.4;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,27 +1,27 @@
|
|||||||
label {
|
label {
|
||||||
display: block;
|
display: block;
|
||||||
margin: 2em auto .5em;
|
margin: 2em auto .5em;
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
}
|
}
|
||||||
input, textarea, select {
|
input, textarea, select {
|
||||||
transition: all 0.1s ease-in;
|
transition: all 0.1s ease-in;
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: auto;
|
margin: auto;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
-webkit-appearance: textarea;
|
-webkit-appearance: textarea;
|
||||||
|
|
||||||
background: $form-input-background;
|
background: $form-input-background;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
border: solid $form-input-border thin;
|
border: solid $form-input-border thin;
|
||||||
|
|
||||||
font-size: 1.2em;
|
font-size: 1.2em;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
|
||||||
&:focus {
|
&:focus {
|
||||||
border-color: $primary;
|
border-color: $primary;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
form input[type="submit"] {
|
form input[type="submit"] {
|
||||||
margin: 2em auto;
|
margin: 2em auto;
|
||||||
@@ -29,18 +29,18 @@ form input[type="submit"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
textarea {
|
textarea {
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
font-family: $lora;
|
font-family: $lora;
|
||||||
font-size: 1.1em;
|
font-size: 1.1em;
|
||||||
line-height: 1.5;
|
line-height: 1.5;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
display: inline;
|
display: inline;
|
||||||
margin: initial;
|
margin: initial;
|
||||||
min-width: initial;
|
min-width: initial;
|
||||||
width: initial;
|
width: initial;
|
||||||
-webkit-appearance: checkbox;
|
-webkit-appearance: checkbox;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,31 +71,31 @@ form.inline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.button, .button:visited, input[type="submit"], input[type="submit"].button {
|
.button, .button:visited, input[type="submit"], input[type="submit"].button {
|
||||||
transition: all 0.1s ease-in;
|
transition: all 0.1s ease-in;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
|
||||||
margin: 0.5em auto;
|
margin: 0.5em auto;
|
||||||
padding: 0.75em 1em;
|
padding: 0.75em 1em;
|
||||||
|
|
||||||
background: $primary;
|
background: $primary;
|
||||||
color: $primary-text-color;
|
color: $primary-text-color;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: transparentize($primary, 0.1);
|
background: transparentize($primary, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.destructive {
|
&.destructive {
|
||||||
background: $red;
|
background: $red;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
background: transparentize($red, 0.1);
|
background: transparentize($red, 0.1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.secondary {
|
&.secondary {
|
||||||
background: $gray;
|
background: $gray;
|
||||||
@@ -115,20 +115,20 @@ input[type="submit"] {
|
|||||||
form.new-post {
|
form.new-post {
|
||||||
max-width: 60em;
|
max-width: 60em;
|
||||||
.title {
|
.title {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 0.75em 0;
|
padding: 0.75em 0;
|
||||||
|
|
||||||
background: none;
|
background: none;
|
||||||
border: none;
|
border: none;
|
||||||
|
|
||||||
font-family: $playfair;
|
font-family: $playfair;
|
||||||
font-size: 2em;
|
font-size: 2em;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
textarea {
|
textarea {
|
||||||
min-height: 20em;
|
min-height: 20em;
|
||||||
overflow-y: scroll;
|
overflow-y: scroll;
|
||||||
resize: none;
|
resize: none;
|
||||||
-webkit-appearance: textarea;
|
-webkit-appearance: textarea;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,43 +6,43 @@ html {
|
|||||||
}
|
}
|
||||||
|
|
||||||
html, body {
|
html, body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
background: $background;
|
background: $background;
|
||||||
color: $text-color;
|
color: $text-color;
|
||||||
font-family: $route159;
|
font-family: $route159;
|
||||||
|
|
||||||
::selection {
|
::selection {
|
||||||
background: transparentize($primary, 0.7);
|
background: transparentize($primary, 0.7);
|
||||||
}
|
}
|
||||||
::-moz-selection {
|
::-moz-selection {
|
||||||
background: transparentize($primary, 0.7);
|
background: transparentize($primary, 0.7);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a, a:visited {
|
a, a:visited {
|
||||||
color: $primary;
|
color: $primary;
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
a::selection {
|
a::selection {
|
||||||
color: $background;
|
color: $background;
|
||||||
}
|
}
|
||||||
a::-moz-selection {
|
a::-moz-selection {
|
||||||
color: $background;
|
color: $background;
|
||||||
}
|
}
|
||||||
small {
|
small {
|
||||||
margin-left: 1em;
|
margin-left: 1em;
|
||||||
color: transparentize($text-color, 0.6);
|
color: transparentize($text-color, 0.6);
|
||||||
font-size: 0.75em;
|
font-size: 0.75em;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
word-break: break-all;
|
word-break: break-all;
|
||||||
}
|
}
|
||||||
|
|
||||||
.center {
|
.center {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
opacity: 0.6;
|
opacity: 0.6;
|
||||||
padding: 5em;
|
padding: 5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.right {
|
.right {
|
||||||
@@ -53,28 +53,28 @@ small {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.spaced {
|
.spaced {
|
||||||
margin: 4rem 0;
|
margin: 4rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.banner {
|
.banner {
|
||||||
background: $gray;
|
background: $gray;
|
||||||
padding-top: 2em;
|
padding-top: 2em;
|
||||||
padding-bottom: 1em;
|
padding-bottom: 1em;
|
||||||
margin: 3em 0px;
|
margin: 3em 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.hidden {
|
.hidden {
|
||||||
display: none;
|
display: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Main */
|
/* Main */
|
||||||
body > main > *, .h-feed > * {
|
body > main > *, .h-feed > * {
|
||||||
margin: 1em $horizontal-margin;
|
margin: 1em $horizontal-margin;
|
||||||
}
|
}
|
||||||
|
|
||||||
body > main > .h-entry, .h-feed {
|
body > main > .h-entry, .h-feed {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
body > main {
|
body > main {
|
||||||
@@ -98,18 +98,18 @@ main {
|
|||||||
margin-top: 1em;
|
margin-top: 1em;
|
||||||
|
|
||||||
&.article {
|
&.article {
|
||||||
margin: 1em auto 0.5em;
|
margin: 1em auto 0.5em;
|
||||||
font-family: $playfair;
|
font-family: $playfair;
|
||||||
font-size: 2.5em;
|
font-size: 2.5em;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.75em;
|
font-size: 1.75em;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
|
|
||||||
&.article {
|
&.article {
|
||||||
font-size: 1.25em;
|
font-size: 1.25em;
|
||||||
margin-bottom: 0.5em;
|
margin-bottom: 0.5em;
|
||||||
}
|
}
|
||||||
@@ -139,15 +139,15 @@ main {
|
|||||||
|
|
||||||
/* Errors */
|
/* Errors */
|
||||||
p.error {
|
p.error {
|
||||||
color: $red;
|
color: $red;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* User page */
|
/* User page */
|
||||||
.user h1 {
|
.user h1 {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,14 +156,14 @@ p.error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.badge {
|
.badge {
|
||||||
margin-right: 1em;
|
margin-right: 1em;
|
||||||
padding: 0.35em 1em;
|
padding: 0.35em 1em;
|
||||||
|
|
||||||
background: $background;
|
background: $background;
|
||||||
color: $primary;
|
color: $primary;
|
||||||
border: 1px solid $primary;
|
border: 1px solid $primary;
|
||||||
|
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.user-summary {
|
.user-summary {
|
||||||
@@ -172,23 +172,25 @@ p.error {
|
|||||||
|
|
||||||
/* Cards */
|
/* Cards */
|
||||||
.cards {
|
.cards {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
padding: 0 5%;
|
padding: 0 5%;
|
||||||
margin: 1rem 0 5rem;
|
margin: 1rem 0 5rem;
|
||||||
}
|
}
|
||||||
.card {
|
.card {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|
||||||
min-width: 20em;
|
position: relative;
|
||||||
min-height: 20em;
|
|
||||||
margin: 1em;
|
|
||||||
box-sizing: border-box;
|
|
||||||
|
|
||||||
background: $gray;
|
min-width: 20em;
|
||||||
|
min-height: 20em;
|
||||||
|
margin: 1em;
|
||||||
|
box-sizing: border-box;
|
||||||
|
|
||||||
|
background: $gray;
|
||||||
|
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
||||||
@@ -213,38 +215,54 @@ p.error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
> * {
|
> * {
|
||||||
margin: 20px;
|
margin: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.cover {
|
.cover {
|
||||||
min-height: 10em;
|
min-height: 10em;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
background-size: cover;
|
background-size: cover;
|
||||||
margin: 0px;
|
margin: 0px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin: 0.75em 20px;
|
flex-grow: 1;
|
||||||
font-family: $playfair;
|
margin: 0;
|
||||||
font-size: 1.75em;
|
font-family: $playfair;
|
||||||
font-weight: normal;
|
font-size: 1.75em;
|
||||||
a {
|
font-weight: normal;
|
||||||
transition: color 0.1s ease-in;
|
line-height: 1.75;
|
||||||
color: $text-color;
|
a {
|
||||||
|
display: block;
|
||||||
|
transition: color 0.1s ease-in;
|
||||||
|
color: $text-color;
|
||||||
|
|
||||||
&:hover { color: $primary; }
|
&:hover { color: $primary; }
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.controls {
|
||||||
|
float: right;
|
||||||
|
|
||||||
|
.button {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
|
|
||||||
font-family: $lora;
|
font-family: $lora;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
line-height: 1.25;
|
line-height: 1.25;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -286,15 +304,15 @@ p.error {
|
|||||||
|
|
||||||
/* Stats */
|
/* Stats */
|
||||||
.stats {
|
.stats {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-around;
|
justify-content: space-around;
|
||||||
margin: 2em;
|
margin: 2em;
|
||||||
|
|
||||||
> div {
|
> div {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ body > header {
|
|||||||
|
|
||||||
#content {
|
#content {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-content: center;
|
align-content: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
}
|
}
|
||||||
|
|
||||||
nav#menu {
|
nav#menu {
|
||||||
@@ -19,44 +19,44 @@ body > header {
|
|||||||
|
|
||||||
a {
|
a {
|
||||||
transform: skewX(15deg);
|
transform: skewX(15deg);
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 1.4em;
|
width: 1.4em;
|
||||||
height: 1.4em;
|
height: 1.4em;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
color: $gray;
|
color: $gray;
|
||||||
font-size: 1.33em;
|
font-size: 1.33em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nav {
|
nav {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|
||||||
hr {
|
hr {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 0.2em;
|
width: 0.2em;
|
||||||
background: $primary;
|
background: $primary;
|
||||||
border: none;
|
border: none;
|
||||||
transform: skewX(-15deg);
|
transform: skewX(-15deg);
|
||||||
}
|
}
|
||||||
a {
|
a {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
align-self: stretch;
|
align-self: stretch;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0 2em;
|
padding: 0 2em;
|
||||||
font-size: 1em;
|
font-size: 1em;
|
||||||
|
|
||||||
i { font-size: 1.2em; }
|
i { font-size: 1.2em; }
|
||||||
|
|
||||||
&.title {
|
&.title {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
padding: 0.5em 1em;
|
padding: 0.5em 1em;
|
||||||
font-size: 1.75em;
|
font-size: 1.75em;
|
||||||
@@ -70,7 +70,7 @@ body > header {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -115,6 +115,18 @@ body > header {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@-webkit-keyframes menuOpening {
|
||||||
|
from {
|
||||||
|
-webkit-transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-webkit-transform: scaleX(1);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body > header {
|
body > header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -132,7 +144,7 @@ body > header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body > header:focus-within #content, #content.show {
|
body > header:focus-within #content, .show + #content {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -193,34 +205,33 @@ body > header {
|
|||||||
|
|
||||||
/* Only enable label animations on large screens */
|
/* Only enable label animations on large screens */
|
||||||
@media screen and (min-width: 600px) {
|
@media screen and (min-width: 600px) {
|
||||||
header nav a {
|
header nav a {
|
||||||
i {
|
i {
|
||||||
transition: all 0.2s ease;
|
transition: all 0.2s ease;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
|
||||||
|
|
||||||
.mobile-label {
|
|
||||||
transition: all 0.2s ease;
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, 0);
|
|
||||||
transform: translateZ(0);
|
|
||||||
opacity: 0;
|
|
||||||
font-size: 0.9em;
|
|
||||||
white-space: nowrap;
|
|
||||||
}
|
|
||||||
|
|
||||||
img + .mobile-label { display: none; }
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
i { margin-bottom: 0.75em; }
|
|
||||||
.mobile-label {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translate(-50%, 80%);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
.mobile-label {
|
||||||
|
transition: all 0.2s ease;
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
transform: translateZ(0);
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 0.9em;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
img + .mobile-label { display: none; }
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
i { margin-bottom: 0.75em; }
|
||||||
|
.mobile-label {
|
||||||
|
opacity: 1;
|
||||||
|
transform: translate(-50%, 80%);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Small screens
|
// Small screens
|
||||||
@@ -237,6 +248,18 @@ body > header {
|
|||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@-webkit-keyframes menuOpening {
|
||||||
|
from {
|
||||||
|
-webkit-transform: scaleX(0);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
to {
|
||||||
|
-webkit-transform: scaleX(1);
|
||||||
|
transform-origin: left;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
body > header {
|
body > header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
@@ -254,7 +277,7 @@ body > header {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
body > header:focus-within #content, #content.show {
|
body > header:focus-within #content, .show + #content {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use rsass;
|
|
||||||
|
|
||||||
use ructe::Ructe;
|
use ructe::Ructe;
|
||||||
use std::process::{Command, Stdio};
|
use std::process::{Command, Stdio};
|
||||||
use std::{ffi::OsStr, fs::*, io::Write, path::*};
|
use std::{ffi::OsStr, fs::*, io::Write, path::*};
|
||||||
@@ -50,19 +48,13 @@ fn main() {
|
|||||||
create_dir_all(&Path::new("static").join("media")).expect("Couldn't init media directory");
|
create_dir_all(&Path::new("static").join("media")).expect("Couldn't init media directory");
|
||||||
|
|
||||||
let cache_id = &compute_static_hash()[..8];
|
let cache_id = &compute_static_hash()[..8];
|
||||||
println!("cargo:rerun-if-changed=target/deploy/plume-front.wasm");
|
println!("cargo:rerun-if-changed=plume-front/pkg/plume_front_bg.wasm");
|
||||||
copy("target/deploy/plume-front.wasm", "static/plume-front.wasm")
|
copy(
|
||||||
.and_then(|_| read_to_string("target/deploy/plume-front.js"))
|
"plume-front/pkg/plume_front_bg.wasm",
|
||||||
.and_then(|js| {
|
"static/plume_front_bg.wasm",
|
||||||
write(
|
)
|
||||||
"static/plume-front.js",
|
.and_then(|_| copy("plume-front/pkg/plume_front.js", "static/plume_front.js"))
|
||||||
js.replace(
|
.ok();
|
||||||
"\"plume-front.wasm\"",
|
|
||||||
&format!("\"/static/cached/{}/plume-front.wasm\"", cache_id),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
|
|
||||||
println!("cargo:rustc-env=CACHE_ID={}", cache_id)
|
println!("cargo:rustc-env=CACHE_ID={}", cache_id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-api"
|
name = "plume-api"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-cli"
|
name = "plume-cli"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
@@ -11,11 +11,11 @@ path = "src/main.rs"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
clap = "2.33"
|
clap = "2.33"
|
||||||
dotenv = "0.14"
|
dotenv = "0.14"
|
||||||
rpassword = "4.0"
|
rpassword = "5.0.0"
|
||||||
|
|
||||||
[dependencies.diesel]
|
[dependencies.diesel]
|
||||||
features = ["r2d2", "chrono"]
|
features = ["r2d2", "chrono"]
|
||||||
version = "*"
|
version = "1.4.5"
|
||||||
|
|
||||||
[dependencies.plume-models]
|
[dependencies.plume-models]
|
||||||
path = "../plume-models"
|
path = "../plume-models"
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
use dotenv;
|
|
||||||
|
|
||||||
use clap::App;
|
use clap::App;
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
use plume_models::{instance::Instance, Connection as Conn, CONFIG};
|
use plume_models::{instance::Instance, Connection as Conn, CONFIG};
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ fn refill<'a>(args: &ArgMatches<'a>, conn: &Connection, searcher: Option<Searche
|
|||||||
searcher.commit();
|
searcher.commit();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unlock<'a>(args: &ArgMatches<'a>) {
|
fn unlock(args: &ArgMatches) {
|
||||||
let path = match args.value_of("path") {
|
let path = match args.value_of("path") {
|
||||||
None => Path::new(&CONFIG.search_index),
|
None => Path::new(&CONFIG.search_index),
|
||||||
Some(x) => Path::new(x),
|
Some(x) => Path::new(x),
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
use clap::{App, Arg, ArgMatches, SubCommand};
|
use clap::{App, Arg, ArgMatches, SubCommand};
|
||||||
|
|
||||||
use plume_models::{instance::Instance, users::*, Connection};
|
use plume_models::{instance::Instance, users::*, Connection};
|
||||||
use rpassword;
|
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
pub fn command<'a, 'b>() -> App<'a, 'b> {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-common"
|
name = "plume-common"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
@@ -14,15 +14,16 @@ heck = "0.3.0"
|
|||||||
hex = "0.3"
|
hex = "0.3"
|
||||||
hyper = "0.12.33"
|
hyper = "0.12.33"
|
||||||
openssl = "0.10.22"
|
openssl = "0.10.22"
|
||||||
rocket = "0.4.5"
|
rocket = "0.4.6"
|
||||||
reqwest = "0.9"
|
reqwest = { version = "0.9", features = ["socks"] }
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
shrinkwraprs = "0.2.1"
|
shrinkwraprs = "0.3.0"
|
||||||
syntect = "3.3"
|
syntect = "4.5.0"
|
||||||
tokio = "0.1.22"
|
tokio = "0.1.22"
|
||||||
regex-syntax = { version = "0.6.17", default-features = false, features = ["unicode-perl"] }
|
regex-syntax = { version = "0.6.17", default-features = false, features = ["unicode-perl"] }
|
||||||
|
tracing = "0.1.22"
|
||||||
|
|
||||||
[dependencies.chrono]
|
[dependencies.chrono]
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ use std::fmt::Debug;
|
|||||||
/// # let conn = ();
|
/// # let conn = ();
|
||||||
/// #
|
/// #
|
||||||
/// let result: Result<(), ()> = Inbox::handle(&conn, activity_json)
|
/// let result: Result<(), ()> = Inbox::handle(&conn, activity_json)
|
||||||
/// .with::<User, Announce, Message>()
|
/// .with::<User, Announce, Message>(None)
|
||||||
/// .with::<User, Create, Message>()
|
/// .with::<User, Create, Message>(None)
|
||||||
/// .done();
|
/// .done();
|
||||||
/// ```
|
/// ```
|
||||||
pub enum Inbox<'a, C, E, R>
|
pub enum Inbox<'a, C, E, R>
|
||||||
@@ -144,7 +144,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Registers an handler on this Inbox.
|
/// Registers an handler on this Inbox.
|
||||||
pub fn with<A, V, M>(self) -> Inbox<'a, C, E, R>
|
pub fn with<A, V, M>(self, proxy: Option<&reqwest::Proxy>) -> Inbox<'a, C, E, R>
|
||||||
where
|
where
|
||||||
A: AsActor<&'a C> + FromId<C, Error = E>,
|
A: AsActor<&'a C> + FromId<C, Error = E>,
|
||||||
V: activitypub::Activity,
|
V: activitypub::Activity,
|
||||||
@@ -174,6 +174,7 @@ where
|
|||||||
ctx,
|
ctx,
|
||||||
&actor_id,
|
&actor_id,
|
||||||
serde_json::from_value(act["actor"].clone()).ok(),
|
serde_json::from_value(act["actor"].clone()).ok(),
|
||||||
|
proxy,
|
||||||
) {
|
) {
|
||||||
Ok(a) => a,
|
Ok(a) => a,
|
||||||
// If the actor was not found, go to the next handler
|
// If the actor was not found, go to the next handler
|
||||||
@@ -194,6 +195,7 @@ where
|
|||||||
ctx,
|
ctx,
|
||||||
&obj_id,
|
&obj_id,
|
||||||
serde_json::from_value(act["object"].clone()).ok(),
|
serde_json::from_value(act["object"].clone()).ok(),
|
||||||
|
proxy,
|
||||||
) {
|
) {
|
||||||
Ok(o) => o,
|
Ok(o) => o,
|
||||||
Err((json, e)) => {
|
Err((json, e)) => {
|
||||||
@@ -292,43 +294,52 @@ pub trait FromId<C>: Sized {
|
|||||||
ctx: &C,
|
ctx: &C,
|
||||||
id: &str,
|
id: &str,
|
||||||
object: Option<Self::Object>,
|
object: Option<Self::Object>,
|
||||||
|
proxy: Option<&reqwest::Proxy>,
|
||||||
) -> Result<Self, (Option<serde_json::Value>, Self::Error)> {
|
) -> Result<Self, (Option<serde_json::Value>, Self::Error)> {
|
||||||
match Self::from_db(ctx, id) {
|
match Self::from_db(ctx, id) {
|
||||||
Ok(x) => Ok(x),
|
Ok(x) => Ok(x),
|
||||||
_ => match object {
|
_ => match object {
|
||||||
Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)),
|
Some(o) => Self::from_activity(ctx, o).map_err(|e| (None, e)),
|
||||||
None => Self::from_activity(ctx, Self::deref(id)?).map_err(|e| (None, e)),
|
None => Self::from_activity(ctx, Self::deref(id, proxy.cloned())?)
|
||||||
|
.map_err(|e| (None, e)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Dereferences an ID
|
/// Dereferences an ID
|
||||||
fn deref(id: &str) -> Result<Self::Object, (Option<serde_json::Value>, Self::Error)> {
|
fn deref(
|
||||||
reqwest::ClientBuilder::new()
|
id: &str,
|
||||||
.connect_timeout(Some(std::time::Duration::from_secs(5)))
|
proxy: Option<reqwest::Proxy>,
|
||||||
.build()
|
) -> Result<Self::Object, (Option<serde_json::Value>, Self::Error)> {
|
||||||
.map_err(|_| (None, InboxError::DerefError.into()))?
|
if let Some(proxy) = proxy {
|
||||||
.get(id)
|
reqwest::ClientBuilder::new().proxy(proxy)
|
||||||
.header(
|
} else {
|
||||||
ACCEPT,
|
reqwest::ClientBuilder::new()
|
||||||
HeaderValue::from_str(
|
}
|
||||||
&super::ap_accept_header()
|
.connect_timeout(Some(std::time::Duration::from_secs(5)))
|
||||||
.into_iter()
|
.build()
|
||||||
.collect::<Vec<_>>()
|
.map_err(|_| (None, InboxError::DerefError.into()))?
|
||||||
.join(", "),
|
.get(id)
|
||||||
)
|
.header(
|
||||||
.map_err(|_| (None, InboxError::DerefError.into()))?,
|
ACCEPT,
|
||||||
|
HeaderValue::from_str(
|
||||||
|
&super::ap_accept_header()
|
||||||
|
.into_iter()
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(", "),
|
||||||
)
|
)
|
||||||
.send()
|
.map_err(|_| (None, InboxError::DerefError.into()))?,
|
||||||
.map_err(|_| (None, InboxError::DerefError))
|
)
|
||||||
.and_then(|mut r| {
|
.send()
|
||||||
let json: serde_json::Value = r
|
.map_err(|_| (None, InboxError::DerefError))
|
||||||
.json()
|
.and_then(|mut r| {
|
||||||
.map_err(|_| (None, InboxError::InvalidObject(None)))?;
|
let json: serde_json::Value = r
|
||||||
serde_json::from_value(json.clone())
|
.json()
|
||||||
.map_err(|_| (Some(json), InboxError::InvalidObject(None)))
|
.map_err(|_| (None, InboxError::InvalidObject(None)))?;
|
||||||
})
|
serde_json::from_value(json.clone())
|
||||||
.map_err(|(json, e)| (json, e.into()))
|
.map_err(|_| (Some(json), InboxError::InvalidObject(None)))
|
||||||
|
})
|
||||||
|
.map_err(|(json, e)| (json, e.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a `Self` from its ActivityPub representation
|
/// Builds a `Self` from its ActivityPub representation
|
||||||
@@ -550,7 +561,7 @@ mod tests {
|
|||||||
fn test_inbox_basic() {
|
fn test_inbox_basic() {
|
||||||
let act = serde_json::to_value(build_create()).unwrap();
|
let act = serde_json::to_value(build_create()).unwrap();
|
||||||
let res: Result<(), ()> = Inbox::handle(&(), act)
|
let res: Result<(), ()> = Inbox::handle(&(), act)
|
||||||
.with::<MyActor, Create, MyObject>()
|
.with::<MyActor, Create, MyObject>(None)
|
||||||
.done();
|
.done();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
@@ -559,10 +570,10 @@ mod tests {
|
|||||||
fn test_inbox_multi_handlers() {
|
fn test_inbox_multi_handlers() {
|
||||||
let act = serde_json::to_value(build_create()).unwrap();
|
let act = serde_json::to_value(build_create()).unwrap();
|
||||||
let res: Result<(), ()> = Inbox::handle(&(), act)
|
let res: Result<(), ()> = Inbox::handle(&(), act)
|
||||||
.with::<MyActor, Announce, MyObject>()
|
.with::<MyActor, Announce, MyObject>(None)
|
||||||
.with::<MyActor, Delete, MyObject>()
|
.with::<MyActor, Delete, MyObject>(None)
|
||||||
.with::<MyActor, Create, MyObject>()
|
.with::<MyActor, Create, MyObject>(None)
|
||||||
.with::<MyActor, Like, MyObject>()
|
.with::<MyActor, Like, MyObject>(None)
|
||||||
.done();
|
.done();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
@@ -572,8 +583,8 @@ mod tests {
|
|||||||
let act = serde_json::to_value(build_create()).unwrap();
|
let act = serde_json::to_value(build_create()).unwrap();
|
||||||
// Create is not handled by this inbox
|
// Create is not handled by this inbox
|
||||||
let res: Result<(), ()> = Inbox::handle(&(), act)
|
let res: Result<(), ()> = Inbox::handle(&(), act)
|
||||||
.with::<MyActor, Announce, MyObject>()
|
.with::<MyActor, Announce, MyObject>(None)
|
||||||
.with::<MyActor, Like, MyObject>()
|
.with::<MyActor, Like, MyObject>(None)
|
||||||
.done();
|
.done();
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
}
|
}
|
||||||
@@ -621,13 +632,13 @@ mod tests {
|
|||||||
let act = serde_json::to_value(build_create()).unwrap();
|
let act = serde_json::to_value(build_create()).unwrap();
|
||||||
|
|
||||||
let res: Result<(), ()> = Inbox::handle(&(), act.clone())
|
let res: Result<(), ()> = Inbox::handle(&(), act.clone())
|
||||||
.with::<FailingActor, Create, MyObject>()
|
.with::<FailingActor, Create, MyObject>(None)
|
||||||
.done();
|
.done();
|
||||||
assert!(res.is_err());
|
assert!(res.is_err());
|
||||||
|
|
||||||
let res: Result<(), ()> = Inbox::handle(&(), act.clone())
|
let res: Result<(), ()> = Inbox::handle(&(), act.clone())
|
||||||
.with::<FailingActor, Create, MyObject>()
|
.with::<FailingActor, Create, MyObject>(None)
|
||||||
.with::<MyActor, Create, MyObject>()
|
.with::<MyActor, Create, MyObject>(None)
|
||||||
.done();
|
.done();
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
use activitypub::{Activity, Link, Object};
|
use activitypub::{Activity, Link, Object};
|
||||||
use array_tool::vec::Uniq;
|
use array_tool::vec::Uniq;
|
||||||
use reqwest::r#async::ClientBuilder;
|
use reqwest::{header::HeaderValue, r#async::ClientBuilder, Url};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
http::Status,
|
http::Status,
|
||||||
request::{FromRequest, Request},
|
request::{FromRequest, Request},
|
||||||
response::{Responder, Response},
|
response::{Responder, Response},
|
||||||
Outcome,
|
Outcome,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use tokio::prelude::*;
|
use tokio::prelude::*;
|
||||||
|
use tracing::{debug, warn};
|
||||||
|
|
||||||
use self::sign::Signable;
|
use self::sign::Signable;
|
||||||
|
|
||||||
@@ -108,7 +108,7 @@ impl<'a, 'r> FromRequest<'a, 'r> for ApRequest {
|
|||||||
.unwrap_or(Outcome::Forward(()))
|
.unwrap_or(Outcome::Forward(()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn broadcast<S, A, T, C>(sender: &S, act: A, to: Vec<T>)
|
pub fn broadcast<S, A, T, C>(sender: &S, act: A, to: Vec<T>, proxy: Option<reqwest::Proxy>)
|
||||||
where
|
where
|
||||||
S: sign::Signer,
|
S: sign::Signer,
|
||||||
A: Activity,
|
A: Activity,
|
||||||
@@ -132,31 +132,54 @@ where
|
|||||||
|
|
||||||
let mut rt = tokio::runtime::current_thread::Runtime::new()
|
let mut rt = tokio::runtime::current_thread::Runtime::new()
|
||||||
.expect("Error while initializing tokio runtime for federation");
|
.expect("Error while initializing tokio runtime for federation");
|
||||||
let client = ClientBuilder::new()
|
|
||||||
.connect_timeout(std::time::Duration::from_secs(5))
|
|
||||||
.build()
|
|
||||||
.expect("Can't build client");
|
|
||||||
for inbox in boxes {
|
for inbox in boxes {
|
||||||
let body = signed.to_string();
|
let body = signed.to_string();
|
||||||
let mut headers = request::headers();
|
let mut headers = request::headers();
|
||||||
|
let url = Url::parse(&inbox);
|
||||||
|
if url.is_err() {
|
||||||
|
warn!("Inbox is invalid URL: {:?}", &inbox);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let url = url.unwrap();
|
||||||
|
if !url.has_host() {
|
||||||
|
warn!("Inbox doesn't have host: {:?}", &inbox);
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
let host_header_value = HeaderValue::from_str(&url.host_str().expect("Unreachable"));
|
||||||
|
if host_header_value.is_err() {
|
||||||
|
warn!("Header value is invalid: {:?}", url.host_str());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
headers.insert("Host", host_header_value.unwrap());
|
||||||
headers.insert("Digest", request::Digest::digest(&body));
|
headers.insert("Digest", request::Digest::digest(&body));
|
||||||
rt.spawn(
|
rt.spawn(
|
||||||
client
|
if let Some(proxy) = proxy.clone() {
|
||||||
.post(&inbox)
|
ClientBuilder::new().proxy(proxy)
|
||||||
.headers(headers.clone())
|
} else {
|
||||||
.header(
|
ClientBuilder::new()
|
||||||
"Signature",
|
}
|
||||||
request::signature(sender, &headers)
|
.connect_timeout(std::time::Duration::from_secs(5))
|
||||||
.expect("activity_pub::broadcast: request signature error"),
|
.build()
|
||||||
)
|
.expect("Can't build client")
|
||||||
.body(body)
|
.post(&inbox)
|
||||||
.send()
|
.headers(headers.clone())
|
||||||
.and_then(|r| r.into_body().concat2())
|
.header(
|
||||||
.map(move |response| {
|
"Signature",
|
||||||
println!("Successfully sent activity to inbox ({})", inbox);
|
request::signature(sender, &headers, ("post", url.path(), url.query()))
|
||||||
println!("Response: \"{:?}\"\n", response)
|
.expect("activity_pub::broadcast: request signature error"),
|
||||||
})
|
)
|
||||||
.map_err(|e| println!("Error while sending to inbox ({:?})", e)),
|
.body(body)
|
||||||
|
.send()
|
||||||
|
.and_then(move |r| {
|
||||||
|
if r.status().is_success() {
|
||||||
|
debug!("Successfully sent activity to inbox ({})", &inbox);
|
||||||
|
} else {
|
||||||
|
warn!("Error while sending to inbox ({:?})", &r)
|
||||||
|
}
|
||||||
|
r.into_body().concat2()
|
||||||
|
})
|
||||||
|
.map(move |response| debug!("Response: \"{:?}\"\n", response))
|
||||||
|
.map_err(|e| warn!("Error while sending to inbox ({:?})", e)),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
rt.run().unwrap();
|
rt.run().unwrap();
|
||||||
|
|||||||
@@ -1,15 +1,18 @@
|
|||||||
use base64;
|
|
||||||
use chrono::{offset::Utc, DateTime};
|
use chrono::{offset::Utc, DateTime};
|
||||||
use openssl::hash::{Hasher, MessageDigest};
|
use openssl::hash::{Hasher, MessageDigest};
|
||||||
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, DATE, USER_AGENT};
|
use reqwest::header::{HeaderMap, HeaderValue, ACCEPT, CONTENT_TYPE, DATE, USER_AGENT};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::time::SystemTime;
|
use std::time::SystemTime;
|
||||||
|
use tracing::warn;
|
||||||
|
|
||||||
use crate::activity_pub::sign::Signer;
|
use crate::activity_pub::sign::Signer;
|
||||||
use crate::activity_pub::{ap_accept_header, AP_CONTENT_TYPE};
|
use crate::activity_pub::{ap_accept_header, AP_CONTENT_TYPE};
|
||||||
|
|
||||||
const PLUME_USER_AGENT: &str = concat!("Plume/", env!("CARGO_PKG_VERSION"));
|
const PLUME_USER_AGENT: &str = concat!("Plume/", env!("CARGO_PKG_VERSION"));
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error();
|
||||||
|
|
||||||
pub struct Digest(String);
|
pub struct Digest(String);
|
||||||
|
|
||||||
impl Digest {
|
impl Digest {
|
||||||
@@ -62,16 +65,16 @@ impl Digest {
|
|||||||
base64::decode(&self.0[pos..]).expect("Digest::value: invalid encoding error")
|
base64::decode(&self.0[pos..]).expect("Digest::value: invalid encoding error")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_header(dig: &str) -> Result<Self, ()> {
|
pub fn from_header(dig: &str) -> Result<Self, Error> {
|
||||||
if let Some(pos) = dig.find('=') {
|
if let Some(pos) = dig.find('=') {
|
||||||
let pos = pos + 1;
|
let pos = pos + 1;
|
||||||
if base64::decode(&dig[pos..]).is_ok() {
|
if base64::decode(&dig[pos..]).is_ok() {
|
||||||
Ok(Digest(dig.to_owned()))
|
Ok(Digest(dig.to_owned()))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(Error())
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -110,27 +113,47 @@ pub fn headers() -> HeaderMap {
|
|||||||
headers
|
headers
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderValue, ()> {
|
type Method<'a> = &'a str;
|
||||||
let signed_string = headers
|
type Path<'a> = &'a str;
|
||||||
|
type Query<'a> = &'a str;
|
||||||
|
type RequestTarget<'a> = (Method<'a>, Path<'a>, Option<Query<'a>>);
|
||||||
|
|
||||||
|
pub fn signature<S: Signer>(
|
||||||
|
signer: &S,
|
||||||
|
headers: &HeaderMap,
|
||||||
|
request_target: RequestTarget,
|
||||||
|
) -> Result<HeaderValue, Error> {
|
||||||
|
let (method, path, query) = request_target;
|
||||||
|
let origin_form = if let Some(query) = query {
|
||||||
|
format!("{}?{}", path, query)
|
||||||
|
} else {
|
||||||
|
path.to_string()
|
||||||
|
};
|
||||||
|
|
||||||
|
let mut headers_vec = Vec::with_capacity(headers.len());
|
||||||
|
for (h, v) in headers.iter() {
|
||||||
|
let v = v.to_str();
|
||||||
|
if v.is_err() {
|
||||||
|
warn!("invalid header error: {:?}", v.unwrap_err());
|
||||||
|
return Err(Error());
|
||||||
|
}
|
||||||
|
headers_vec.push((h.as_str().to_lowercase(), v.expect("Unreachable")));
|
||||||
|
}
|
||||||
|
let request_target = format!("{} {}", method.to_lowercase(), origin_form);
|
||||||
|
headers_vec.push(("(request-target)".to_string(), &request_target));
|
||||||
|
|
||||||
|
let signed_string = headers_vec
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(h, v)| {
|
.map(|(h, v)| format!("{}: {}", h, v))
|
||||||
format!(
|
|
||||||
"{}: {}",
|
|
||||||
h.as_str().to_lowercase(),
|
|
||||||
v.to_str()
|
|
||||||
.expect("request::signature: invalid header error")
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
.join("\n");
|
.join("\n");
|
||||||
let signed_headers = headers
|
let signed_headers = headers_vec
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(h, _)| h.as_str())
|
.map(|(h, _)| h.as_ref())
|
||||||
.collect::<Vec<&str>>()
|
.collect::<Vec<&str>>()
|
||||||
.join(" ")
|
.join(" ");
|
||||||
.to_lowercase();
|
|
||||||
|
|
||||||
let data = signer.sign(&signed_string).map_err(|_| ())?;
|
let data = signer.sign(&signed_string).map_err(|_| Error())?;
|
||||||
let sign = base64::encode(&data);
|
let sign = base64::encode(&data);
|
||||||
|
|
||||||
HeaderValue::from_str(&format!(
|
HeaderValue::from_str(&format!(
|
||||||
@@ -138,5 +161,63 @@ pub fn signature<S: Signer>(signer: &S, headers: &HeaderMap) -> Result<HeaderVal
|
|||||||
key_id = signer.get_key_id(),
|
key_id = signer.get_key_id(),
|
||||||
signed_headers = signed_headers,
|
signed_headers = signed_headers,
|
||||||
signature = sign
|
signature = sign
|
||||||
)).map_err(|_| ())
|
)).map_err(|_| Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::{signature, Error};
|
||||||
|
use crate::activity_pub::sign::{gen_keypair, Signer};
|
||||||
|
use openssl::{hash::MessageDigest, pkey::PKey, rsa::Rsa};
|
||||||
|
use reqwest::header::HeaderMap;
|
||||||
|
|
||||||
|
struct MySigner {
|
||||||
|
public_key: String,
|
||||||
|
private_key: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MySigner {
|
||||||
|
fn new() -> Self {
|
||||||
|
let (pub_key, priv_key) = gen_keypair();
|
||||||
|
Self {
|
||||||
|
public_key: String::from_utf8(pub_key).unwrap(),
|
||||||
|
private_key: String::from_utf8(priv_key).unwrap(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Signer for MySigner {
|
||||||
|
type Error = Error;
|
||||||
|
|
||||||
|
fn get_key_id(&self) -> String {
|
||||||
|
"mysigner".into()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn sign(&self, to_sign: &str) -> Result<Vec<u8>, Self::Error> {
|
||||||
|
let key = PKey::from_rsa(Rsa::private_key_from_pem(self.private_key.as_ref()).unwrap())
|
||||||
|
.unwrap();
|
||||||
|
let mut signer = openssl::sign::Signer::new(MessageDigest::sha256(), &key).unwrap();
|
||||||
|
signer.update(to_sign.as_bytes()).unwrap();
|
||||||
|
signer.sign_to_vec().map_err(|_| Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn verify(&self, data: &str, signature: &[u8]) -> Result<bool, Self::Error> {
|
||||||
|
let key = PKey::from_rsa(Rsa::public_key_from_pem(self.public_key.as_ref()).unwrap())
|
||||||
|
.unwrap();
|
||||||
|
let mut verifier = openssl::sign::Verifier::new(MessageDigest::sha256(), &key).unwrap();
|
||||||
|
verifier.update(data.as_bytes()).unwrap();
|
||||||
|
verifier.verify(&signature).map_err(|_| Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_signature_request_target() {
|
||||||
|
let signer = MySigner::new();
|
||||||
|
let headers = HeaderMap::new();
|
||||||
|
let result = signature(&signer, &headers, ("post", "/inbox", None)).unwrap();
|
||||||
|
let fields: Vec<&str> = result.to_str().unwrap().split(",").collect();
|
||||||
|
assert_eq!(r#"headers="(request-target)""#, fields[2]);
|
||||||
|
let sign = &fields[3][11..(fields[3].len() - 1)];
|
||||||
|
assert!(signer.verify("post /inbox", sign.as_bytes()).is_ok());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
use super::request;
|
use super::request;
|
||||||
use base64;
|
|
||||||
use chrono::{naive::NaiveDateTime, DateTime, Duration, Utc};
|
use chrono::{naive::NaiveDateTime, DateTime, Duration, Utc};
|
||||||
use hex;
|
|
||||||
use openssl::{pkey::PKey, rsa::Rsa, sha::sha256};
|
use openssl::{pkey::PKey, rsa::Rsa, sha::sha256};
|
||||||
use rocket::http::HeaderMap;
|
use rocket::http::HeaderMap;
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
/// Returns (public key, private key)
|
/// Returns (public key, private key)
|
||||||
pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
||||||
@@ -20,6 +17,9 @@ pub fn gen_keypair() -> (Vec<u8>, Vec<u8>) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct Error();
|
||||||
|
|
||||||
pub trait Signer {
|
pub trait Signer {
|
||||||
type Error;
|
type Error;
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ pub trait Signer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait Signable {
|
pub trait Signable {
|
||||||
fn sign<T>(&mut self, creator: &T) -> Result<&mut Self, ()>
|
fn sign<T>(&mut self, creator: &T) -> Result<&mut Self, Error>
|
||||||
where
|
where
|
||||||
T: Signer;
|
T: Signer;
|
||||||
fn verify<T>(self, creator: &T) -> bool
|
fn verify<T>(self, creator: &T) -> bool
|
||||||
@@ -46,7 +46,7 @@ pub trait Signable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Signable for serde_json::Value {
|
impl Signable for serde_json::Value {
|
||||||
fn sign<T: Signer>(&mut self, creator: &T) -> Result<&mut serde_json::Value, ()> {
|
fn sign<T: Signer>(&mut self, creator: &T) -> Result<&mut serde_json::Value, Error> {
|
||||||
let creation_date = Utc::now().to_rfc3339();
|
let creation_date = Utc::now().to_rfc3339();
|
||||||
let mut options = json!({
|
let mut options = json!({
|
||||||
"type": "RsaSignature2017",
|
"type": "RsaSignature2017",
|
||||||
@@ -64,7 +64,7 @@ impl Signable for serde_json::Value {
|
|||||||
let document_hash = Self::hash(&self.to_string());
|
let document_hash = Self::hash(&self.to_string());
|
||||||
let to_be_signed = options_hash + &document_hash;
|
let to_be_signed = options_hash + &document_hash;
|
||||||
|
|
||||||
let signature = base64::encode(&creator.sign(&to_be_signed).map_err(|_| ())?);
|
let signature = base64::encode(&creator.sign(&to_be_signed).map_err(|_| Error())?);
|
||||||
|
|
||||||
options["signatureValue"] = serde_json::Value::String(signature);
|
options["signatureValue"] = serde_json::Value::String(signature);
|
||||||
self["signature"] = options;
|
self["signature"] = options;
|
||||||
|
|||||||
Regular → Executable
-3
@@ -2,9 +2,6 @@
|
|||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate activitystreams_derive;
|
extern crate activitystreams_derive;
|
||||||
use activitystreams_traits;
|
|
||||||
|
|
||||||
use serde;
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate shrinkwraprs;
|
extern crate shrinkwraprs;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use rocket::{
|
|||||||
response::{Flash, Redirect},
|
response::{Flash, Redirect},
|
||||||
};
|
};
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use syntect::html::ClassedHTMLGenerator;
|
use syntect::html::{ClassStyle, ClassedHTMLGenerator};
|
||||||
use syntect::parsing::SyntaxSet;
|
use syntect::parsing::SyntaxSet;
|
||||||
|
|
||||||
/// Generates an hexadecimal representation of 32 bytes of random data
|
/// Generates an hexadecimal representation of 32 bytes of random data
|
||||||
@@ -60,6 +60,7 @@ fn to_inline(tag: Tag<'_>) -> Tag<'_> {
|
|||||||
struct HighlighterContext {
|
struct HighlighterContext {
|
||||||
content: Vec<String>,
|
content: Vec<String>,
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn highlight_code<'a>(
|
fn highlight_code<'a>(
|
||||||
context: &mut Option<HighlighterContext>,
|
context: &mut Option<HighlighterContext>,
|
||||||
evt: Event<'a>,
|
evt: Event<'a>,
|
||||||
@@ -92,9 +93,13 @@ fn highlight_code<'a>(
|
|||||||
.find_syntax_by_name(&lang)
|
.find_syntax_by_name(&lang)
|
||||||
.unwrap_or_else(|| syntax_set.find_syntax_plain_text())
|
.unwrap_or_else(|| syntax_set.find_syntax_plain_text())
|
||||||
});
|
});
|
||||||
let mut html = ClassedHTMLGenerator::new(&syntax, &syntax_set);
|
let mut html = ClassedHTMLGenerator::new_with_class_style(
|
||||||
|
&syntax,
|
||||||
|
&syntax_set,
|
||||||
|
ClassStyle::Spaced,
|
||||||
|
);
|
||||||
for line in ctx.content {
|
for line in ctx.content {
|
||||||
html.parse_html_for_line(&line);
|
html.parse_html_for_line_which_includes_newline(&line);
|
||||||
}
|
}
|
||||||
let q = html.finalize();
|
let q = html.finalize();
|
||||||
result.push(Event::Html(q.into()));
|
result.push(Event::Html(q.into()));
|
||||||
@@ -115,6 +120,7 @@ fn highlight_code<'a>(
|
|||||||
_ => Some(vec![evt]),
|
_ => Some(vec![evt]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Event<'a>>> {
|
fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Event<'a>>> {
|
||||||
let (s, res) = match evt {
|
let (s, res) = match evt {
|
||||||
Event::Text(txt) => match state.take() {
|
Event::Text(txt) => match state.take() {
|
||||||
@@ -133,6 +139,7 @@ fn flatten_text<'a>(state: &mut Option<String>, evt: Event<'a>) -> Option<Vec<Ev
|
|||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn inline_tags<'a>(
|
fn inline_tags<'a>(
|
||||||
(state, inline): &mut (Vec<Tag<'a>>, bool),
|
(state, inline): &mut (Vec<Tag<'a>>, bool),
|
||||||
evt: Event<'a>,
|
evt: Event<'a>,
|
||||||
|
|||||||
+40
-3
@@ -1,15 +1,52 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-front"
|
name = "plume-front"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
[lib]
|
||||||
|
crate-type = ["cdylib"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
stdweb = "=0.4.18"
|
|
||||||
stdweb-internal-runtime = "=0.1.4"
|
|
||||||
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
gettext = { git = "https://github.com/Plume-org/gettext/", rev = "294c54d74c699fbc66502b480a37cc66c1daa7f3" }
|
||||||
gettext-macros = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
gettext-macros = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
||||||
gettext-utils = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
gettext-utils = { git = "https://github.com/Plume-org/gettext-macros/", rev = "a7c605f7edd6bfbfbfe7778026bfefd88d82db10" }
|
||||||
lazy_static = "1.3"
|
lazy_static = "1.3"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
|
wasm-bindgen = "0.2.70"
|
||||||
|
js-sys = "0.3.47"
|
||||||
|
serde_derive = "1.0.123"
|
||||||
|
console_error_panic_hook = "0.1.6"
|
||||||
|
|
||||||
|
[dependencies.web-sys]
|
||||||
|
version = "0.3.47"
|
||||||
|
features = [
|
||||||
|
'console',
|
||||||
|
'ClipboardEvent',
|
||||||
|
'CssStyleDeclaration',
|
||||||
|
'DataTransfer',
|
||||||
|
'Document',
|
||||||
|
'DomStringMap',
|
||||||
|
'DomTokenList',
|
||||||
|
'Element',
|
||||||
|
'EventTarget',
|
||||||
|
'FocusEvent',
|
||||||
|
'History',
|
||||||
|
'HtmlAnchorElement',
|
||||||
|
'HtmlDocument',
|
||||||
|
'HtmlFormElement',
|
||||||
|
'HtmlInputElement',
|
||||||
|
'HtmlSelectElement',
|
||||||
|
'HtmlTextAreaElement',
|
||||||
|
'KeyboardEvent',
|
||||||
|
'Storage',
|
||||||
|
'Location',
|
||||||
|
'MouseEvent',
|
||||||
|
'Navigator',
|
||||||
|
'Node',
|
||||||
|
'NodeList',
|
||||||
|
'Text',
|
||||||
|
'TouchEvent',
|
||||||
|
'Window'
|
||||||
|
]
|
||||||
|
|||||||
+426
-266
@@ -1,10 +1,12 @@
|
|||||||
use crate::CATALOG;
|
use crate::{document, CATALOG};
|
||||||
use serde::{Deserialize, Serialize};
|
use js_sys::{encode_uri_component, Date, RegExp};
|
||||||
use serde_json;
|
use serde_derive::{Deserialize, Serialize};
|
||||||
use std::sync::Mutex;
|
use std::{convert::TryInto, sync::Mutex};
|
||||||
use stdweb::{
|
use wasm_bindgen::{prelude::*, JsCast, JsValue};
|
||||||
unstable::{TryFrom, TryInto},
|
use web_sys::{
|
||||||
web::{event::*, html_element::*, *},
|
console, window, ClipboardEvent, Element, Event, FocusEvent, HtmlAnchorElement, HtmlDocument,
|
||||||
|
HtmlElement, HtmlFormElement, HtmlInputElement, HtmlSelectElement, HtmlTextAreaElement,
|
||||||
|
KeyboardEvent, MouseEvent, Node,
|
||||||
};
|
};
|
||||||
|
|
||||||
macro_rules! mv {
|
macro_rules! mv {
|
||||||
@@ -18,30 +20,29 @@ macro_rules! mv {
|
|||||||
|
|
||||||
fn get_elt_value(id: &'static str) -> String {
|
fn get_elt_value(id: &'static str) -> String {
|
||||||
let elt = document().get_element_by_id(id).unwrap();
|
let elt = document().get_element_by_id(id).unwrap();
|
||||||
let inp: Result<InputElement, _> = elt.clone().try_into();
|
let inp: Option<&HtmlInputElement> = elt.dyn_ref();
|
||||||
let textarea: Result<TextAreaElement, _> = elt.clone().try_into();
|
let textarea: Option<&HtmlTextAreaElement> = elt.dyn_ref();
|
||||||
let select: Result<SelectElement, _> = elt.try_into();
|
let select: Option<&HtmlSelectElement> = elt.dyn_ref();
|
||||||
inp.map(|i| i.raw_value()).unwrap_or_else(|_| {
|
inp.map(|i| i.value()).unwrap_or_else(|| {
|
||||||
textarea
|
textarea
|
||||||
.map(|t| t.value())
|
.map(|t| t.value())
|
||||||
.unwrap_or_else(|_| select.unwrap().raw_value())
|
.unwrap_or_else(|| select.unwrap().value())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn set_value<S: AsRef<str>>(id: &'static str, val: S) {
|
fn set_value<S: AsRef<str>>(id: &'static str, val: S) {
|
||||||
let elt = document().get_element_by_id(id).unwrap();
|
let elt = document().get_element_by_id(id).unwrap();
|
||||||
let inp: Result<InputElement, _> = elt.clone().try_into();
|
let inp: Option<&HtmlInputElement> = elt.dyn_ref();
|
||||||
let textarea: Result<TextAreaElement, _> = elt.clone().try_into();
|
let textarea: Option<&HtmlTextAreaElement> = elt.dyn_ref();
|
||||||
let select: Result<SelectElement, _> = elt.try_into();
|
let select: Option<&HtmlSelectElement> = elt.dyn_ref();
|
||||||
inp.map(|i| i.set_raw_value(val.as_ref()))
|
inp.map(|i| i.set_value(val.as_ref())).unwrap_or_else(|| {
|
||||||
.unwrap_or_else(|_| {
|
textarea
|
||||||
textarea
|
.map(|t| t.set_value(val.as_ref()))
|
||||||
.map(|t| t.set_value(val.as_ref()))
|
.unwrap_or_else(|| select.unwrap().set_value(val.as_ref()))
|
||||||
.unwrap_or_else(|_| select.unwrap().set_raw_value(val.as_ref()))
|
})
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn no_return(evt: KeyDownEvent) {
|
fn no_return(evt: KeyboardEvent) {
|
||||||
if evt.key() == "Enter" {
|
if evt.key() == "Enter" {
|
||||||
evt.prevent_default();
|
evt.prevent_default();
|
||||||
}
|
}
|
||||||
@@ -51,7 +52,6 @@ fn no_return(evt: KeyDownEvent) {
|
|||||||
pub enum EditorError {
|
pub enum EditorError {
|
||||||
NoneError,
|
NoneError,
|
||||||
DOMError,
|
DOMError,
|
||||||
TypeError,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<std::option::NoneError> for EditorError {
|
impl From<std::option::NoneError> for EditorError {
|
||||||
@@ -59,22 +59,7 @@ impl From<std::option::NoneError> for EditorError {
|
|||||||
EditorError::NoneError
|
EditorError::NoneError
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl From<stdweb::web::error::InvalidCharacterError> for EditorError {
|
const AUTOSAVE_DEBOUNCE_TIME: i32 = 5000;
|
||||||
fn from(_: stdweb::web::error::InvalidCharacterError) -> Self {
|
|
||||||
EditorError::DOMError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<stdweb::private::TODO> for EditorError {
|
|
||||||
fn from(_: stdweb::private::TODO) -> Self {
|
|
||||||
EditorError::DOMError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl From<stdweb::private::ConversionError> for EditorError {
|
|
||||||
fn from(_: stdweb::private::ConversionError) -> Self {
|
|
||||||
EditorError::TypeError
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const AUTOSAVE_DEBOUNCE_TIME: u32 = 5000;
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Serialize, Deserialize)]
|
||||||
struct AutosaveInformation {
|
struct AutosaveInformation {
|
||||||
contents: String,
|
contents: String,
|
||||||
@@ -85,10 +70,16 @@ struct AutosaveInformation {
|
|||||||
tags: String,
|
tags: String,
|
||||||
title: String,
|
title: String,
|
||||||
}
|
}
|
||||||
js_serializable!(AutosaveInformation);
|
|
||||||
fn is_basic_editor() -> bool {
|
fn is_basic_editor() -> bool {
|
||||||
if let Some(basic_editor) = window().local_storage().get("basic-editor") {
|
if let Some(basic_editor) = window()
|
||||||
basic_editor == "true"
|
.unwrap()
|
||||||
|
.local_storage()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.get("basic-editor")
|
||||||
|
.unwrap()
|
||||||
|
{
|
||||||
|
&basic_editor == "true"
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
@@ -97,65 +88,58 @@ fn get_title() -> String {
|
|||||||
if is_basic_editor() {
|
if is_basic_editor() {
|
||||||
get_elt_value("title")
|
get_elt_value("title")
|
||||||
} else {
|
} else {
|
||||||
let title_field = HtmlElement::try_from(
|
document()
|
||||||
document()
|
.query_selector("#plume-editor > h1")
|
||||||
.query_selector("#plume-editor > h1")
|
.unwrap()
|
||||||
.ok()
|
.unwrap()
|
||||||
.unwrap()
|
.dyn_ref::<HtmlElement>()
|
||||||
.unwrap(),
|
.unwrap()
|
||||||
)
|
.inner_text()
|
||||||
.ok()
|
|
||||||
.unwrap();
|
|
||||||
title_field.inner_text()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_autosave_id() -> String {
|
fn get_autosave_id() -> String {
|
||||||
format!(
|
format!(
|
||||||
"editor_contents={}",
|
"editor_contents={}",
|
||||||
window().location().unwrap().pathname().unwrap()
|
window().unwrap().location().pathname().unwrap()
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
fn get_editor_contents() -> String {
|
fn get_editor_contents() -> String {
|
||||||
if is_basic_editor() {
|
if is_basic_editor() {
|
||||||
get_elt_value("editor-content")
|
get_elt_value("editor-content")
|
||||||
} else {
|
} else {
|
||||||
let editor =
|
let editor = document().query_selector("article").unwrap().unwrap();
|
||||||
HtmlElement::try_from(document().query_selector("article").ok().unwrap().unwrap())
|
let child_nodes = editor.child_nodes();
|
||||||
.ok()
|
let mut md = String::new();
|
||||||
.unwrap();
|
for i in 0..child_nodes.length() {
|
||||||
editor.child_nodes().iter().fold(String::new(), |md, ch| {
|
let ch = child_nodes.get(i).unwrap();
|
||||||
let to_append = match ch.node_type() {
|
let to_append = match ch.node_type() {
|
||||||
NodeType::Element => {
|
Node::ELEMENT_NODE => {
|
||||||
if js! { return @{&ch}.tagName; } == "DIV" {
|
let elt = ch.dyn_ref::<Element>().unwrap();
|
||||||
(js! { return @{&ch}.innerHTML; })
|
if elt.tag_name() == "DIV" {
|
||||||
.try_into()
|
elt.inner_html()
|
||||||
.unwrap_or_default()
|
|
||||||
} else {
|
} else {
|
||||||
(js! { return @{&ch}.outerHTML; })
|
elt.outer_html()
|
||||||
.try_into()
|
|
||||||
.unwrap_or_default()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
NodeType::Text => ch.node_value().unwrap_or_default(),
|
Node::TEXT_NODE => ch.node_value().unwrap_or_default(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
format!("{}\n\n{}", md, to_append)
|
md = format!("{}\n\n{}", md, to_append);
|
||||||
})
|
}
|
||||||
|
md
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_subtitle() -> String {
|
fn get_subtitle() -> String {
|
||||||
if is_basic_editor() {
|
if is_basic_editor() {
|
||||||
get_elt_value("subtitle")
|
get_elt_value("subtitle")
|
||||||
} else {
|
} else {
|
||||||
let subtitle_element = HtmlElement::try_from(
|
document()
|
||||||
document()
|
.query_selector("#plume-editor > h2")
|
||||||
.query_selector("#plume-editor > h2")
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap(),
|
.dyn_ref::<HtmlElement>()
|
||||||
)
|
.unwrap()
|
||||||
.ok()
|
.inner_text()
|
||||||
.unwrap();
|
|
||||||
subtitle_element.inner_text()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn autosave() {
|
fn autosave() {
|
||||||
@@ -170,27 +154,31 @@ fn autosave() {
|
|||||||
};
|
};
|
||||||
let id = get_autosave_id();
|
let id = get_autosave_id();
|
||||||
match window()
|
match window()
|
||||||
|
.unwrap()
|
||||||
.local_storage()
|
.local_storage()
|
||||||
.insert(&id, &serde_json::to_string(&info).unwrap())
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.set(&id, &serde_json::to_string(&info).unwrap())
|
||||||
{
|
{
|
||||||
Ok(_) => {}
|
Ok(_) => {}
|
||||||
_ => console!(log, "Autosave failed D:"),
|
_ => console::log_1(&"Autosave failed D:".into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//This is only necessary until we go to stdweb 4.20 at least
|
|
||||||
fn confirm(message: &str) -> bool {
|
|
||||||
let result: bool = js! {return confirm(@{message});} == true;
|
|
||||||
result
|
|
||||||
}
|
|
||||||
fn load_autosave() {
|
fn load_autosave() {
|
||||||
if let Some(autosave_str) = window().local_storage().get(&get_autosave_id()) {
|
if let Ok(Some(autosave_str)) = window()
|
||||||
|
.unwrap()
|
||||||
|
.local_storage()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.get(&get_autosave_id())
|
||||||
|
{
|
||||||
let autosave_info: AutosaveInformation = serde_json::from_str(&autosave_str).ok().unwrap();
|
let autosave_info: AutosaveInformation = serde_json::from_str(&autosave_str).ok().unwrap();
|
||||||
let message = i18n!(
|
let message = i18n!(
|
||||||
CATALOG,
|
CATALOG,
|
||||||
"Do you want to load the local autosave last edited at {}?";
|
"Do you want to load the local autosave last edited at {}?";
|
||||||
Date::from_time(autosave_info.last_saved).to_date_string()
|
Date::new(&JsValue::from_f64(autosave_info.last_saved)).to_date_string().as_string().unwrap()
|
||||||
);
|
);
|
||||||
if confirm(&message) {
|
if let Ok(true) = window().unwrap().confirm_with_message(&message) {
|
||||||
set_value("editor-content", &autosave_info.contents);
|
set_value("editor-content", &autosave_info.contents);
|
||||||
set_value("title", &autosave_info.title);
|
set_value("title", &autosave_info.title);
|
||||||
set_value("subtitle", &autosave_info.subtitle);
|
set_value("subtitle", &autosave_info.subtitle);
|
||||||
@@ -203,18 +191,33 @@ fn load_autosave() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn clear_autosave() {
|
fn clear_autosave() {
|
||||||
window().local_storage().remove(&get_autosave_id());
|
window()
|
||||||
console!(log, &format!("Saved to {}", &get_autosave_id()));
|
.unwrap()
|
||||||
|
.local_storage()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.remove_item(&get_autosave_id())
|
||||||
|
.unwrap();
|
||||||
|
console::log_1(&&format!("Saved to {}", &get_autosave_id()).into());
|
||||||
}
|
}
|
||||||
|
type TimeoutHandle = i32;
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref AUTOSAVE_TIMEOUT: Mutex<Option<TimeoutHandle>> = Mutex::new(None);
|
static ref AUTOSAVE_TIMEOUT: Mutex<Option<TimeoutHandle>> = Mutex::new(None);
|
||||||
}
|
}
|
||||||
fn autosave_debounce() {
|
fn autosave_debounce() {
|
||||||
|
let window = window().unwrap();
|
||||||
let timeout = &mut AUTOSAVE_TIMEOUT.lock().unwrap();
|
let timeout = &mut AUTOSAVE_TIMEOUT.lock().unwrap();
|
||||||
if let Some(timeout) = timeout.take() {
|
if let Some(timeout) = timeout.take() {
|
||||||
timeout.clear();
|
window.clear_timeout_with_handle(timeout);
|
||||||
}
|
}
|
||||||
**timeout = Some(window().set_clearable_timeout(autosave, AUTOSAVE_DEBOUNCE_TIME));
|
let callback = Closure::once(autosave);
|
||||||
|
**timeout = window
|
||||||
|
.set_timeout_with_callback_and_timeout_and_arguments_0(
|
||||||
|
callback.as_ref().unchecked_ref(),
|
||||||
|
AUTOSAVE_DEBOUNCE_TIME,
|
||||||
|
)
|
||||||
|
.ok();
|
||||||
|
callback.forget();
|
||||||
}
|
}
|
||||||
fn init_widget(
|
fn init_widget(
|
||||||
parent: &Element,
|
parent: &Element,
|
||||||
@@ -223,19 +226,33 @@ fn init_widget(
|
|||||||
content: String,
|
content: String,
|
||||||
disable_return: bool,
|
disable_return: bool,
|
||||||
) -> Result<HtmlElement, EditorError> {
|
) -> Result<HtmlElement, EditorError> {
|
||||||
let widget = placeholder(make_editable(tag).try_into()?, &placeholder_text);
|
let widget = placeholder(
|
||||||
|
make_editable(tag).dyn_into::<HtmlElement>().unwrap(),
|
||||||
|
&placeholder_text,
|
||||||
|
);
|
||||||
if !content.is_empty() {
|
if !content.is_empty() {
|
||||||
widget.dataset().insert("edited", "true")?;
|
widget
|
||||||
|
.dataset()
|
||||||
|
.set("edited", "true")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
}
|
}
|
||||||
widget.append_child(&document().create_text_node(&content));
|
widget
|
||||||
|
.append_child(&document().create_text_node(&content))
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
if disable_return {
|
if disable_return {
|
||||||
widget.add_event_listener(no_return);
|
let callback = Closure::wrap(Box::new(no_return) as Box<dyn FnMut(KeyboardEvent)>);
|
||||||
|
widget
|
||||||
|
.add_event_listener_with_callback("keydown", callback.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
callback.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
parent.append_child(&widget);
|
parent
|
||||||
|
.append_child(&widget)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
// We need to do that to make sure the placeholder is correctly rendered
|
// We need to do that to make sure the placeholder is correctly rendered
|
||||||
widget.focus();
|
widget.focus().map_err(|_| EditorError::DOMError)?;
|
||||||
widget.blur();
|
widget.blur().map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
filter_paste(&widget);
|
filter_paste(&widget);
|
||||||
|
|
||||||
@@ -244,48 +261,88 @@ fn init_widget(
|
|||||||
|
|
||||||
fn filter_paste(elt: &HtmlElement) {
|
fn filter_paste(elt: &HtmlElement) {
|
||||||
// Only insert text when pasting something
|
// Only insert text when pasting something
|
||||||
js! {
|
let insert_text = Closure::wrap(Box::new(|evt: ClipboardEvent| {
|
||||||
@{&elt}.addEventListener("paste", function (evt) {
|
evt.prevent_default();
|
||||||
evt.preventDefault();
|
if let Some(data) = evt.clipboard_data() {
|
||||||
document.execCommand("insertText", false, evt.clipboardData.getData("text"));
|
if let Ok(data) = data.get_data("text") {
|
||||||
});
|
document()
|
||||||
};
|
.dyn_ref::<HtmlDocument>()
|
||||||
|
.unwrap()
|
||||||
|
.exec_command_with_show_ui_and_value("insertText", false, &data)
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}) as Box<dyn FnMut(ClipboardEvent)>);
|
||||||
|
elt.add_event_listener_with_callback("paste", insert_text.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
insert_text.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init() -> Result<(), EditorError> {
|
pub fn init() -> Result<(), EditorError> {
|
||||||
if let Some(ed) = document().get_element_by_id("plume-fallback-editor") {
|
if let Some(ed) = document().get_element_by_id("plume-fallback-editor") {
|
||||||
load_autosave();
|
load_autosave();
|
||||||
ed.add_event_listener(|_: SubmitEvent| clear_autosave());
|
let callback = Closure::wrap(Box::new(|_| clear_autosave()) as Box<dyn FnMut(Event)>);
|
||||||
|
ed.add_event_listener_with_callback("submit", callback.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
callback.forget();
|
||||||
}
|
}
|
||||||
// Check if the user wants to use the basic editor
|
// Check if the user wants to use the basic editor
|
||||||
if window()
|
if window()
|
||||||
|
.unwrap()
|
||||||
.local_storage()
|
.local_storage()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
.get("basic-editor")
|
.get("basic-editor")
|
||||||
.map(|x| x == "true")
|
.map(|x| x.is_some() && x.unwrap() == "true")
|
||||||
.unwrap_or(true)
|
.unwrap_or(true)
|
||||||
{
|
{
|
||||||
if let Some(editor) = document().get_element_by_id("plume-fallback-editor") {
|
if let Some(editor) = document().get_element_by_id("plume-fallback-editor") {
|
||||||
if let Ok(Some(title_label)) = document().query_selector("label[for=title]") {
|
if let Ok(Some(title_label)) = document().query_selector("label[for=title]") {
|
||||||
let editor_button = document().create_element("a")?;
|
let editor_button = document()
|
||||||
js! { @{&editor_button}.href = "#"; }
|
.create_element("a")
|
||||||
editor_button.add_event_listener(|_: ClickEvent| {
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
if window()
|
editor_button
|
||||||
|
.dyn_ref::<HtmlAnchorElement>()
|
||||||
|
.unwrap()
|
||||||
|
.set_href("#");
|
||||||
|
let disable_basic_editor = Closure::wrap(Box::new(|_| {
|
||||||
|
let window = window().unwrap();
|
||||||
|
if window
|
||||||
.local_storage()
|
.local_storage()
|
||||||
.insert("basic-editor", "false")
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.set("basic-editor", "false")
|
||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
console!(log, "Failed to write into local storage");
|
console::log_1(&"Failed to write into local storage".into());
|
||||||
}
|
}
|
||||||
window().history().go(0).ok(); // refresh
|
window.history().unwrap().go_with_delta(0).ok(); // refresh
|
||||||
});
|
})
|
||||||
editor_button.append_child(
|
as Box<dyn FnMut(MouseEvent)>);
|
||||||
&document().create_text_node(&i18n!(CATALOG, "Open the rich text editor")),
|
editor_button
|
||||||
|
.add_event_listener_with_callback(
|
||||||
|
"click",
|
||||||
|
disable_basic_editor.as_ref().unchecked_ref(),
|
||||||
|
)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
disable_basic_editor.forget();
|
||||||
|
editor_button
|
||||||
|
.append_child(
|
||||||
|
&document().create_text_node(&i18n!(CATALOG, "Open the rich text editor")),
|
||||||
|
)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
editor
|
||||||
|
.insert_before(&editor_button, Some(&title_label))
|
||||||
|
.ok();
|
||||||
|
let callback = Closure::wrap(
|
||||||
|
Box::new(|_| autosave_debounce()) as Box<dyn FnMut(KeyboardEvent)>
|
||||||
);
|
);
|
||||||
editor.insert_before(&editor_button, &title_label).ok();
|
|
||||||
document()
|
document()
|
||||||
.get_element_by_id("editor-content")
|
.get_element_by_id("editor-content")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.add_event_listener(|_: KeyDownEvent| autosave_debounce());
|
.add_event_listener_with_callback("keydown", callback.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
callback.forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,14 +355,30 @@ pub fn init() -> Result<(), EditorError> {
|
|||||||
fn init_editor() -> Result<(), EditorError> {
|
fn init_editor() -> Result<(), EditorError> {
|
||||||
if let Some(ed) = document().get_element_by_id("plume-editor") {
|
if let Some(ed) = document().get_element_by_id("plume-editor") {
|
||||||
// Show the editor
|
// Show the editor
|
||||||
js! { @{&ed}.style.display = "block"; };
|
ed.dyn_ref::<HtmlElement>()
|
||||||
|
.unwrap()
|
||||||
|
.style()
|
||||||
|
.set_property("display", "block")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
// And hide the HTML-only fallback
|
// And hide the HTML-only fallback
|
||||||
let old_ed = document().get_element_by_id("plume-fallback-editor")?;
|
let old_ed = document().get_element_by_id("plume-fallback-editor");
|
||||||
|
if old_ed.is_none() {
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
let old_ed = old_ed.unwrap();
|
||||||
let old_title = document().get_element_by_id("plume-editor-title")?;
|
let old_title = document().get_element_by_id("plume-editor-title")?;
|
||||||
js! {
|
old_ed
|
||||||
@{&old_ed}.style.display = "none";
|
.dyn_ref::<HtmlElement>()
|
||||||
@{&old_title}.style.display = "none";
|
.unwrap()
|
||||||
};
|
.style()
|
||||||
|
.set_property("display", "none")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
old_title
|
||||||
|
.dyn_ref::<HtmlElement>()
|
||||||
|
.unwrap()
|
||||||
|
.style()
|
||||||
|
.set_property("display", "none")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
// Get content from the old editor (when editing an article for instance)
|
// Get content from the old editor (when editing an article for instance)
|
||||||
let title_val = get_elt_value("title");
|
let title_val = get_elt_value("title");
|
||||||
@@ -327,35 +400,44 @@ fn init_editor() -> Result<(), EditorError> {
|
|||||||
content_val.clone(),
|
content_val.clone(),
|
||||||
false,
|
false,
|
||||||
)?;
|
)?;
|
||||||
js! { @{&content}.innerHTML = @{content_val}; };
|
content.set_inner_html(&content_val);
|
||||||
|
|
||||||
// character counter
|
// character counter
|
||||||
content.add_event_listener(mv!(content => move |_: KeyDownEvent| {
|
let character_counter = Closure::wrap(Box::new(mv!(content => move |_| {
|
||||||
window().set_timeout(mv!(content => move || {
|
let update_char_count = Closure::wrap(Box::new(mv!(content => move || {
|
||||||
if let Some(e) = document().get_element_by_id("char-count") {
|
if let Some(e) = document().get_element_by_id("char-count") {
|
||||||
let count = chars_left("#plume-fallback-editor", &content).unwrap_or_default();
|
let count = chars_left("#plume-fallback-editor", &content).unwrap_or_default();
|
||||||
let text = i18n!(CATALOG, "Around {} characters left"; count);
|
let text = i18n!(CATALOG, "Around {} characters left"; count);
|
||||||
HtmlElement::try_from(e).map(|e| {
|
e.dyn_ref::<HtmlElement>().map(|e| {
|
||||||
js!{@{e}.innerText = @{text}};
|
e.set_inner_text(&text);
|
||||||
}).ok();
|
}).unwrap();
|
||||||
};
|
};
|
||||||
}), 0);
|
})) as Box<dyn FnMut()>);
|
||||||
|
window().unwrap().set_timeout_with_callback_and_timeout_and_arguments(update_char_count.as_ref().unchecked_ref(), 0, &js_sys::Array::new()).unwrap();
|
||||||
|
update_char_count.forget();
|
||||||
autosave_debounce();
|
autosave_debounce();
|
||||||
}));
|
})) as Box<dyn FnMut(KeyboardEvent)>);
|
||||||
|
content
|
||||||
|
.add_event_listener_with_callback("keydown", character_counter.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
character_counter.forget();
|
||||||
|
|
||||||
document().get_element_by_id("publish")?.add_event_listener(
|
let show_popup = Closure::wrap(Box::new(mv!(title, subtitle, content, old_ed => move |_| {
|
||||||
mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
let popup = document().get_element_by_id("publish-popup").or_else(||
|
||||||
let popup = document().get_element_by_id("publish-popup").or_else(||
|
init_popup(&title, &subtitle, &content, &old_ed).ok()
|
||||||
init_popup(&title, &subtitle, &content, &old_ed).ok()
|
).unwrap();
|
||||||
).unwrap();
|
let bg = document().get_element_by_id("popup-bg").or_else(||
|
||||||
let bg = document().get_element_by_id("popup-bg").or_else(||
|
init_popup_bg().ok()
|
||||||
init_popup_bg().ok()
|
).unwrap();
|
||||||
).unwrap();
|
|
||||||
|
|
||||||
popup.class_list().add("show").unwrap();
|
popup.class_list().add_1("show").unwrap();
|
||||||
bg.class_list().add("show").unwrap();
|
bg.class_list().add_1("show").unwrap();
|
||||||
}),
|
})) as Box<dyn FnMut(MouseEvent)>);
|
||||||
);
|
document()
|
||||||
|
.get_element_by_id("publish")?
|
||||||
|
.add_event_listener_with_callback("click", show_popup.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
show_popup.forget();
|
||||||
|
|
||||||
show_errors();
|
show_errors();
|
||||||
setup_close_button();
|
setup_close_button();
|
||||||
@@ -365,32 +447,47 @@ fn init_editor() -> Result<(), EditorError> {
|
|||||||
|
|
||||||
fn setup_close_button() {
|
fn setup_close_button() {
|
||||||
if let Some(button) = document().get_element_by_id("close-editor") {
|
if let Some(button) = document().get_element_by_id("close-editor") {
|
||||||
button.add_event_listener(|_: ClickEvent| {
|
let close_editor = Closure::wrap(Box::new(|_| {
|
||||||
window()
|
window()
|
||||||
|
.unwrap()
|
||||||
.local_storage()
|
.local_storage()
|
||||||
.insert("basic-editor", "true")
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.set("basic-editor", "true")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
window().history().go(0).unwrap(); // Refresh the page
|
window()
|
||||||
});
|
.unwrap()
|
||||||
|
.history()
|
||||||
|
.unwrap()
|
||||||
|
.go_with_delta(0)
|
||||||
|
.unwrap(); // Refresh the page
|
||||||
|
}) as Box<dyn FnMut(MouseEvent)>);
|
||||||
|
button
|
||||||
|
.add_event_listener_with_callback("click", close_editor.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
close_editor.forget();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_errors() {
|
fn show_errors() {
|
||||||
if let Ok(Some(header)) = document().query_selector("header") {
|
let document = document();
|
||||||
let list = document().create_element("header").unwrap();
|
if let Ok(Some(header)) = document.query_selector("header") {
|
||||||
list.class_list().add("messages").unwrap();
|
let list = document.create_element("header").unwrap();
|
||||||
for error in document().query_selector_all("p.error").unwrap() {
|
list.class_list().add_1("messages").unwrap();
|
||||||
|
let errors = document.query_selector_all("p.error").unwrap();
|
||||||
|
for i in 0..errors.length() {
|
||||||
|
let error = errors.get(i).unwrap();
|
||||||
error
|
error
|
||||||
.parent_element()
|
.parent_element()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.remove_child(&error)
|
.remove_child(&error)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
list.append_child(&error);
|
let _ = list.append_child(&error);
|
||||||
}
|
}
|
||||||
header
|
header
|
||||||
.parent_element()
|
.parent_element()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.insert_before(&list, &header.next_sibling().unwrap())
|
.insert_before(&list, header.next_sibling().as_ref())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -401,9 +498,17 @@ fn init_popup(
|
|||||||
content: &HtmlElement,
|
content: &HtmlElement,
|
||||||
old_ed: &Element,
|
old_ed: &Element,
|
||||||
) -> Result<Element, EditorError> {
|
) -> Result<Element, EditorError> {
|
||||||
let popup = document().create_element("div")?;
|
let document = document();
|
||||||
popup.class_list().add("popup")?;
|
let popup = document
|
||||||
popup.set_attribute("id", "publish-popup")?;
|
.create_element("div")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
popup
|
||||||
|
.class_list()
|
||||||
|
.add_1("popup")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
popup
|
||||||
|
.set_attribute("id", "publish-popup")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
let tags = get_elt_value("tags")
|
let tags = get_elt_value("tags")
|
||||||
.split(',')
|
.split(',')
|
||||||
@@ -411,112 +516,157 @@ fn init_popup(
|
|||||||
.map(str::to_string)
|
.map(str::to_string)
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
let license = get_elt_value("license");
|
let license = get_elt_value("license");
|
||||||
make_input(&i18n!(CATALOG, "Tags"), "popup-tags", &popup).set_raw_value(&tags.join(", "));
|
make_input(&i18n!(CATALOG, "Tags"), "popup-tags", &popup).set_value(&tags.join(", "));
|
||||||
make_input(&i18n!(CATALOG, "License"), "popup-license", &popup).set_raw_value(&license);
|
make_input(&i18n!(CATALOG, "License"), "popup-license", &popup).set_value(&license);
|
||||||
|
|
||||||
let cover_label = document().create_element("label")?;
|
let cover_label = document
|
||||||
cover_label.append_child(&document().create_text_node(&i18n!(CATALOG, "Cover")));
|
.create_element("label")
|
||||||
cover_label.set_attribute("for", "cover")?;
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
let cover = document().get_element_by_id("cover")?;
|
cover_label
|
||||||
|
.append_child(&document.create_text_node(&i18n!(CATALOG, "Cover")))
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
cover_label
|
||||||
|
.set_attribute("for", "cover")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
let cover = document.get_element_by_id("cover")?;
|
||||||
cover.parent_element()?.remove_child(&cover).ok();
|
cover.parent_element()?.remove_child(&cover).ok();
|
||||||
popup.append_child(&cover_label);
|
popup
|
||||||
popup.append_child(&cover);
|
.append_child(&cover_label)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
popup
|
||||||
|
.append_child(&cover)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
if let Some(draft_checkbox) = document().get_element_by_id("draft") {
|
if let Some(draft_checkbox) = document.get_element_by_id("draft") {
|
||||||
let draft_label = document().create_element("label")?;
|
let draft_checkbox = draft_checkbox.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
draft_label.set_attribute("for", "popup-draft")?;
|
let draft_label = document
|
||||||
|
.create_element("label")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
draft_label
|
||||||
|
.set_attribute("for", "popup-draft")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
let draft = document().create_element("input").unwrap();
|
let draft = document.create_element("input").unwrap();
|
||||||
js! {
|
draft.set_id("popup-draft");
|
||||||
@{&draft}.id = "popup-draft";
|
let draft = draft.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
@{&draft}.name = "popup-draft";
|
draft.set_name("popup-draft");
|
||||||
@{&draft}.type = "checkbox";
|
draft.set_type("checkbox");
|
||||||
@{&draft}.checked = @{&draft_checkbox}.checked;
|
draft.set_checked(draft_checkbox.checked());
|
||||||
};
|
|
||||||
|
|
||||||
draft_label.append_child(&draft);
|
draft_label
|
||||||
draft_label.append_child(&document().create_text_node(&i18n!(CATALOG, "This is a draft")));
|
.append_child(&draft)
|
||||||
popup.append_child(&draft_label);
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
draft_label
|
||||||
|
.append_child(&document.create_text_node(&i18n!(CATALOG, "This is a draft")))
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
popup
|
||||||
|
.append_child(&draft_label)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let button = document().create_element("input")?;
|
let button = document
|
||||||
js! {
|
.create_element("input")
|
||||||
@{&button}.type = "submit";
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
@{&button}.value = @{i18n!(CATALOG, "Publish")};
|
button
|
||||||
};
|
.append_child(&document.create_text_node(&i18n!(CATALOG, "Publish")))
|
||||||
button.append_child(&document().create_text_node(&i18n!(CATALOG, "Publish")));
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
button.add_event_listener(
|
let button = button.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
mv!(title, subtitle, content, old_ed => move |_: ClickEvent| {
|
button.set_type("submit");
|
||||||
title.focus(); // Remove the placeholder before publishing
|
button.set_value(&i18n!(CATALOG, "Publish"));
|
||||||
set_value("title", title.inner_text());
|
let callback = Closure::wrap(Box::new(mv!(title, subtitle, content, old_ed => move |_| {
|
||||||
subtitle.focus();
|
let document = self::document();
|
||||||
set_value("subtitle", subtitle.inner_text());
|
title.focus().unwrap(); // Remove the placeholder before publishing
|
||||||
content.focus();
|
set_value("title", title.inner_text());
|
||||||
set_value("editor-content", content.child_nodes().iter().fold(String::new(), |md, ch| {
|
subtitle.focus().unwrap();
|
||||||
let to_append = match ch.node_type() {
|
set_value("subtitle", subtitle.inner_text());
|
||||||
NodeType::Element => {
|
content.focus().unwrap();
|
||||||
if js!{ return @{&ch}.tagName; } == "DIV" {
|
let mut md = String::new();
|
||||||
(js!{ return @{&ch}.innerHTML; }).try_into().unwrap_or_default()
|
let child_nodes = content.child_nodes();
|
||||||
} else {
|
for i in 0..child_nodes.length() {
|
||||||
(js!{ return @{&ch}.outerHTML; }).try_into().unwrap_or_default()
|
let ch = child_nodes.get(i).unwrap();
|
||||||
}
|
let to_append = match ch.node_type() {
|
||||||
},
|
Node::ELEMENT_NODE => {
|
||||||
NodeType::Text => ch.node_value().unwrap_or_default(),
|
let ch = ch.dyn_ref::<Element>().unwrap();
|
||||||
_ => unreachable!(),
|
if ch.tag_name() == "DIV" {
|
||||||
};
|
ch.inner_html()
|
||||||
format!("{}\n\n{}", md, to_append)
|
} else {
|
||||||
}));
|
ch.outer_html()
|
||||||
set_value("tags", get_elt_value("popup-tags"));
|
}
|
||||||
if let Some(draft) = document().get_element_by_id("popup-draft") {
|
},
|
||||||
js!{
|
Node::TEXT_NODE => ch.node_value().unwrap_or_default(),
|
||||||
document.getElementById("draft").checked = @{draft}.checked;
|
_ => unreachable!(),
|
||||||
};
|
|
||||||
}
|
|
||||||
let cover = document().get_element_by_id("cover").unwrap();
|
|
||||||
cover.parent_element().unwrap().remove_child(&cover).ok();
|
|
||||||
old_ed.append_child(&cover);
|
|
||||||
set_value("license", get_elt_value("popup-license"));
|
|
||||||
clear_autosave();
|
|
||||||
js! {
|
|
||||||
@{&old_ed}.submit();
|
|
||||||
};
|
};
|
||||||
}),
|
md = format!("{}\n\n{}", md, to_append);
|
||||||
);
|
}
|
||||||
popup.append_child(&button);
|
set_value("editor-content", md);
|
||||||
|
set_value("tags", get_elt_value("popup-tags"));
|
||||||
|
if let Some(draft) = document.get_element_by_id("popup-draft") {
|
||||||
|
if let Some(draft_checkbox) = document.get_element_by_id("draft") {
|
||||||
|
let draft_checkbox = draft_checkbox.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
|
let draft = draft.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
|
draft_checkbox.set_checked(draft.checked());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let cover = document.get_element_by_id("cover").unwrap();
|
||||||
|
cover.parent_element().unwrap().remove_child(&cover).ok();
|
||||||
|
old_ed.append_child(&cover).unwrap();
|
||||||
|
set_value("license", get_elt_value("popup-license"));
|
||||||
|
clear_autosave();
|
||||||
|
let old_ed = old_ed.dyn_ref::<HtmlFormElement>().unwrap();
|
||||||
|
old_ed.submit().unwrap();
|
||||||
|
})) as Box<dyn FnMut(MouseEvent)>);
|
||||||
|
button
|
||||||
|
.add_event_listener_with_callback("click", callback.as_ref().unchecked_ref())
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
callback.forget();
|
||||||
|
popup
|
||||||
|
.append_child(&button)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
document().body()?.append_child(&popup);
|
document
|
||||||
|
.body()?
|
||||||
|
.append_child(&popup)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
Ok(popup)
|
Ok(popup)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_popup_bg() -> Result<Element, EditorError> {
|
fn init_popup_bg() -> Result<Element, EditorError> {
|
||||||
let bg = document().create_element("div")?;
|
let bg = document()
|
||||||
bg.class_list().add("popup-bg")?;
|
.create_element("div")
|
||||||
bg.set_attribute("id", "popup-bg")?;
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
bg.class_list()
|
||||||
|
.add_1("popup-bg")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
bg.set_attribute("id", "popup-bg")
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
|
||||||
document().body()?.append_child(&bg);
|
document()
|
||||||
bg.add_event_listener(|_: ClickEvent| close_popup());
|
.body()?
|
||||||
|
.append_child(&bg)
|
||||||
|
.map_err(|_| EditorError::DOMError)?;
|
||||||
|
let callback = Closure::wrap(Box::new(|_| close_popup()) as Box<dyn FnMut(MouseEvent)>);
|
||||||
|
bg.add_event_listener_with_callback("click", callback.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
callback.forget();
|
||||||
Ok(bg)
|
Ok(bg)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn chars_left(selector: &str, content: &HtmlElement) -> Option<i32> {
|
fn chars_left(selector: &str, content: &HtmlElement) -> Option<i32> {
|
||||||
match document().query_selector(selector) {
|
match document().query_selector(selector) {
|
||||||
Ok(Some(form)) => HtmlElement::try_from(form).ok().and_then(|form| {
|
Ok(Some(form)) => form.dyn_ref::<HtmlElement>().and_then(|form| {
|
||||||
if let Some(len) = form
|
if let Some(len) = form
|
||||||
.get_attribute("content-size")
|
.get_attribute("content-size")
|
||||||
.and_then(|s| s.parse::<i32>().ok())
|
.and_then(|s| s.parse::<i32>().ok())
|
||||||
{
|
{
|
||||||
(js! {
|
(encode_uri_component(&content.inner_html())
|
||||||
let x = encodeURIComponent(@{content}.innerHTML)
|
.replace("%20", "+")
|
||||||
.replace(/%20/g, "+")
|
.replace("%0A", "%0D0A")
|
||||||
.replace(/%0A/g, "%0D%0A")
|
.replace_by_pattern(&RegExp::new("[!'*()]", "g"), "XXX")
|
||||||
.replace(new RegExp("[!'*()]", "g"), "XXX") // replace exceptions of encodeURIComponent with placeholder
|
.length()
|
||||||
.length + 2;
|
+ 2_u32)
|
||||||
console.log(x);
|
.try_into()
|
||||||
return x;
|
.map(|c: i32| len - c)
|
||||||
})
|
.ok()
|
||||||
.try_into()
|
|
||||||
.map(|c: i32| len - c)
|
|
||||||
.ok()
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -526,26 +676,26 @@ fn chars_left(selector: &str, content: &HtmlElement) -> Option<i32> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn close_popup() {
|
fn close_popup() {
|
||||||
let hide = |x: Element| x.class_list().remove("show");
|
let hide = |x: Element| x.class_list().remove_1("show");
|
||||||
document().get_element_by_id("publish-popup").map(hide);
|
document().get_element_by_id("publish-popup").map(hide);
|
||||||
document().get_element_by_id("popup-bg").map(hide);
|
document().get_element_by_id("popup-bg").map(hide);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_input(label_text: &str, name: &'static str, form: &Element) -> InputElement {
|
fn make_input(label_text: &str, name: &'static str, form: &Element) -> HtmlInputElement {
|
||||||
let label = document().create_element("label").unwrap();
|
let document = document();
|
||||||
label.append_child(&document().create_text_node(label_text));
|
let label = document.create_element("label").unwrap();
|
||||||
|
label
|
||||||
|
.append_child(&document.create_text_node(label_text))
|
||||||
|
.unwrap();
|
||||||
label.set_attribute("for", name).unwrap();
|
label.set_attribute("for", name).unwrap();
|
||||||
|
|
||||||
let inp: InputElement = document()
|
let inp = document.create_element("input").unwrap();
|
||||||
.create_element("input")
|
let inp = inp.dyn_into::<HtmlInputElement>().unwrap();
|
||||||
.unwrap()
|
|
||||||
.try_into()
|
|
||||||
.unwrap();
|
|
||||||
inp.set_attribute("name", name).unwrap();
|
inp.set_attribute("name", name).unwrap();
|
||||||
inp.set_attribute("id", name).unwrap();
|
inp.set_attribute("id", name).unwrap();
|
||||||
|
|
||||||
form.append_child(&label);
|
form.append_child(&label).unwrap();
|
||||||
form.append_child(&inp);
|
form.append_child(&inp).unwrap();
|
||||||
inp
|
inp
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -559,36 +709,46 @@ fn make_editable(tag: &'static str) -> Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn placeholder(elt: HtmlElement, text: &str) -> HtmlElement {
|
fn placeholder(elt: HtmlElement, text: &str) -> HtmlElement {
|
||||||
elt.dataset().insert("placeholder", text).unwrap();
|
elt.dataset().set("placeholder", text).unwrap();
|
||||||
elt.dataset().insert("edited", "false").unwrap();
|
elt.dataset().set("edited", "false").unwrap();
|
||||||
|
|
||||||
elt.add_event_listener(mv!(elt => move |_: FocusEvent| {
|
let callback = Closure::wrap(Box::new(mv!(elt => move |_: FocusEvent| {
|
||||||
if elt.dataset().get("edited").unwrap().as_str() != "true" {
|
if elt.dataset().get("edited").unwrap().as_str() != "true" {
|
||||||
clear_children(&elt);
|
clear_children(&elt);
|
||||||
}
|
}
|
||||||
}));
|
})) as Box<dyn FnMut(FocusEvent)>);
|
||||||
elt.add_event_listener(mv!(elt => move |_: BlurEvent| {
|
elt.add_event_listener_with_callback("focus", callback.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
callback.forget();
|
||||||
|
let callback = Closure::wrap(Box::new(mv!(elt => move |_: Event| {
|
||||||
if elt.dataset().get("edited").unwrap().as_str() != "true" {
|
if elt.dataset().get("edited").unwrap().as_str() != "true" {
|
||||||
clear_children(&elt);
|
clear_children(&elt);
|
||||||
|
|
||||||
let ph = document().create_element("span").expect("Couldn't create placeholder");
|
let ph = document().create_element("span").expect("Couldn't create placeholder");
|
||||||
ph.class_list().add("placeholder").expect("Couldn't add class");
|
ph.class_list().add_1("placeholder").expect("Couldn't add class");
|
||||||
ph.append_child(&document().create_text_node(&elt.dataset().get("placeholder").unwrap_or_default()));
|
ph.append_child(&document().create_text_node(&elt.dataset().get("placeholder").unwrap_or_default())).unwrap();
|
||||||
elt.append_child(&ph);
|
elt.append_child(&ph).unwrap();
|
||||||
}
|
}
|
||||||
}));
|
})) as Box<dyn FnMut(Event)>);
|
||||||
elt.add_event_listener(mv!(elt => move |_: KeyUpEvent| {
|
elt.add_event_listener_with_callback("blur", callback.as_ref().unchecked_ref())
|
||||||
elt.dataset().insert("edited", if elt.inner_text().trim_matches('\n').is_empty() {
|
.unwrap();
|
||||||
|
callback.forget();
|
||||||
|
let callback = Closure::wrap(Box::new(mv!(elt => move |_: KeyboardEvent| {
|
||||||
|
elt.dataset().set("edited", if elt.inner_text().trim_matches('\n').is_empty() {
|
||||||
"false"
|
"false"
|
||||||
} else {
|
} else {
|
||||||
"true"
|
"true"
|
||||||
}).expect("Couldn't update edition state");
|
}).expect("Couldn't update edition state");
|
||||||
}));
|
})) as Box<dyn FnMut(KeyboardEvent)>);
|
||||||
|
elt.add_event_listener_with_callback("keyup", callback.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
callback.forget();
|
||||||
elt
|
elt
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_children(elt: &HtmlElement) {
|
fn clear_children(elt: &HtmlElement) {
|
||||||
for child in elt.child_nodes() {
|
let child_nodes = elt.child_nodes();
|
||||||
elt.remove_child(&child).unwrap();
|
for _ in 0..child_nodes.length() {
|
||||||
|
elt.remove_child(&child_nodes.get(0).unwrap()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Executable
+174
@@ -0,0 +1,174 @@
|
|||||||
|
#![recursion_limit = "128"]
|
||||||
|
#![feature(decl_macro, proc_macro_hygiene, try_trait)]
|
||||||
|
|
||||||
|
#[macro_use]
|
||||||
|
extern crate gettext_macros;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate lazy_static;
|
||||||
|
|
||||||
|
use wasm_bindgen::{prelude::*, JsCast};
|
||||||
|
use web_sys::{console, window, Document, Element, Event, HtmlInputElement, TouchEvent};
|
||||||
|
|
||||||
|
init_i18n!(
|
||||||
|
"plume-front",
|
||||||
|
af,
|
||||||
|
ar,
|
||||||
|
bg,
|
||||||
|
ca,
|
||||||
|
cs,
|
||||||
|
cy,
|
||||||
|
da,
|
||||||
|
de,
|
||||||
|
el,
|
||||||
|
en,
|
||||||
|
eo,
|
||||||
|
es,
|
||||||
|
fa,
|
||||||
|
fi,
|
||||||
|
fr,
|
||||||
|
gl,
|
||||||
|
he,
|
||||||
|
hi,
|
||||||
|
hr,
|
||||||
|
hu,
|
||||||
|
it,
|
||||||
|
ja,
|
||||||
|
ko,
|
||||||
|
nb,
|
||||||
|
nl,
|
||||||
|
no,
|
||||||
|
pl,
|
||||||
|
pt,
|
||||||
|
ro,
|
||||||
|
ru,
|
||||||
|
sat,
|
||||||
|
si,
|
||||||
|
sk,
|
||||||
|
sl,
|
||||||
|
sr,
|
||||||
|
sv,
|
||||||
|
tr,
|
||||||
|
uk,
|
||||||
|
vi,
|
||||||
|
zh
|
||||||
|
);
|
||||||
|
|
||||||
|
mod editor;
|
||||||
|
|
||||||
|
compile_i18n!();
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
static ref CATALOG: gettext::Catalog = {
|
||||||
|
let catalogs = include_i18n!();
|
||||||
|
let lang = window().unwrap().navigator().language().unwrap();
|
||||||
|
let lang = lang.splitn(2, '-').next().unwrap_or("en");
|
||||||
|
|
||||||
|
let english_position = catalogs
|
||||||
|
.iter()
|
||||||
|
.position(|(language_code, _)| *language_code == "en")
|
||||||
|
.unwrap();
|
||||||
|
catalogs
|
||||||
|
.iter()
|
||||||
|
.find(|(l, _)| l == &lang)
|
||||||
|
.unwrap_or(&catalogs[english_position])
|
||||||
|
.clone()
|
||||||
|
.1
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[wasm_bindgen(start)]
|
||||||
|
pub fn main() -> Result<(), JsValue> {
|
||||||
|
extern crate console_error_panic_hook;
|
||||||
|
use std::panic;
|
||||||
|
panic::set_hook(Box::new(console_error_panic_hook::hook));
|
||||||
|
|
||||||
|
menu();
|
||||||
|
search();
|
||||||
|
editor::init()
|
||||||
|
.map_err(|e| console::error_1(&&format!("Editor error: {:?}", e).into()))
|
||||||
|
.ok();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Toggle menu on mobile devices
|
||||||
|
///
|
||||||
|
/// It should normally be working fine even without this code
|
||||||
|
/// But :focus-within is not yet supported by Webkit/Blink
|
||||||
|
fn menu() {
|
||||||
|
let document = document();
|
||||||
|
if let Ok(Some(button)) = document.query_selector("#menu a") {
|
||||||
|
if let Some(menu) = document.get_element_by_id("content") {
|
||||||
|
let show_menu = Closure::wrap(Box::new(|_: TouchEvent| {
|
||||||
|
self::document()
|
||||||
|
.get_element_by_id("menu")
|
||||||
|
.map(|menu| {
|
||||||
|
menu.set_attribute("aria-expanded", "true")
|
||||||
|
.map(|_| menu.class_list().add_1("show"))
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap();
|
||||||
|
}) as Box<dyn FnMut(TouchEvent)>);
|
||||||
|
button
|
||||||
|
.add_event_listener_with_callback("touchend", show_menu.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
show_menu.forget();
|
||||||
|
|
||||||
|
let close_menu = Closure::wrap(Box::new(|evt: TouchEvent| {
|
||||||
|
if evt
|
||||||
|
.target()
|
||||||
|
.unwrap()
|
||||||
|
.dyn_ref::<Element>()
|
||||||
|
.unwrap()
|
||||||
|
.closest("a")
|
||||||
|
.unwrap()
|
||||||
|
.is_some()
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self::document()
|
||||||
|
.get_element_by_id("menu")
|
||||||
|
.map(|menu| {
|
||||||
|
menu.set_attribute("aria-expanded", "false")
|
||||||
|
.map(|_| menu.class_list().remove_1("show"))
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
.unwrap()
|
||||||
|
}) as Box<dyn FnMut(TouchEvent)>);
|
||||||
|
menu.add_event_listener_with_callback("touchend", close_menu.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
close_menu.forget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Clear the URL of the search page before submitting request
|
||||||
|
fn search() {
|
||||||
|
if let Some(form) = document().get_element_by_id("form") {
|
||||||
|
let normalize_query = Closure::wrap(Box::new(|_: Event| {
|
||||||
|
document()
|
||||||
|
.query_selector_all("#form input")
|
||||||
|
.map(|inputs| {
|
||||||
|
for i in 0..inputs.length() {
|
||||||
|
let input = inputs.get(i).unwrap();
|
||||||
|
let input = input.dyn_ref::<HtmlInputElement>().unwrap();
|
||||||
|
if input.name().is_empty() {
|
||||||
|
input.set_name(&input.dyn_ref::<Element>().unwrap().id());
|
||||||
|
}
|
||||||
|
if !input.name().is_empty() && input.value().is_empty() {
|
||||||
|
input.set_name("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}) as Box<dyn FnMut(Event)>);
|
||||||
|
form.add_event_listener_with_callback("submit", normalize_query.as_ref().unchecked_ref())
|
||||||
|
.unwrap();
|
||||||
|
normalize_query.forget();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn document() -> Document {
|
||||||
|
window().unwrap().document().unwrap()
|
||||||
|
}
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
#![recursion_limit = "128"]
|
|
||||||
#![feature(decl_macro, proc_macro_hygiene, try_trait)]
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate gettext_macros;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate stdweb;
|
|
||||||
use stdweb::web::{event::*, *};
|
|
||||||
|
|
||||||
init_i18n!(
|
|
||||||
"plume-front",
|
|
||||||
ar,
|
|
||||||
bg,
|
|
||||||
ca,
|
|
||||||
cs,
|
|
||||||
de,
|
|
||||||
en,
|
|
||||||
eo,
|
|
||||||
es,
|
|
||||||
fa,
|
|
||||||
fr,
|
|
||||||
gl,
|
|
||||||
hi,
|
|
||||||
hr,
|
|
||||||
it,
|
|
||||||
ja,
|
|
||||||
nb,
|
|
||||||
pl,
|
|
||||||
pt,
|
|
||||||
ro,
|
|
||||||
ru,
|
|
||||||
sr,
|
|
||||||
sk,
|
|
||||||
sv
|
|
||||||
);
|
|
||||||
|
|
||||||
mod editor;
|
|
||||||
|
|
||||||
compile_i18n!();
|
|
||||||
|
|
||||||
lazy_static! {
|
|
||||||
static ref CATALOG: gettext::Catalog = {
|
|
||||||
let catalogs = include_i18n!();
|
|
||||||
let lang = js! { return navigator.language }.into_string().unwrap();
|
|
||||||
let lang = lang.splitn(2, '-').next().unwrap_or("en");
|
|
||||||
|
|
||||||
let english_position = catalogs
|
|
||||||
.iter()
|
|
||||||
.position(|(language_code, _)| *language_code == "en")
|
|
||||||
.unwrap();
|
|
||||||
catalogs
|
|
||||||
.iter()
|
|
||||||
.find(|(l, _)| l == &lang)
|
|
||||||
.unwrap_or(&catalogs[english_position])
|
|
||||||
.clone()
|
|
||||||
.1
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
menu();
|
|
||||||
search();
|
|
||||||
editor::init()
|
|
||||||
.map_err(|e| console!(error, format!("Editor error: {:?}", e)))
|
|
||||||
.ok();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Toggle menu on mobile devices
|
|
||||||
///
|
|
||||||
/// It should normally be working fine even without this code
|
|
||||||
/// But :focus-within is not yet supported by Webkit/Blink
|
|
||||||
fn menu() {
|
|
||||||
if let Some(button) = document().get_element_by_id("menu") {
|
|
||||||
if let Some(menu) = document().get_element_by_id("content") {
|
|
||||||
button.add_event_listener(|_: TouchEnd| {
|
|
||||||
document()
|
|
||||||
.get_element_by_id("menu")
|
|
||||||
.map(|menu| menu.class_list().add("show"));
|
|
||||||
});
|
|
||||||
menu.add_event_listener(|_: TouchEnd| {
|
|
||||||
document()
|
|
||||||
.get_element_by_id("menu")
|
|
||||||
.map(|menu| menu.class_list().remove("show"));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Clear the URL of the search page before submitting request
|
|
||||||
fn search() {
|
|
||||||
if let Some(form) = document().get_element_by_id("form") {
|
|
||||||
form.add_event_listener(|_: SubmitEvent| {
|
|
||||||
document()
|
|
||||||
.query_selector_all("#form input")
|
|
||||||
.map(|inputs| {
|
|
||||||
for input in inputs {
|
|
||||||
js! {
|
|
||||||
if (@{&input}.name === "") {
|
|
||||||
@{&input}.name = @{&input}.id
|
|
||||||
}
|
|
||||||
if (@{&input}.name && !@{&input}.value) {
|
|
||||||
@{&input}.name = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.ok();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-macro"
|
name = "plume-macro"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Trinity Pointard <trinity.pointard@insa-rennes.fr>"]
|
authors = ["Trinity Pointard <trinity.pointard@insa-rennes.fr>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Plume procedural macros"
|
description = "Plume procedural macros"
|
||||||
|
|||||||
Regular → Executable
+4
-4
@@ -89,12 +89,12 @@ fn file_to_migration(file: &str) -> TokenStream2 {
|
|||||||
let mut actions = vec![];
|
let mut actions = vec![];
|
||||||
for line in file.lines() {
|
for line in file.lines() {
|
||||||
if sql {
|
if sql {
|
||||||
if line.starts_with("--#!") {
|
if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||||
if !acc.trim().is_empty() {
|
if !acc.trim().is_empty() {
|
||||||
actions.push(quote!(Action::Sql(#acc)));
|
actions.push(quote!(Action::Sql(#acc)));
|
||||||
}
|
}
|
||||||
sql = false;
|
sql = false;
|
||||||
acc = line[4..].to_string();
|
acc = acc_str.to_string();
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
} else if line.starts_with("--") {
|
} else if line.starts_with("--") {
|
||||||
continue;
|
continue;
|
||||||
@@ -102,8 +102,8 @@ fn file_to_migration(file: &str) -> TokenStream2 {
|
|||||||
acc.push_str(line);
|
acc.push_str(line);
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
}
|
}
|
||||||
} else if line.starts_with("--#!") {
|
} else if let Some(acc_str) = line.strip_prefix("--#!") {
|
||||||
acc.push_str(&line[4..]);
|
acc.push_str(&acc_str);
|
||||||
acc.push('\n');
|
acc.push('\n');
|
||||||
} else if line.starts_with("--") {
|
} else if line.starts_with("--") {
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "plume-models"
|
name = "plume-models"
|
||||||
version = "0.6.0"
|
version = "0.6.1-dev"
|
||||||
authors = ["Plume contributors"]
|
authors = ["Plume contributors"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
@@ -16,22 +16,25 @@ lazy_static = "1.0"
|
|||||||
ldap3 = "0.7.1"
|
ldap3 = "0.7.1"
|
||||||
migrations_internals= "1.4.0"
|
migrations_internals= "1.4.0"
|
||||||
openssl = "0.10.22"
|
openssl = "0.10.22"
|
||||||
rocket = "0.4.5"
|
rocket = "0.4.6"
|
||||||
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
rocket_i18n = { git = "https://github.com/Plume-org/rocket_i18n", rev = "e922afa7c366038b3433278c03b1456b346074f2" }
|
||||||
reqwest = "0.9"
|
reqwest = "0.9"
|
||||||
scheduled-thread-pool = "0.2.2"
|
scheduled-thread-pool = "0.2.2"
|
||||||
serde = "1.0"
|
serde = "1.0"
|
||||||
serde_derive = "1.0"
|
serde_derive = "1.0"
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
tantivy = "0.12.0"
|
tantivy = "0.13.3"
|
||||||
url = "2.1"
|
url = "2.1"
|
||||||
walkdir = "2.2"
|
walkdir = "2.2"
|
||||||
webfinger = "0.4.1"
|
webfinger = "0.4.1"
|
||||||
whatlang = "0.7.1"
|
whatlang = "0.11.1"
|
||||||
shrinkwraprs = "0.2.1"
|
shrinkwraprs = "0.2.1"
|
||||||
diesel-derive-newtype = "0.1.2"
|
diesel-derive-newtype = "0.1.2"
|
||||||
glob = "0.3.0"
|
glob = "0.3.0"
|
||||||
lindera-tantivy = { version = "0.1.3", optional = true }
|
lindera-tantivy = { version = "0.7.1", optional = true }
|
||||||
|
tracing = "0.1.22"
|
||||||
|
riker = "0.4.2"
|
||||||
|
once_cell = "1.5.2"
|
||||||
|
|
||||||
[dependencies.chrono]
|
[dependencies.chrono]
|
||||||
features = ["serde"]
|
features = ["serde"]
|
||||||
@@ -39,7 +42,7 @@ version = "0.4"
|
|||||||
|
|
||||||
[dependencies.diesel]
|
[dependencies.diesel]
|
||||||
features = ["r2d2", "chrono"]
|
features = ["r2d2", "chrono"]
|
||||||
version = "1.4.2"
|
version = "1.4.5"
|
||||||
|
|
||||||
[dependencies.plume-api]
|
[dependencies.plume-api]
|
||||||
path = "../plume-api"
|
path = "../plume-api"
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -87,7 +87,7 @@ impl BlocklistedEmail {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{instance::tests as instance_tests, tests::rockets, Connection as Conn};
|
use crate::{instance::tests as instance_tests, tests::db, Connection as Conn};
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
pub(crate) fn fill_database(conn: &Conn) -> Vec<BlocklistedEmail> {
|
pub(crate) fn fill_database(conn: &Conn) -> Vec<BlocklistedEmail> {
|
||||||
@@ -106,29 +106,28 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_match() {
|
fn test_match() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let various = fill_database(conn);
|
let various = fill_database(&conn);
|
||||||
let match1 = "user1@bad-actor.com";
|
let match1 = "user1@bad-actor.com";
|
||||||
let match2 = "spammer@lax-administration.com";
|
let match2 = "spammer@lax-administration.com";
|
||||||
let no_match = "happy-user@lax-administration.com";
|
let no_match = "happy-user@lax-administration.com";
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BlocklistedEmail::matches_blocklist(conn, match1)
|
BlocklistedEmail::matches_blocklist(&conn, match1)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.id,
|
.id,
|
||||||
various[0].id
|
various[0].id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BlocklistedEmail::matches_blocklist(conn, match2)
|
BlocklistedEmail::matches_blocklist(&conn, match2)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.id,
|
.id,
|
||||||
various[1].id
|
various[1].id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
BlocklistedEmail::matches_blocklist(conn, no_match)
|
BlocklistedEmail::matches_blocklist(&conn, no_match)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.is_none(),
|
.is_none(),
|
||||||
true
|
true
|
||||||
|
|||||||
+77
-89
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ap_url, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs,
|
ap_url, db_conn::DbConn, instance::*, medias::Media, posts::Post, safe_string::SafeString,
|
||||||
search::Searcher, users::User, Connection, Error, PlumeRocket, Result, ITEMS_PER_PAGE,
|
schema::blogs, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||||
};
|
};
|
||||||
use activitypub::{
|
use activitypub::{
|
||||||
actor::Group,
|
actor::Group,
|
||||||
@@ -20,7 +20,6 @@ use plume_common::activity_pub::{
|
|||||||
inbox::{AsActor, FromId},
|
inbox::{AsActor, FromId},
|
||||||
sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source,
|
sign, ActivityStream, ApSignature, Id, IntoId, PublicKey, Source,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webfinger::*;
|
use webfinger::*;
|
||||||
|
|
||||||
@@ -132,25 +131,25 @@ impl Blog {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_by_fqn(c: &PlumeRocket, fqn: &str) -> Result<Blog> {
|
pub fn find_by_fqn(conn: &DbConn, fqn: &str) -> Result<Blog> {
|
||||||
let from_db = blogs::table
|
let from_db = blogs::table
|
||||||
.filter(blogs::fqn.eq(fqn))
|
.filter(blogs::fqn.eq(fqn))
|
||||||
.first(&*c.conn)
|
.first(&**conn)
|
||||||
.optional()?;
|
.optional()?;
|
||||||
if let Some(from_db) = from_db {
|
if let Some(from_db) = from_db {
|
||||||
Ok(from_db)
|
Ok(from_db)
|
||||||
} else {
|
} else {
|
||||||
Blog::fetch_from_webfinger(c, fqn)
|
Blog::fetch_from_webfinger(conn, fqn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_from_webfinger(c: &PlumeRocket, acct: &str) -> Result<Blog> {
|
fn fetch_from_webfinger(conn: &DbConn, acct: &str) -> Result<Blog> {
|
||||||
resolve_with_prefix(Prefix::Group, acct.to_owned(), true)?
|
resolve_with_prefix(Prefix::Group, acct.to_owned(), true)?
|
||||||
.links
|
.links
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
||||||
.ok_or(Error::Webfinger)
|
.ok_or(Error::Webfinger)
|
||||||
.and_then(|l| Blog::from_id(c, &l.href?, None).map_err(|(_, e)| e))
|
.and_then(|l| Blog::from_id(conn, &l.href?, None, CONFIG.proxy()).map_err(|(_, e)| e))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_activity(&self, conn: &Connection) -> Result<CustomGroup> {
|
pub fn to_activity(&self, conn: &Connection) -> Result<CustomGroup> {
|
||||||
@@ -217,16 +216,16 @@ impl Blog {
|
|||||||
|
|
||||||
pub fn outbox(&self, conn: &Connection) -> Result<ActivityStream<OrderedCollection>> {
|
pub fn outbox(&self, conn: &Connection) -> Result<ActivityStream<OrderedCollection>> {
|
||||||
let mut coll = OrderedCollection::default();
|
let mut coll = OrderedCollection::default();
|
||||||
coll.collection_props.items = serde_json::to_value(self.get_activities(conn)?)?;
|
coll.collection_props.items = serde_json::to_value(self.get_activities(conn))?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_total_items_u64(self.get_activities(conn)?.len() as u64)?;
|
.set_total_items_u64(self.get_activities(conn).len() as u64)?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?;
|
.set_first_link(Id::new(ap_url(&format!("{}?page=1", &self.outbox_url))))?;
|
||||||
coll.collection_props
|
coll.collection_props
|
||||||
.set_last_link(Id::new(ap_url(&format!(
|
.set_last_link(Id::new(ap_url(&format!(
|
||||||
"{}?page={}",
|
"{}?page={}",
|
||||||
&self.outbox_url,
|
&self.outbox_url,
|
||||||
(self.get_activities(conn)?.len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64
|
(self.get_activities(conn).len() as u64 + ITEMS_PER_PAGE as u64 - 1) as u64
|
||||||
/ ITEMS_PER_PAGE as u64
|
/ ITEMS_PER_PAGE as u64
|
||||||
))))?;
|
))))?;
|
||||||
Ok(ActivityStream::new(coll))
|
Ok(ActivityStream::new(coll))
|
||||||
@@ -237,7 +236,7 @@ impl Blog {
|
|||||||
(min, max): (i32, i32),
|
(min, max): (i32, i32),
|
||||||
) -> Result<ActivityStream<OrderedCollectionPage>> {
|
) -> Result<ActivityStream<OrderedCollectionPage>> {
|
||||||
let mut coll = OrderedCollectionPage::default();
|
let mut coll = OrderedCollectionPage::default();
|
||||||
let acts = self.get_activity_page(&conn, (min, max))?;
|
let acts = self.get_activity_page(&conn, (min, max));
|
||||||
//This still doesn't do anything because the outbox
|
//This still doesn't do anything because the outbox
|
||||||
//doesn't do anything yet
|
//doesn't do anything yet
|
||||||
coll.collection_page_props.set_next_link(Id::new(&format!(
|
coll.collection_page_props.set_next_link(Id::new(&format!(
|
||||||
@@ -253,15 +252,15 @@ impl Blog {
|
|||||||
coll.collection_props.items = serde_json::to_value(acts)?;
|
coll.collection_props.items = serde_json::to_value(acts)?;
|
||||||
Ok(ActivityStream::new(coll))
|
Ok(ActivityStream::new(coll))
|
||||||
}
|
}
|
||||||
fn get_activities(&self, _conn: &Connection) -> Result<Vec<serde_json::Value>> {
|
fn get_activities(&self, _conn: &Connection) -> Vec<serde_json::Value> {
|
||||||
Ok(vec![])
|
vec![]
|
||||||
}
|
}
|
||||||
fn get_activity_page(
|
fn get_activity_page(
|
||||||
&self,
|
&self,
|
||||||
_conn: &Connection,
|
_conn: &Connection,
|
||||||
(_min, _max): (i32, i32),
|
(_min, _max): (i32, i32),
|
||||||
) -> Result<Vec<serde_json::Value>> {
|
) -> Vec<serde_json::Value> {
|
||||||
Ok(vec![])
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_keypair(&self) -> Result<PKey<Private>> {
|
pub fn get_keypair(&self) -> Result<PKey<Private>> {
|
||||||
@@ -318,9 +317,9 @@ impl Blog {
|
|||||||
.and_then(|c| c.url().ok())
|
.and_then(|c| c.url().ok())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
pub fn delete(&self, conn: &Connection) -> Result<()> {
|
||||||
for post in Post::get_for_blog(conn, &self)? {
|
for post in Post::get_for_blog(conn, &self)? {
|
||||||
post.delete(conn, searcher)?;
|
post.delete(conn)?;
|
||||||
}
|
}
|
||||||
diesel::delete(self)
|
diesel::delete(self)
|
||||||
.execute(conn)
|
.execute(conn)
|
||||||
@@ -335,20 +334,20 @@ impl IntoId for Blog {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Blog {
|
impl FromId<DbConn> for Blog {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = CustomGroup;
|
type Object = CustomGroup;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Self::find_by_ap_url(&c.conn, id)
|
Self::find_by_ap_url(&conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, acct: CustomGroup) -> Result<Self> {
|
fn from_activity(conn: &DbConn, acct: CustomGroup) -> Result<Self> {
|
||||||
let url = Url::parse(&acct.object.object_props.id_string()?)?;
|
let url = Url::parse(&acct.object.object_props.id_string()?)?;
|
||||||
let inst = url.host_str()?;
|
let inst = url.host_str()?;
|
||||||
let instance = Instance::find_by_domain(&c.conn, inst).or_else(|_| {
|
let instance = Instance::find_by_domain(conn, inst).or_else(|_| {
|
||||||
Instance::insert(
|
Instance::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewInstance {
|
NewInstance {
|
||||||
public_domain: inst.to_owned(),
|
public_domain: inst.to_owned(),
|
||||||
name: inst.to_owned(),
|
name: inst.to_owned(),
|
||||||
@@ -371,9 +370,9 @@ impl FromId<PlumeRocket> for Blog {
|
|||||||
.and_then(|icon| {
|
.and_then(|icon| {
|
||||||
let owner = icon.object_props.attributed_to_link::<Id>().ok()?;
|
let owner = icon.object_props.attributed_to_link::<Id>().ok()?;
|
||||||
Media::save_remote(
|
Media::save_remote(
|
||||||
&c.conn,
|
conn,
|
||||||
icon.object_props.url_string().ok()?,
|
icon.object_props.url_string().ok()?,
|
||||||
&User::from_id(c, &owner, None).ok()?,
|
&User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?,
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
@@ -387,9 +386,9 @@ impl FromId<PlumeRocket> for Blog {
|
|||||||
.and_then(|banner| {
|
.and_then(|banner| {
|
||||||
let owner = banner.object_props.attributed_to_link::<Id>().ok()?;
|
let owner = banner.object_props.attributed_to_link::<Id>().ok()?;
|
||||||
Media::save_remote(
|
Media::save_remote(
|
||||||
&c.conn,
|
conn,
|
||||||
banner.object_props.url_string().ok()?,
|
banner.object_props.url_string().ok()?,
|
||||||
&User::from_id(c, &owner, None).ok()?,
|
&User::from_id(conn, &owner, None, CONFIG.proxy()).ok()?,
|
||||||
)
|
)
|
||||||
.ok()
|
.ok()
|
||||||
})
|
})
|
||||||
@@ -401,7 +400,7 @@ impl FromId<PlumeRocket> for Blog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Blog::insert(
|
Blog::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewBlog {
|
NewBlog {
|
||||||
actor_id: name.clone(),
|
actor_id: name.clone(),
|
||||||
title: acct.object.object_props.name_string().unwrap_or(name),
|
title: acct.object.object_props.name_string().unwrap_or(name),
|
||||||
@@ -497,14 +496,8 @@ impl NewBlog {
|
|||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
blog_authors::*,
|
blog_authors::*, instance::tests as instance_tests, medias::NewMedia, tests::db,
|
||||||
config::CONFIG,
|
users::tests as usersTests, Connection as Conn,
|
||||||
instance::tests as instance_tests,
|
|
||||||
medias::NewMedia,
|
|
||||||
search::tests::get_searcher,
|
|
||||||
tests::{db, rockets},
|
|
||||||
users::tests as usersTests,
|
|
||||||
Connection as Conn,
|
|
||||||
};
|
};
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
@@ -591,10 +584,10 @@ pub(crate) mod tests {
|
|||||||
fn get_instance() {
|
fn get_instance() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
|
|
||||||
let blog = Blog::insert(
|
let blog = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"SomeName".to_owned(),
|
"SomeName".to_owned(),
|
||||||
"Some name".to_owned(),
|
"Some name".to_owned(),
|
||||||
@@ -606,7 +599,7 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
blog.get_instance(conn).unwrap().id,
|
blog.get_instance(&conn).unwrap().id,
|
||||||
Instance::get_local().unwrap().id
|
Instance::get_local().unwrap().id
|
||||||
);
|
);
|
||||||
// TODO add tests for remote instance
|
// TODO add tests for remote instance
|
||||||
@@ -618,10 +611,10 @@ pub(crate) mod tests {
|
|||||||
fn authors() {
|
fn authors() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (user, _) = fill_database(conn);
|
let (user, _) = fill_database(&conn);
|
||||||
|
|
||||||
let b1 = Blog::insert(
|
let b1 = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"SomeName".to_owned(),
|
"SomeName".to_owned(),
|
||||||
"Some name".to_owned(),
|
"Some name".to_owned(),
|
||||||
@@ -632,7 +625,7 @@ pub(crate) mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let b2 = Blog::insert(
|
let b2 = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"Blog".to_owned(),
|
"Blog".to_owned(),
|
||||||
"Blog".to_owned(),
|
"Blog".to_owned(),
|
||||||
@@ -645,7 +638,7 @@ pub(crate) mod tests {
|
|||||||
let blog = vec![b1, b2];
|
let blog = vec![b1, b2];
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[0].id,
|
blog_id: blog[0].id,
|
||||||
author_id: user[0].id,
|
author_id: user[0].id,
|
||||||
@@ -655,7 +648,7 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[0].id,
|
blog_id: blog[0].id,
|
||||||
author_id: user[1].id,
|
author_id: user[1].id,
|
||||||
@@ -665,7 +658,7 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[1].id,
|
blog_id: blog[1].id,
|
||||||
author_id: user[0].id,
|
author_id: user[0].id,
|
||||||
@@ -675,39 +668,39 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert!(blog[0]
|
assert!(blog[0]
|
||||||
.list_authors(conn)
|
.list_authors(&conn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|a| a.id == user[0].id));
|
.any(|a| a.id == user[0].id));
|
||||||
assert!(blog[0]
|
assert!(blog[0]
|
||||||
.list_authors(conn)
|
.list_authors(&conn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|a| a.id == user[1].id));
|
.any(|a| a.id == user[1].id));
|
||||||
assert!(blog[1]
|
assert!(blog[1]
|
||||||
.list_authors(conn)
|
.list_authors(&conn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|a| a.id == user[0].id));
|
.any(|a| a.id == user[0].id));
|
||||||
assert!(!blog[1]
|
assert!(!blog[1]
|
||||||
.list_authors(conn)
|
.list_authors(&conn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|a| a.id == user[1].id));
|
.any(|a| a.id == user[1].id));
|
||||||
|
|
||||||
assert!(Blog::find_for_author(conn, &user[0])
|
assert!(Blog::find_for_author(&conn, &user[0])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|b| b.id == blog[0].id));
|
.any(|b| b.id == blog[0].id));
|
||||||
assert!(Blog::find_for_author(conn, &user[1])
|
assert!(Blog::find_for_author(&conn, &user[1])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|b| b.id == blog[0].id));
|
.any(|b| b.id == blog[0].id));
|
||||||
assert!(Blog::find_for_author(conn, &user[0])
|
assert!(Blog::find_for_author(&conn, &user[0])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|b| b.id == blog[1].id));
|
.any(|b| b.id == blog[1].id));
|
||||||
assert!(!Blog::find_for_author(conn, &user[1])
|
assert!(!Blog::find_for_author(&conn, &user[1])
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|b| b.id == blog[1].id));
|
.any(|b| b.id == blog[1].id));
|
||||||
@@ -717,13 +710,12 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_local() {
|
fn find_local() {
|
||||||
let r = rockets();
|
let conn = &db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
|
|
||||||
let blog = Blog::insert(
|
let blog = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"SomeName".to_owned(),
|
"SomeName".to_owned(),
|
||||||
"Some name".to_owned(),
|
"Some name".to_owned(),
|
||||||
@@ -734,7 +726,7 @@ pub(crate) mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(Blog::find_by_fqn(&r, "SomeName").unwrap().id, blog.id);
|
assert_eq!(Blog::find_by_fqn(&conn, "SomeName").unwrap().id, blog.id);
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -743,10 +735,10 @@ pub(crate) mod tests {
|
|||||||
fn get_fqn() {
|
fn get_fqn() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
|
|
||||||
let blog = Blog::insert(
|
let blog = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"SomeName".to_owned(),
|
"SomeName".to_owned(),
|
||||||
"Some name".to_owned(),
|
"Some name".to_owned(),
|
||||||
@@ -766,12 +758,10 @@ pub(crate) mod tests {
|
|||||||
fn delete() {
|
fn delete() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, blogs) = fill_database(conn);
|
let (_, blogs) = fill_database(&conn);
|
||||||
|
|
||||||
blogs[0]
|
blogs[0].delete(&conn).unwrap();
|
||||||
.delete(conn, &get_searcher(&CONFIG.search_tokenizers))
|
assert!(Blog::get(&conn, blogs[0].id).is_err());
|
||||||
.unwrap();
|
|
||||||
assert!(Blog::get(conn, blogs[0].id).is_err());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -780,11 +770,10 @@ pub(crate) mod tests {
|
|||||||
fn delete_via_user() {
|
fn delete_via_user() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let searcher = get_searcher(&CONFIG.search_tokenizers);
|
let (user, _) = fill_database(&conn);
|
||||||
let (user, _) = fill_database(conn);
|
|
||||||
|
|
||||||
let b1 = Blog::insert(
|
let b1 = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"SomeName".to_owned(),
|
"SomeName".to_owned(),
|
||||||
"Some name".to_owned(),
|
"Some name".to_owned(),
|
||||||
@@ -795,7 +784,7 @@ pub(crate) mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let b2 = Blog::insert(
|
let b2 = Blog::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlog::new_local(
|
NewBlog::new_local(
|
||||||
"Blog".to_owned(),
|
"Blog".to_owned(),
|
||||||
"Blog".to_owned(),
|
"Blog".to_owned(),
|
||||||
@@ -808,7 +797,7 @@ pub(crate) mod tests {
|
|||||||
let blog = vec![b1, b2];
|
let blog = vec![b1, b2];
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[0].id,
|
blog_id: blog[0].id,
|
||||||
author_id: user[0].id,
|
author_id: user[0].id,
|
||||||
@@ -818,7 +807,7 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[0].id,
|
blog_id: blog[0].id,
|
||||||
author_id: user[1].id,
|
author_id: user[1].id,
|
||||||
@@ -828,7 +817,7 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
BlogAuthor::insert(
|
BlogAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewBlogAuthor {
|
NewBlogAuthor {
|
||||||
blog_id: blog[1].id,
|
blog_id: blog[1].id,
|
||||||
author_id: user[0].id,
|
author_id: user[0].id,
|
||||||
@@ -837,24 +826,23 @@ pub(crate) mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
user[0].delete(conn, &searcher).unwrap();
|
user[0].delete(&conn).unwrap();
|
||||||
assert!(Blog::get(conn, blog[0].id).is_ok());
|
assert!(Blog::get(&conn, blog[0].id).is_ok());
|
||||||
assert!(Blog::get(conn, blog[1].id).is_err());
|
assert!(Blog::get(&conn, blog[1].id).is_err());
|
||||||
user[1].delete(conn, &searcher).unwrap();
|
user[1].delete(&conn).unwrap();
|
||||||
assert!(Blog::get(conn, blog[0].id).is_err());
|
assert!(Blog::get(&conn, blog[0].id).is_err());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn self_federation() {
|
fn self_federation() {
|
||||||
let r = rockets();
|
let conn = &db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, mut blogs) = fill_database(conn);
|
let (users, mut blogs) = fill_database(&conn);
|
||||||
blogs[0].icon_id = Some(
|
blogs[0].icon_id = Some(
|
||||||
Media::insert(
|
Media::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewMedia {
|
NewMedia {
|
||||||
file_path: "aaa.png".into(),
|
file_path: "aaa.png".into(),
|
||||||
alt_text: String::new(),
|
alt_text: String::new(),
|
||||||
@@ -870,7 +858,7 @@ pub(crate) mod tests {
|
|||||||
);
|
);
|
||||||
blogs[0].banner_id = Some(
|
blogs[0].banner_id = Some(
|
||||||
Media::insert(
|
Media::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewMedia {
|
NewMedia {
|
||||||
file_path: "bbb.png".into(),
|
file_path: "bbb.png".into(),
|
||||||
alt_text: String::new(),
|
alt_text: String::new(),
|
||||||
@@ -884,11 +872,11 @@ pub(crate) mod tests {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.id,
|
.id,
|
||||||
);
|
);
|
||||||
let _: Blog = blogs[0].save_changes(conn).unwrap();
|
let _: Blog = blogs[0].save_changes(&**conn).unwrap();
|
||||||
|
|
||||||
let ap_repr = blogs[0].to_activity(conn).unwrap();
|
let ap_repr = blogs[0].to_activity(&conn).unwrap();
|
||||||
blogs[0].delete(conn, &*r.searcher).unwrap();
|
blogs[0].delete(&conn).unwrap();
|
||||||
let blog = Blog::from_activity(&r, ap_repr).unwrap();
|
let blog = Blog::from_activity(&conn, ap_repr).unwrap();
|
||||||
|
|
||||||
assert_eq!(blog.actor_id, blogs[0].actor_id);
|
assert_eq!(blog.actor_id, blogs[0].actor_id);
|
||||||
assert_eq!(blog.title, blogs[0].title);
|
assert_eq!(blog.title, blogs[0].title);
|
||||||
@@ -900,8 +888,8 @@ pub(crate) mod tests {
|
|||||||
assert_eq!(blog.public_key, blogs[0].public_key);
|
assert_eq!(blog.public_key, blogs[0].public_key);
|
||||||
assert_eq!(blog.fqn, blogs[0].fqn);
|
assert_eq!(blog.fqn, blogs[0].fqn);
|
||||||
assert_eq!(blog.summary_html, blogs[0].summary_html);
|
assert_eq!(blog.summary_html, blogs[0].summary_html);
|
||||||
assert_eq!(blog.icon_url(conn), blogs[0].icon_url(conn));
|
assert_eq!(blog.icon_url(&conn), blogs[0].icon_url(&conn));
|
||||||
assert_eq!(blog.banner_url(conn), blogs[0].banner_url(conn));
|
assert_eq!(blog.banner_url(&conn), blogs[0].banner_url(&conn));
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comment_seers::{CommentSeers, NewCommentSeers},
|
comment_seers::{CommentSeers, NewCommentSeers},
|
||||||
|
db_conn::DbConn,
|
||||||
instance::Instance,
|
instance::Instance,
|
||||||
medias::Media,
|
medias::Media,
|
||||||
mentions::Mention,
|
mentions::Mention,
|
||||||
@@ -8,7 +9,7 @@ use crate::{
|
|||||||
safe_string::SafeString,
|
safe_string::SafeString,
|
||||||
schema::comments,
|
schema::comments,
|
||||||
users::User,
|
users::User,
|
||||||
Connection, Error, PlumeRocket, Result,
|
Connection, Error, Result, CONFIG,
|
||||||
};
|
};
|
||||||
use activitypub::{
|
use activitypub::{
|
||||||
activity::{Create, Delete},
|
activity::{Create, Delete},
|
||||||
@@ -24,7 +25,6 @@ use plume_common::{
|
|||||||
},
|
},
|
||||||
utils,
|
utils,
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
||||||
@@ -105,13 +105,13 @@ impl Comment {
|
|||||||
.unwrap_or(false)
|
.unwrap_or(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_activity(&self, c: &PlumeRocket) -> Result<Note> {
|
pub fn to_activity(&self, conn: &DbConn) -> Result<Note> {
|
||||||
let author = User::get(&c.conn, self.author_id)?;
|
let author = User::get(conn, self.author_id)?;
|
||||||
let (html, mentions, _hashtags) = utils::md_to_html(
|
let (html, mentions, _hashtags) = utils::md_to_html(
|
||||||
self.content.get().as_ref(),
|
self.content.get().as_ref(),
|
||||||
Some(&Instance::get_local()?.public_domain),
|
Some(&Instance::get_local()?.public_domain),
|
||||||
true,
|
true,
|
||||||
Some(Media::get_media_processor(&c.conn, vec![&author])),
|
Some(Media::get_media_processor(conn, vec![&author])),
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut note = Note::default();
|
let mut note = Note::default();
|
||||||
@@ -124,8 +124,8 @@ impl Comment {
|
|||||||
note.object_props.set_content_string(html)?;
|
note.object_props.set_content_string(html)?;
|
||||||
note.object_props
|
note.object_props
|
||||||
.set_in_reply_to_link(Id::new(self.in_response_to_id.map_or_else(
|
.set_in_reply_to_link(Id::new(self.in_response_to_id.map_or_else(
|
||||||
|| Ok(Post::get(&c.conn, self.post_id)?.ap_url),
|
|| Ok(Post::get(conn, self.post_id)?.ap_url),
|
||||||
|id| Ok(Comment::get(&c.conn, id)?.ap_url.unwrap_or_default()) as Result<String>,
|
|id| Ok(Comment::get(conn, id)?.ap_url.unwrap_or_default()) as Result<String>,
|
||||||
)?))?;
|
)?))?;
|
||||||
note.object_props
|
note.object_props
|
||||||
.set_published_string(chrono::Utc::now().to_rfc3339())?;
|
.set_published_string(chrono::Utc::now().to_rfc3339())?;
|
||||||
@@ -134,16 +134,16 @@ impl Comment {
|
|||||||
note.object_props.set_tag_link_vec(
|
note.object_props.set_tag_link_vec(
|
||||||
mentions
|
mentions
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|m| Mention::build_activity(c, &m).ok())
|
.filter_map(|m| Mention::build_activity(conn, &m).ok())
|
||||||
.collect::<Vec<link::Mention>>(),
|
.collect::<Vec<link::Mention>>(),
|
||||||
)?;
|
)?;
|
||||||
Ok(note)
|
Ok(note)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn create_activity(&self, c: &PlumeRocket) -> Result<Create> {
|
pub fn create_activity(&self, conn: &DbConn) -> Result<Create> {
|
||||||
let author = User::get(&c.conn, self.author_id)?;
|
let author = User::get(&conn, self.author_id)?;
|
||||||
|
|
||||||
let note = self.to_activity(c)?;
|
let note = self.to_activity(conn)?;
|
||||||
let mut act = Create::default();
|
let mut act = Create::default();
|
||||||
act.create_props.set_actor_link(author.into_id())?;
|
act.create_props.set_actor_link(author.into_id())?;
|
||||||
act.create_props.set_object_object(note.clone())?;
|
act.create_props.set_object_object(note.clone())?;
|
||||||
@@ -152,7 +152,7 @@ impl Comment {
|
|||||||
act.object_props
|
act.object_props
|
||||||
.set_to_link_vec(note.object_props.to_link_vec::<Id>()?)?;
|
.set_to_link_vec(note.object_props.to_link_vec::<Id>()?)?;
|
||||||
act.object_props
|
act.object_props
|
||||||
.set_cc_link_vec(vec![Id::new(self.get_author(&c.conn)?.followers_endpoint)])?;
|
.set_cc_link_vec(vec![Id::new(self.get_author(&conn)?.followers_endpoint)])?;
|
||||||
Ok(act)
|
Ok(act)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,16 +194,15 @@ impl Comment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Comment {
|
impl FromId<DbConn> for Comment {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = Note;
|
type Object = Note;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Self::find_by_ap_url(&c.conn, id)
|
Self::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, note: Note) -> Result<Self> {
|
fn from_activity(conn: &DbConn, note: Note) -> Result<Self> {
|
||||||
let conn = &*c.conn;
|
|
||||||
let comm = {
|
let comm = {
|
||||||
let previous_url = note.object_props.in_reply_to.as_ref()?.as_str()?;
|
let previous_url = note.object_props.in_reply_to.as_ref()?.as_str()?;
|
||||||
let previous_comment = Comment::find_by_ap_url(conn, previous_url);
|
let previous_comment = Comment::find_by_ap_url(conn, previous_url);
|
||||||
@@ -236,9 +235,10 @@ impl FromId<PlumeRocket> for Comment {
|
|||||||
Ok(Post::find_by_ap_url(conn, previous_url)?.id) as Result<i32>
|
Ok(Post::find_by_ap_url(conn, previous_url)?.id) as Result<i32>
|
||||||
})?,
|
})?,
|
||||||
author_id: User::from_id(
|
author_id: User::from_id(
|
||||||
c,
|
conn,
|
||||||
¬e.object_props.attributed_to_link::<Id>()?,
|
¬e.object_props.attributed_to_link::<Id>()?,
|
||||||
None,
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
)
|
)
|
||||||
.map_err(|(_, e)| e)?
|
.map_err(|(_, e)| e)?
|
||||||
.id,
|
.id,
|
||||||
@@ -296,7 +296,7 @@ impl FromId<PlumeRocket> for Comment {
|
|||||||
.collect::<HashSet<_>>() // remove duplicates (don't do a query more than once)
|
.collect::<HashSet<_>>() // remove duplicates (don't do a query more than once)
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v| {
|
.map(|v| {
|
||||||
if let Ok(user) = User::from_id(c, &v, None) {
|
if let Ok(user) = User::from_id(conn, &v, None, CONFIG.proxy()) {
|
||||||
vec![user]
|
vec![user]
|
||||||
} else {
|
} else {
|
||||||
vec![] // TODO try to fetch collection
|
vec![] // TODO try to fetch collection
|
||||||
@@ -322,41 +322,41 @@ impl FromId<PlumeRocket> for Comment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Create, &PlumeRocket> for Comment {
|
impl AsObject<User, Create, &DbConn> for Comment {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn activity(self, _c: &PlumeRocket, _actor: User, _id: &str) -> Result<Self> {
|
fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result<Self> {
|
||||||
// The actual creation takes place in the FromId impl
|
// The actual creation takes place in the FromId impl
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Delete, &PlumeRocket> for Comment {
|
impl AsObject<User, Delete, &DbConn> for Comment {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
if self.author_id != actor.id {
|
if self.author_id != actor.id {
|
||||||
return Err(Error::Unauthorized);
|
return Err(Error::Unauthorized);
|
||||||
}
|
}
|
||||||
|
|
||||||
for m in Mention::list_for_comment(&c.conn, self.id)? {
|
for m in Mention::list_for_comment(conn, self.id)? {
|
||||||
for n in Notification::find_for_mention(&c.conn, &m)? {
|
for n in Notification::find_for_mention(conn, &m)? {
|
||||||
n.delete(&c.conn)?;
|
n.delete(conn)?;
|
||||||
}
|
}
|
||||||
m.delete(&c.conn)?;
|
m.delete(conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
for n in Notification::find_for_comment(&c.conn, &self)? {
|
for n in Notification::find_for_comment(&conn, &self)? {
|
||||||
n.delete(&c.conn)?;
|
n.delete(&**conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::update(comments::table)
|
diesel::update(comments::table)
|
||||||
.filter(comments::in_response_to_id.eq(self.id))
|
.filter(comments::in_response_to_id.eq(self.id))
|
||||||
.set(comments::in_response_to_id.eq(self.in_response_to_id))
|
.set(comments::in_response_to_id.eq(self.in_response_to_id))
|
||||||
.execute(&*c.conn)?;
|
.execute(&**conn)?;
|
||||||
diesel::delete(&self).execute(&*c.conn)?;
|
diesel::delete(&self).execute(&**conn)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -392,17 +392,16 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::inbox::{inbox, tests::fill_database, InboxResult};
|
use crate::inbox::{inbox, tests::fill_database, InboxResult};
|
||||||
use crate::safe_string::SafeString;
|
use crate::safe_string::SafeString;
|
||||||
use crate::tests::rockets;
|
use crate::tests::db;
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
// creates a post, get it's Create activity, delete the post,
|
// creates a post, get it's Create activity, delete the post,
|
||||||
// "send" the Create to the inbox, and check it works
|
// "send" the Create to the inbox, and check it works
|
||||||
#[test]
|
#[test]
|
||||||
fn self_federation() {
|
fn self_federation() {
|
||||||
let r = rockets();
|
let conn = &db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let original_comm = Comment::insert(
|
let original_comm = Comment::insert(
|
||||||
conn,
|
conn,
|
||||||
@@ -418,14 +417,14 @@ mod tests {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let act = original_comm.create_activity(&r).unwrap();
|
let act = original_comm.create_activity(&conn).unwrap();
|
||||||
inbox(
|
inbox(
|
||||||
&r,
|
&conn,
|
||||||
serde_json::to_value(original_comm.build_delete(conn).unwrap()).unwrap(),
|
serde_json::to_value(original_comm.build_delete(&conn).unwrap()).unwrap(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match inbox(&r, serde_json::to_value(act).unwrap()).unwrap() {
|
match inbox(&conn, serde_json::to_value(act).unwrap()).unwrap() {
|
||||||
InboxResult::Commented(c) => {
|
InboxResult::Commented(c) => {
|
||||||
// TODO: one is HTML, the other markdown: assert_eq!(c.content, original_comm.content);
|
// TODO: one is HTML, the other markdown: assert_eq!(c.content, original_comm.content);
|
||||||
assert_eq!(c.in_response_to_id, original_comm.in_response_to_id);
|
assert_eq!(c.in_response_to_id, original_comm.in_response_to_id);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use crate::search::TokenizerKind as SearchTokenizer;
|
use crate::search::TokenizerKind as SearchTokenizer;
|
||||||
use rocket::config::Limits;
|
use rocket::config::Limits;
|
||||||
use rocket::Config as RocketConfig;
|
use rocket::Config as RocketConfig;
|
||||||
|
use std::collections::HashSet;
|
||||||
use std::env::{self, var};
|
use std::env::{self, var};
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
@@ -21,6 +22,12 @@ pub struct Config {
|
|||||||
pub default_theme: String,
|
pub default_theme: String,
|
||||||
pub media_directory: String,
|
pub media_directory: String,
|
||||||
pub ldap: Option<LdapConfig>,
|
pub ldap: Option<LdapConfig>,
|
||||||
|
pub proxy: Option<ProxyConfig>,
|
||||||
|
}
|
||||||
|
impl Config {
|
||||||
|
pub fn proxy(&self) -> Option<&reqwest::Proxy> {
|
||||||
|
self.proxy.as_ref().map(|p| &p.proxy)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@@ -157,8 +164,8 @@ impl Default for LogoConfig {
|
|||||||
};
|
};
|
||||||
let mut custom_icons = env::vars()
|
let mut custom_icons = env::vars()
|
||||||
.filter_map(|(var, val)| {
|
.filter_map(|(var, val)| {
|
||||||
if var.starts_with("PLUME_LOGO_") {
|
if let Some(size) = var.strip_prefix("PLUME_LOGO_") {
|
||||||
Some((var[11..].to_owned(), val))
|
Some((size.to_owned(), val))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -247,6 +254,7 @@ pub struct LdapConfig {
|
|||||||
pub tls: bool,
|
pub tls: bool,
|
||||||
pub user_name_attr: String,
|
pub user_name_attr: String,
|
||||||
pub mail_attr: String,
|
pub mail_attr: String,
|
||||||
|
pub user: Option<(String, String)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_ldap_config() -> Option<LdapConfig> {
|
fn get_ldap_config() -> Option<LdapConfig> {
|
||||||
@@ -262,21 +270,68 @@ fn get_ldap_config() -> Option<LdapConfig> {
|
|||||||
};
|
};
|
||||||
let user_name_attr = var("LDAP_USER_NAME_ATTR").unwrap_or_else(|_| "cn".to_owned());
|
let user_name_attr = var("LDAP_USER_NAME_ATTR").unwrap_or_else(|_| "cn".to_owned());
|
||||||
let mail_attr = var("LDAP_USER_MAIL_ATTR").unwrap_or_else(|_| "mail".to_owned());
|
let mail_attr = var("LDAP_USER_MAIL_ATTR").unwrap_or_else(|_| "mail".to_owned());
|
||||||
|
let user = var("LDAP_USER").ok();
|
||||||
|
let password = var("LDAP_PASSWORD").ok();
|
||||||
|
let user = match (user, password) {
|
||||||
|
(Some(user), Some(password)) => Some((user, password)),
|
||||||
|
(None, None) => None,
|
||||||
|
_ => panic!("Invalid LDAP configuration both or neither of LDAP_USER and LDAP_PASSWORD must be set")
|
||||||
|
};
|
||||||
Some(LdapConfig {
|
Some(LdapConfig {
|
||||||
addr,
|
addr,
|
||||||
base_dn,
|
base_dn,
|
||||||
tls,
|
tls,
|
||||||
user_name_attr,
|
user_name_attr,
|
||||||
mail_attr,
|
mail_attr,
|
||||||
|
user
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
(None, None) => None,
|
(None, None) => None,
|
||||||
(_, _) => {
|
_ => {
|
||||||
panic!("Invalid LDAP configuration : both LDAP_ADDR and LDAP_BASE_DN must be set")
|
panic!("Invalid LDAP configuration : both LDAP_ADDR and LDAP_BASE_DN must be set")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ProxyConfig {
|
||||||
|
pub url: reqwest::Url,
|
||||||
|
pub only_domains: Option<HashSet<String>>,
|
||||||
|
pub proxy: reqwest::Proxy,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_proxy_config() -> Option<ProxyConfig> {
|
||||||
|
let url: reqwest::Url = var("PROXY_URL").ok()?.parse().expect("Invalid PROXY_URL");
|
||||||
|
let proxy_url = url.clone();
|
||||||
|
let only_domains: Option<HashSet<String>> = var("PROXY_DOMAINS")
|
||||||
|
.ok()
|
||||||
|
.map(|ods| ods.split(',').map(str::to_owned).collect());
|
||||||
|
let proxy = if let Some(ref only_domains) = only_domains {
|
||||||
|
let only_domains = only_domains.clone();
|
||||||
|
reqwest::Proxy::custom(move |url| {
|
||||||
|
if let Some(domain) = url.domain() {
|
||||||
|
if only_domains.contains(domain)
|
||||||
|
|| only_domains
|
||||||
|
.iter()
|
||||||
|
.any(|target| domain.ends_with(&format!(".{}", target)))
|
||||||
|
{
|
||||||
|
Some(proxy_url.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
reqwest::Proxy::all(proxy_url).expect("Invalid PROXY_URL")
|
||||||
|
};
|
||||||
|
Some(ProxyConfig {
|
||||||
|
url,
|
||||||
|
only_domains,
|
||||||
|
proxy,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref CONFIG: Config = Config {
|
pub static ref CONFIG: Config = Config {
|
||||||
base_url: var("BASE_URL").unwrap_or_else(|_| format!(
|
base_url: var("BASE_URL").unwrap_or_else(|_| format!(
|
||||||
@@ -305,5 +360,6 @@ lazy_static! {
|
|||||||
media_directory: var("MEDIA_UPLOAD_DIRECTORY")
|
media_directory: var("MEDIA_UPLOAD_DIRECTORY")
|
||||||
.unwrap_or_else(|_| "static/media".to_owned()),
|
.unwrap_or_else(|_| "static/media".to_owned()),
|
||||||
ldap: get_ldap_config(),
|
ldap: get_ldap_config(),
|
||||||
|
proxy: get_proxy_config(),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-21
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ap_url, notifications::*, schema::follows, users::User, Connection, Error, PlumeRocket, Result,
|
ap_url, db_conn::DbConn, notifications::*, schema::follows, users::User, Connection, Error,
|
||||||
CONFIG,
|
Result, CONFIG,
|
||||||
};
|
};
|
||||||
use activitypub::activity::{Accept, Follow as FollowAct, Undo};
|
use activitypub::activity::{Accept, Follow as FollowAct, Undo};
|
||||||
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||||
@@ -116,7 +116,12 @@ impl Follow {
|
|||||||
.accept_props
|
.accept_props
|
||||||
.set_actor_link::<Id>(target.clone().into_id())?;
|
.set_actor_link::<Id>(target.clone().into_id())?;
|
||||||
accept.accept_props.set_object_object(follow)?;
|
accept.accept_props.set_object_object(follow)?;
|
||||||
broadcast(&*target, accept, vec![from.clone()]);
|
broadcast(
|
||||||
|
&*target,
|
||||||
|
accept,
|
||||||
|
vec![from.clone()],
|
||||||
|
CONFIG.proxy().cloned(),
|
||||||
|
);
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,11 +141,11 @@ impl Follow {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, FollowAct, &PlumeRocket> for User {
|
impl AsObject<User, FollowAct, &DbConn> for User {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = Follow;
|
type Output = Follow;
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, id: &str) -> Result<Follow> {
|
fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result<Follow> {
|
||||||
// Mastodon (at least) requires the full Follow object when accepting it,
|
// Mastodon (at least) requires the full Follow object when accepting it,
|
||||||
// so we rebuilt it here
|
// so we rebuilt it here
|
||||||
let mut follow = FollowAct::default();
|
let mut follow = FollowAct::default();
|
||||||
@@ -148,40 +153,50 @@ impl AsObject<User, FollowAct, &PlumeRocket> for User {
|
|||||||
follow
|
follow
|
||||||
.follow_props
|
.follow_props
|
||||||
.set_actor_link::<Id>(actor.clone().into_id())?;
|
.set_actor_link::<Id>(actor.clone().into_id())?;
|
||||||
Follow::accept_follow(&c.conn, &actor, &self, follow, actor.id, self.id)
|
Follow::accept_follow(conn, &actor, &self, follow, actor.id, self.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Follow {
|
impl FromId<DbConn> for Follow {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = FollowAct;
|
type Object = FollowAct;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Follow::find_by_ap_url(&c.conn, id)
|
Follow::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, follow: FollowAct) -> Result<Self> {
|
fn from_activity(conn: &DbConn, follow: FollowAct) -> Result<Self> {
|
||||||
let actor =
|
let actor = User::from_id(
|
||||||
User::from_id(c, &follow.follow_props.actor_link::<Id>()?, None).map_err(|(_, e)| e)?;
|
conn,
|
||||||
|
&follow.follow_props.actor_link::<Id>()?,
|
||||||
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
|
)
|
||||||
|
.map_err(|(_, e)| e)?;
|
||||||
|
|
||||||
let target = User::from_id(c, &follow.follow_props.object_link::<Id>()?, None)
|
let target = User::from_id(
|
||||||
.map_err(|(_, e)| e)?;
|
conn,
|
||||||
Follow::accept_follow(&c.conn, &actor, &target, follow, actor.id, target.id)
|
&follow.follow_props.object_link::<Id>()?,
|
||||||
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
|
)
|
||||||
|
.map_err(|(_, e)| e)?;
|
||||||
|
Follow::accept_follow(conn, &actor, &target, follow, actor.id, target.id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Undo, &PlumeRocket> for Follow {
|
impl AsObject<User, Undo, &DbConn> for Follow {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
let conn = &*c.conn;
|
let conn = conn;
|
||||||
if self.follower_id == actor.id {
|
if self.follower_id == actor.id {
|
||||||
diesel::delete(&self).execute(conn)?;
|
diesel::delete(&self).execute(&**conn)?;
|
||||||
|
|
||||||
// delete associated notification if any
|
// delete associated notification if any
|
||||||
if let Ok(notif) = Notification::find(conn, notification_kind::FOLLOW, self.id) {
|
if let Ok(notif) = Notification::find(&conn, notification_kind::FOLLOW, self.id) {
|
||||||
diesel::delete(¬if).execute(conn)?;
|
diesel::delete(¬if).execute(&**conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
+88
-107
@@ -1,13 +1,13 @@
|
|||||||
use activitypub::activity::*;
|
use activitypub::activity::*;
|
||||||
use serde_json;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
comments::Comment,
|
comments::Comment,
|
||||||
|
db_conn::DbConn,
|
||||||
follows, likes,
|
follows, likes,
|
||||||
posts::{Post, PostUpdate},
|
posts::{Post, PostUpdate},
|
||||||
reshares::Reshare,
|
reshares::Reshare,
|
||||||
users::User,
|
users::User,
|
||||||
Error, PlumeRocket,
|
Error, CONFIG,
|
||||||
};
|
};
|
||||||
use plume_common::activity_pub::inbox::Inbox;
|
use plume_common::activity_pub::inbox::Inbox;
|
||||||
|
|
||||||
@@ -46,20 +46,20 @@ impl_into_inbox_result! {
|
|||||||
Reshare => Reshared
|
Reshare => Reshared
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result<InboxResult, Error> {
|
pub fn inbox(conn: &DbConn, act: serde_json::Value) -> Result<InboxResult, Error> {
|
||||||
Inbox::handle(ctx, act)
|
Inbox::handle(conn, act)
|
||||||
.with::<User, Announce, Post>()
|
.with::<User, Announce, Post>(CONFIG.proxy())
|
||||||
.with::<User, Create, Comment>()
|
.with::<User, Create, Comment>(CONFIG.proxy())
|
||||||
.with::<User, Create, Post>()
|
.with::<User, Create, Post>(CONFIG.proxy())
|
||||||
.with::<User, Delete, Comment>()
|
.with::<User, Delete, Comment>(CONFIG.proxy())
|
||||||
.with::<User, Delete, Post>()
|
.with::<User, Delete, Post>(CONFIG.proxy())
|
||||||
.with::<User, Delete, User>()
|
.with::<User, Delete, User>(CONFIG.proxy())
|
||||||
.with::<User, Follow, User>()
|
.with::<User, Follow, User>(CONFIG.proxy())
|
||||||
.with::<User, Like, Post>()
|
.with::<User, Like, Post>(CONFIG.proxy())
|
||||||
.with::<User, Undo, Reshare>()
|
.with::<User, Undo, Reshare>(CONFIG.proxy())
|
||||||
.with::<User, Undo, follows::Follow>()
|
.with::<User, Undo, follows::Follow>(CONFIG.proxy())
|
||||||
.with::<User, Undo, likes::Like>()
|
.with::<User, Undo, likes::Like>(CONFIG.proxy())
|
||||||
.with::<User, Update, PostUpdate>()
|
.with::<User, Update, PostUpdate>(CONFIG.proxy())
|
||||||
.done()
|
.done()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,13 +67,13 @@ pub fn inbox(ctx: &PlumeRocket, act: serde_json::Value) -> Result<InboxResult, E
|
|||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::InboxResult;
|
use super::InboxResult;
|
||||||
use crate::blogs::tests::fill_database as blog_fill_db;
|
use crate::blogs::tests::fill_database as blog_fill_db;
|
||||||
|
use crate::db_conn::DbConn;
|
||||||
use crate::safe_string::SafeString;
|
use crate::safe_string::SafeString;
|
||||||
use crate::tests::rockets;
|
use crate::tests::db;
|
||||||
use crate::PlumeRocket;
|
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
pub fn fill_database(
|
pub fn fill_database(
|
||||||
rockets: &PlumeRocket,
|
conn: &DbConn,
|
||||||
) -> (
|
) -> (
|
||||||
Vec<crate::posts::Post>,
|
Vec<crate::posts::Post>,
|
||||||
Vec<crate::users::User>,
|
Vec<crate::users::User>,
|
||||||
@@ -82,9 +82,9 @@ pub(crate) mod tests {
|
|||||||
use crate::post_authors::*;
|
use crate::post_authors::*;
|
||||||
use crate::posts::*;
|
use crate::posts::*;
|
||||||
|
|
||||||
let (users, blogs) = blog_fill_db(&rockets.conn);
|
let (users, blogs) = blog_fill_db(&conn);
|
||||||
let post = Post::insert(
|
let post = Post::insert(
|
||||||
&rockets.conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "testing".to_owned(),
|
slug: "testing".to_owned(),
|
||||||
@@ -98,12 +98,11 @@ pub(crate) mod tests {
|
|||||||
source: String::new(),
|
source: String::new(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&rockets.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
PostAuthor::insert(
|
PostAuthor::insert(
|
||||||
&rockets.conn,
|
&conn,
|
||||||
NewPostAuthor {
|
NewPostAuthor {
|
||||||
post_id: post.id,
|
post_id: post.id,
|
||||||
author_id: users[0].id,
|
author_id: users[0].id,
|
||||||
@@ -116,10 +115,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn announce_post() {
|
fn announce_post() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/announce/1",
|
"id": "https://plu.me/announce/1",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -127,7 +125,7 @@ pub(crate) mod tests {
|
|||||||
"type": "Announce",
|
"type": "Announce",
|
||||||
});
|
});
|
||||||
|
|
||||||
match super::inbox(&r, act).unwrap() {
|
match super::inbox(&conn, act).unwrap() {
|
||||||
super::InboxResult::Reshared(r) => {
|
super::InboxResult::Reshared(r) => {
|
||||||
assert_eq!(r.post_id, posts[0].id);
|
assert_eq!(r.post_id, posts[0].id);
|
||||||
assert_eq!(r.user_id, users[0].id);
|
assert_eq!(r.user_id, users[0].id);
|
||||||
@@ -141,10 +139,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_comment() {
|
fn create_comment() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -159,7 +156,7 @@ pub(crate) mod tests {
|
|||||||
"type": "Create",
|
"type": "Create",
|
||||||
});
|
});
|
||||||
|
|
||||||
match super::inbox(&r, act).unwrap() {
|
match super::inbox(&conn, act).unwrap() {
|
||||||
super::InboxResult::Commented(c) => {
|
super::InboxResult::Commented(c) => {
|
||||||
assert_eq!(c.author_id, users[0].id);
|
assert_eq!(c.author_id, users[0].id);
|
||||||
assert_eq!(c.post_id, posts[0].id);
|
assert_eq!(c.post_id, posts[0].id);
|
||||||
@@ -175,10 +172,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_comment() {
|
fn spoof_comment() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -194,7 +190,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -205,10 +201,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_comment_by_object_with_id() {
|
fn spoof_comment_by_object_with_id() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -226,7 +221,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -236,10 +231,9 @@ pub(crate) mod tests {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_comment_by_object_without_id() {
|
fn spoof_comment_by_object_without_id() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -255,7 +249,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -266,10 +260,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn create_post() {
|
fn create_post() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, blogs) = fill_database(&r);
|
let (_, users, blogs) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -290,9 +283,9 @@ pub(crate) mod tests {
|
|||||||
"type": "Create",
|
"type": "Create",
|
||||||
});
|
});
|
||||||
|
|
||||||
match super::inbox(&r, act).unwrap() {
|
match super::inbox(&conn, act).unwrap() {
|
||||||
super::InboxResult::Post(p) => {
|
super::InboxResult::Post(p) => {
|
||||||
assert!(p.is_author(conn, users[0].id).unwrap());
|
assert!(p.is_author(&conn, users[0].id).unwrap());
|
||||||
assert_eq!(p.source, "Hello.".to_owned());
|
assert_eq!(p.source, "Hello.".to_owned());
|
||||||
assert_eq!(p.blog_id, blogs[0].id);
|
assert_eq!(p.blog_id, blogs[0].id);
|
||||||
assert_eq!(p.content, SafeString::new("Hello."));
|
assert_eq!(p.content, SafeString::new("Hello."));
|
||||||
@@ -307,10 +300,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_post() {
|
fn spoof_post() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, blogs) = fill_database(&r);
|
let (_, users, blogs) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -332,7 +324,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -343,10 +335,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_post_by_object_with_id() {
|
fn spoof_post_by_object_with_id() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, blogs) = fill_database(&r);
|
let (_, users, blogs) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -371,7 +362,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -382,10 +373,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn spoof_post_by_object_without_id() {
|
fn spoof_post_by_object_without_id() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, blogs) = fill_database(&r);
|
let (_, users, blogs) = fill_database(&conn);
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/comment/1/activity",
|
"id": "https://plu.me/comment/1/activity",
|
||||||
"actor": users[0].ap_url,
|
"actor": users[0].ap_url,
|
||||||
@@ -407,7 +397,7 @@ pub(crate) mod tests {
|
|||||||
});
|
});
|
||||||
|
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
super::inbox(&r, act.clone()),
|
super::inbox(&conn, act.clone()),
|
||||||
Err(super::Error::Inbox(
|
Err(super::Error::Inbox(
|
||||||
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
box plume_common::activity_pub::inbox::InboxError::InvalidObject(_),
|
||||||
))
|
))
|
||||||
@@ -420,12 +410,11 @@ pub(crate) mod tests {
|
|||||||
fn delete_comment() {
|
fn delete_comment() {
|
||||||
use crate::comments::*;
|
use crate::comments::*;
|
||||||
|
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
Comment::insert(
|
Comment::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewComment {
|
NewComment {
|
||||||
content: SafeString::new("My comment"),
|
content: SafeString::new("My comment"),
|
||||||
in_response_to_id: None,
|
in_response_to_id: None,
|
||||||
@@ -445,7 +434,7 @@ pub(crate) mod tests {
|
|||||||
"object": "https://plu.me/comment/1",
|
"object": "https://plu.me/comment/1",
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/comment/1/delete",
|
"id": "https://plu.me/comment/1/delete",
|
||||||
@@ -453,17 +442,16 @@ pub(crate) mod tests {
|
|||||||
"object": "https://plu.me/comment/1",
|
"object": "https://plu.me/comment/1",
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delete_post() {
|
fn delete_post() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let fail_act = json!({
|
let fail_act = json!({
|
||||||
"id": "https://plu.me/comment/1/delete",
|
"id": "https://plu.me/comment/1/delete",
|
||||||
@@ -471,7 +459,7 @@ pub(crate) mod tests {
|
|||||||
"object": posts[0].ap_url,
|
"object": posts[0].ap_url,
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/comment/1/delete",
|
"id": "https://plu.me/comment/1/delete",
|
||||||
@@ -479,17 +467,16 @@ pub(crate) mod tests {
|
|||||||
"object": posts[0].ap_url,
|
"object": posts[0].ap_url,
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn delete_user() {
|
fn delete_user() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, _) = fill_database(&r);
|
let (_, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let fail_act = json!({
|
let fail_act = json!({
|
||||||
"id": "https://plu.me/@/Admin#delete",
|
"id": "https://plu.me/@/Admin#delete",
|
||||||
@@ -497,7 +484,7 @@ pub(crate) mod tests {
|
|||||||
"object": users[0].ap_url,
|
"object": users[0].ap_url,
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/@/Admin#delete",
|
"id": "https://plu.me/@/Admin#delete",
|
||||||
@@ -505,8 +492,8 @@ pub(crate) mod tests {
|
|||||||
"object": users[0].ap_url,
|
"object": users[0].ap_url,
|
||||||
"type": "Delete",
|
"type": "Delete",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
assert!(crate::users::User::get(conn, users[0].id).is_err());
|
assert!(crate::users::User::get(&conn, users[0].id).is_err());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -514,10 +501,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn follow() {
|
fn follow() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, _) = fill_database(&r);
|
let (_, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/follow/1",
|
"id": "https://plu.me/follow/1",
|
||||||
@@ -525,7 +511,7 @@ pub(crate) mod tests {
|
|||||||
"object": users[1].ap_url,
|
"object": users[1].ap_url,
|
||||||
"type": "Follow",
|
"type": "Follow",
|
||||||
});
|
});
|
||||||
match super::inbox(&r, act).unwrap() {
|
match super::inbox(&conn, act).unwrap() {
|
||||||
InboxResult::Followed(f) => {
|
InboxResult::Followed(f) => {
|
||||||
assert_eq!(f.follower_id, users[0].id);
|
assert_eq!(f.follower_id, users[0].id);
|
||||||
assert_eq!(f.following_id, users[1].id);
|
assert_eq!(f.following_id, users[1].id);
|
||||||
@@ -539,10 +525,9 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn like() {
|
fn like() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/like/1",
|
"id": "https://plu.me/like/1",
|
||||||
@@ -550,7 +535,7 @@ pub(crate) mod tests {
|
|||||||
"object": posts[0].ap_url,
|
"object": posts[0].ap_url,
|
||||||
"type": "Like",
|
"type": "Like",
|
||||||
});
|
});
|
||||||
match super::inbox(&r, act).unwrap() {
|
match super::inbox(&conn, act).unwrap() {
|
||||||
InboxResult::Liked(l) => {
|
InboxResult::Liked(l) => {
|
||||||
assert_eq!(l.user_id, users[1].id);
|
assert_eq!(l.user_id, users[1].id);
|
||||||
assert_eq!(l.post_id, posts[0].id);
|
assert_eq!(l.post_id, posts[0].id);
|
||||||
@@ -566,13 +551,12 @@ pub(crate) mod tests {
|
|||||||
fn undo_reshare() {
|
fn undo_reshare() {
|
||||||
use crate::reshares::*;
|
use crate::reshares::*;
|
||||||
|
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let announce = Reshare::insert(
|
let announce = Reshare::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewReshare {
|
NewReshare {
|
||||||
post_id: posts[0].id,
|
post_id: posts[0].id,
|
||||||
user_id: users[1].id,
|
user_id: users[1].id,
|
||||||
@@ -587,7 +571,7 @@ pub(crate) mod tests {
|
|||||||
"object": announce.ap_url,
|
"object": announce.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/undo/1",
|
"id": "https://plu.me/undo/1",
|
||||||
@@ -595,7 +579,7 @@ pub(crate) mod tests {
|
|||||||
"object": announce.ap_url,
|
"object": announce.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -604,13 +588,12 @@ pub(crate) mod tests {
|
|||||||
fn undo_follow() {
|
fn undo_follow() {
|
||||||
use crate::follows::*;
|
use crate::follows::*;
|
||||||
|
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, _) = fill_database(&r);
|
let (_, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let follow = Follow::insert(
|
let follow = Follow::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewFollow {
|
NewFollow {
|
||||||
follower_id: users[0].id,
|
follower_id: users[0].id,
|
||||||
following_id: users[1].id,
|
following_id: users[1].id,
|
||||||
@@ -625,7 +608,7 @@ pub(crate) mod tests {
|
|||||||
"object": follow.ap_url,
|
"object": follow.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/undo/1",
|
"id": "https://plu.me/undo/1",
|
||||||
@@ -633,7 +616,7 @@ pub(crate) mod tests {
|
|||||||
"object": follow.ap_url,
|
"object": follow.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -642,13 +625,12 @@ pub(crate) mod tests {
|
|||||||
fn undo_like() {
|
fn undo_like() {
|
||||||
use crate::likes::*;
|
use crate::likes::*;
|
||||||
|
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let like = Like::insert(
|
let like = Like::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewLike {
|
NewLike {
|
||||||
post_id: posts[0].id,
|
post_id: posts[0].id,
|
||||||
user_id: users[1].id,
|
user_id: users[1].id,
|
||||||
@@ -663,7 +645,7 @@ pub(crate) mod tests {
|
|||||||
"object": like.ap_url,
|
"object": like.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, fail_act).is_err());
|
assert!(super::inbox(&conn, fail_act).is_err());
|
||||||
|
|
||||||
let ok_act = json!({
|
let ok_act = json!({
|
||||||
"id": "https://plu.me/undo/1",
|
"id": "https://plu.me/undo/1",
|
||||||
@@ -671,17 +653,16 @@ pub(crate) mod tests {
|
|||||||
"object": like.ap_url,
|
"object": like.ap_url,
|
||||||
"type": "Undo",
|
"type": "Undo",
|
||||||
});
|
});
|
||||||
assert!(super::inbox(&r, ok_act).is_ok());
|
assert!(super::inbox(&conn, ok_act).is_ok());
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn update_post() {
|
fn update_post() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (posts, users, _) = fill_database(&r);
|
let (posts, users, _) = fill_database(&conn);
|
||||||
|
|
||||||
let act = json!({
|
let act = json!({
|
||||||
"id": "https://plu.me/update/1",
|
"id": "https://plu.me/update/1",
|
||||||
@@ -700,7 +681,7 @@ pub(crate) mod tests {
|
|||||||
"type": "Update",
|
"type": "Update",
|
||||||
});
|
});
|
||||||
|
|
||||||
super::inbox(&r, act).unwrap();
|
super::inbox(&conn, act).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,6 +247,7 @@ pub(crate) mod tests {
|
|||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
pub(crate) fn fill_database(conn: &Conn) -> Vec<(NewInstance, Instance)> {
|
pub(crate) fn fill_database(conn: &Conn) -> Vec<(NewInstance, Instance)> {
|
||||||
|
diesel::delete(instances::table).execute(conn).unwrap();
|
||||||
let res = vec");
|
assert_eq!(inst.short_description.get(), "[short](#link)");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
inst.short_description_html,
|
inst.short_description_html,
|
||||||
SafeString::new("<p><a href=\"#link\">short</a></p>\n")
|
SafeString::new("<p dir=\"auto\"><a href=\"#link\">short</a></p>\n")
|
||||||
);
|
);
|
||||||
assert_eq!(inst.default_license, "CC-BY-SAO".to_owned());
|
assert_eq!(inst.default_license, "CC-BY-SAO".to_owned());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
Regular → Executable
+19
-13
@@ -11,14 +11,17 @@ extern crate lazy_static;
|
|||||||
extern crate plume_macro;
|
extern crate plume_macro;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
#[macro_use]
|
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tantivy;
|
extern crate tantivy;
|
||||||
|
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use plume_common::activity_pub::inbox::InboxError;
|
use plume_common::activity_pub::inbox::InboxError;
|
||||||
|
use posts::PostEvent;
|
||||||
|
use riker::actors::{channel, ActorSystem, ChannelRef, SystemBuilder};
|
||||||
|
use users::UserEvent;
|
||||||
|
|
||||||
#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
|
#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
|
||||||
compile_error!("Either feature \"sqlite\" or \"postgres\" must be enabled for this crate.");
|
compile_error!("Either feature \"sqlite\" or \"postgres\" must be enabled for this crate.");
|
||||||
@@ -31,6 +34,19 @@ pub type Connection = diesel::SqliteConnection;
|
|||||||
#[cfg(all(not(feature = "sqlite"), feature = "postgres"))]
|
#[cfg(all(not(feature = "sqlite"), feature = "postgres"))]
|
||||||
pub type Connection = diesel::PgConnection;
|
pub type Connection = diesel::PgConnection;
|
||||||
|
|
||||||
|
pub(crate) static ACTOR_SYS: Lazy<ActorSystem> = Lazy::new(|| {
|
||||||
|
SystemBuilder::new()
|
||||||
|
.name("plume")
|
||||||
|
.create()
|
||||||
|
.expect("Failed to create actor system")
|
||||||
|
});
|
||||||
|
|
||||||
|
pub(crate) static USER_CHAN: Lazy<ChannelRef<UserEvent>> =
|
||||||
|
Lazy::new(|| channel("user_events", &*ACTOR_SYS).expect("Failed to create user channel"));
|
||||||
|
|
||||||
|
pub(crate) static POST_CHAN: Lazy<ChannelRef<PostEvent>> =
|
||||||
|
Lazy::new(|| channel("post_events", &*ACTOR_SYS).expect("Failed to create post channel"));
|
||||||
|
|
||||||
/// All the possible errors that can be encoutered in this crate
|
/// All the possible errors that can be encoutered in this crate
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
@@ -282,12 +298,10 @@ pub fn ap_url(url: &str) -> String {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::{db_conn, migrations::IMPORTED_MIGRATIONS, search, Connection as Conn, CONFIG};
|
use crate::{db_conn, migrations::IMPORTED_MIGRATIONS, Connection as Conn, CONFIG};
|
||||||
use diesel::r2d2::ConnectionManager;
|
use diesel::r2d2::ConnectionManager;
|
||||||
use plume_common::utils::random_hex;
|
use plume_common::utils::random_hex;
|
||||||
use scheduled_thread_pool::ScheduledThreadPool;
|
|
||||||
use std::env::temp_dir;
|
use std::env::temp_dir;
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! part_eq {
|
macro_rules! part_eq {
|
||||||
@@ -317,15 +331,6 @@ mod tests {
|
|||||||
pool
|
pool
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn rockets() -> super::PlumeRocket {
|
|
||||||
super::PlumeRocket {
|
|
||||||
conn: db_conn::DbConn((*DB_POOL).get().unwrap()),
|
|
||||||
searcher: Arc::new(search::tests::get_searcher(&CONFIG.search_tokenizers)),
|
|
||||||
worker: Arc::new(ScheduledThreadPool::new(2)),
|
|
||||||
user: None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
@@ -351,6 +356,7 @@ pub mod password_reset_requests;
|
|||||||
pub mod plume_rocket;
|
pub mod plume_rocket;
|
||||||
pub mod post_authors;
|
pub mod post_authors;
|
||||||
pub mod posts;
|
pub mod posts;
|
||||||
|
pub mod remote_fetch_actor;
|
||||||
pub mod reshares;
|
pub mod reshares;
|
||||||
pub mod safe_string;
|
pub mod safe_string;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
|||||||
+34
-25
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
notifications::*, posts::Post, schema::likes, timeline::*, users::User, Connection, Error,
|
db_conn::DbConn, notifications::*, posts::Post, schema::likes, timeline::*, users::User,
|
||||||
PlumeRocket, Result,
|
Connection, Error, Result, CONFIG,
|
||||||
};
|
};
|
||||||
use activitypub::activity;
|
use activitypub::activity;
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
@@ -83,64 +83,73 @@ impl Like {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, activity::Like, &PlumeRocket> for Post {
|
impl AsObject<User, activity::Like, &DbConn> for Post {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = Like;
|
type Output = Like;
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, id: &str) -> Result<Like> {
|
fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result<Like> {
|
||||||
let res = Like::insert(
|
let res = Like::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewLike {
|
NewLike {
|
||||||
post_id: self.id,
|
post_id: self.id,
|
||||||
user_id: actor.id,
|
user_id: actor.id,
|
||||||
ap_url: id.to_string(),
|
ap_url: id.to_string(),
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
res.notify(&c.conn)?;
|
res.notify(conn)?;
|
||||||
|
|
||||||
Timeline::add_to_all_timelines(c, &self, Kind::Like(&actor))?;
|
Timeline::add_to_all_timelines(conn, &self, Kind::Like(&actor))?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Like {
|
impl FromId<DbConn> for Like {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = activity::Like;
|
type Object = activity::Like;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Like::find_by_ap_url(&c.conn, id)
|
Like::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, act: activity::Like) -> Result<Self> {
|
fn from_activity(conn: &DbConn, act: activity::Like) -> Result<Self> {
|
||||||
let res = Like::insert(
|
let res = Like::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewLike {
|
NewLike {
|
||||||
post_id: Post::from_id(c, &act.like_props.object_link::<Id>()?, None)
|
post_id: Post::from_id(
|
||||||
.map_err(|(_, e)| e)?
|
conn,
|
||||||
.id,
|
&act.like_props.object_link::<Id>()?,
|
||||||
user_id: User::from_id(c, &act.like_props.actor_link::<Id>()?, None)
|
None,
|
||||||
.map_err(|(_, e)| e)?
|
CONFIG.proxy(),
|
||||||
.id,
|
)
|
||||||
|
.map_err(|(_, e)| e)?
|
||||||
|
.id,
|
||||||
|
user_id: User::from_id(
|
||||||
|
conn,
|
||||||
|
&act.like_props.actor_link::<Id>()?,
|
||||||
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
|
)
|
||||||
|
.map_err(|(_, e)| e)?
|
||||||
|
.id,
|
||||||
ap_url: act.object_props.id_string()?,
|
ap_url: act.object_props.id_string()?,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
res.notify(&c.conn)?;
|
res.notify(conn)?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, activity::Undo, &PlumeRocket> for Like {
|
impl AsObject<User, activity::Undo, &DbConn> for Like {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
let conn = &*c.conn;
|
|
||||||
if actor.id == self.user_id {
|
if actor.id == self.user_id {
|
||||||
diesel::delete(&self).execute(conn)?;
|
diesel::delete(&self).execute(&**conn)?;
|
||||||
|
|
||||||
// delete associated notification if any
|
// delete associated notification if any
|
||||||
if let Ok(notif) = Notification::find(conn, notification_kind::LIKE, self.id) {
|
if let Ok(notif) = Notification::find(&conn, notification_kind::LIKE, self.id) {
|
||||||
diesel::delete(¬if).execute(conn)?;
|
diesel::delete(¬if).execute(&**conn)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -30,9 +30,9 @@ impl TryFrom<i32> for ListType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<i32> for ListType {
|
impl From<ListType> for i32 {
|
||||||
fn into(self) -> i32 {
|
fn from(list_type: ListType) -> Self {
|
||||||
match self {
|
match list_type {
|
||||||
ListType::User => 0,
|
ListType::User => 0,
|
||||||
ListType::Blog => 1,
|
ListType::Blog => 1,
|
||||||
ListType::Word => 2,
|
ListType::Word => 2,
|
||||||
@@ -246,22 +246,22 @@ impl List {
|
|||||||
private::ListElem::prefix_in_list(conn, self, word)
|
private::ListElem::prefix_in_list(conn, self, word)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert new users in a list
|
// Insert new users in a list
|
||||||
func! {add: add_users, User}
|
func! {add: add_users, User}
|
||||||
|
|
||||||
/// Insert new blogs in a list
|
// Insert new blogs in a list
|
||||||
func! {add: add_blogs, Blog}
|
func! {add: add_blogs, Blog}
|
||||||
|
|
||||||
/// Insert new words in a list
|
// Insert new words in a list
|
||||||
func! {add: add_words, Word}
|
func! {add: add_words, Word}
|
||||||
|
|
||||||
/// Insert new prefixes in a list
|
// Insert new prefixes in a list
|
||||||
func! {add: add_prefixes, Prefix}
|
func! {add: add_prefixes, Prefix}
|
||||||
|
|
||||||
/// Get all users in the list
|
// Get all users in the list
|
||||||
func! {list: list_users, User, users}
|
func! {list: list_users, User, users}
|
||||||
|
|
||||||
/// Get all blogs in the list
|
// Get all blogs in the list
|
||||||
func! {list: list_blogs, Blog, blogs}
|
func! {list: list_blogs, Blog, blogs}
|
||||||
|
|
||||||
/// Get all words in the list
|
/// Get all words in the list
|
||||||
|
|||||||
+57
-21
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ap_url, instance::Instance, safe_string::SafeString, schema::medias, users::User, Connection,
|
ap_url, db_conn::DbConn, instance::Instance, safe_string::SafeString, schema::medias,
|
||||||
Error, PlumeRocket, Result,
|
users::User, Connection, Error, Result, CONFIG,
|
||||||
};
|
};
|
||||||
use activitypub::object::Image;
|
use activitypub::object::Image;
|
||||||
use askama_escape::escape;
|
use askama_escape::escape;
|
||||||
@@ -10,8 +10,14 @@ use plume_common::{
|
|||||||
activity_pub::{inbox::FromId, Id},
|
activity_pub::{inbox::FromId, Id},
|
||||||
utils::MediaProcessor,
|
utils::MediaProcessor,
|
||||||
};
|
};
|
||||||
use reqwest;
|
use std::{
|
||||||
use std::{fs, path::Path};
|
fs::{self, DirBuilder},
|
||||||
|
path::{Path, PathBuf},
|
||||||
|
};
|
||||||
|
use tracing::warn;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
|
const REMOTE_MEDIA_DIRECTORY: &str = "remote";
|
||||||
|
|
||||||
#[derive(Clone, Identifiable, Queryable)]
|
#[derive(Clone, Identifiable, Queryable)]
|
||||||
pub struct Media {
|
pub struct Media {
|
||||||
@@ -197,26 +203,28 @@ impl Media {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: merge with save_remote?
|
// TODO: merge with save_remote?
|
||||||
pub fn from_activity(c: &PlumeRocket, image: &Image) -> Result<Media> {
|
pub fn from_activity(conn: &DbConn, image: &Image) -> Result<Media> {
|
||||||
let conn = &*c.conn;
|
|
||||||
let remote_url = image.object_props.url_string().ok()?;
|
let remote_url = image.object_props.url_string().ok()?;
|
||||||
let ext = remote_url
|
let path = determine_mirror_file_path(&remote_url);
|
||||||
.rsplit('.')
|
let parent = path.parent()?;
|
||||||
.next()
|
if !parent.is_dir() {
|
||||||
.map(ToOwned::to_owned)
|
DirBuilder::new().recursive(true).create(parent)?;
|
||||||
.unwrap_or_else(|| String::from("png"));
|
}
|
||||||
let path = Path::new(&super::CONFIG.media_directory).join(format!(
|
|
||||||
"{}.{}",
|
|
||||||
GUID::rand().to_string(),
|
|
||||||
ext
|
|
||||||
));
|
|
||||||
|
|
||||||
let mut dest = fs::File::create(path.clone()).ok()?;
|
let mut dest = fs::File::create(path.clone()).ok()?;
|
||||||
reqwest::get(remote_url.as_str())
|
// TODO: conditional GET
|
||||||
.ok()?
|
if let Some(proxy) = CONFIG.proxy() {
|
||||||
.copy_to(&mut dest)
|
reqwest::ClientBuilder::new().proxy(proxy.clone()).build()?
|
||||||
.ok()?;
|
} else {
|
||||||
|
reqwest::Client::new()
|
||||||
|
}
|
||||||
|
.get(remote_url.as_str())
|
||||||
|
.send()
|
||||||
|
.ok()?
|
||||||
|
.copy_to(&mut dest)
|
||||||
|
.ok()?;
|
||||||
|
|
||||||
|
// TODO: upsert
|
||||||
Media::insert(
|
Media::insert(
|
||||||
conn,
|
conn,
|
||||||
NewMedia {
|
NewMedia {
|
||||||
@@ -227,7 +235,7 @@ impl Media {
|
|||||||
sensitive: image.object_props.summary_string().is_ok(),
|
sensitive: image.object_props.summary_string().is_ok(),
|
||||||
content_warning: image.object_props.summary_string().ok(),
|
content_warning: image.object_props.summary_string().ok(),
|
||||||
owner_id: User::from_id(
|
owner_id: User::from_id(
|
||||||
c,
|
conn,
|
||||||
image
|
image
|
||||||
.object_props
|
.object_props
|
||||||
.attributed_to_link_vec::<Id>()
|
.attributed_to_link_vec::<Id>()
|
||||||
@@ -236,6 +244,7 @@ impl Media {
|
|||||||
.next()?
|
.next()?
|
||||||
.as_ref(),
|
.as_ref(),
|
||||||
None,
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
)
|
)
|
||||||
.map_err(|(_, e)| e)?
|
.map_err(|(_, e)| e)?
|
||||||
.id,
|
.id,
|
||||||
@@ -257,6 +266,33 @@ impl Media {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn determine_mirror_file_path(url: &str) -> PathBuf {
|
||||||
|
let mut file_path = Path::new(&super::CONFIG.media_directory).join(REMOTE_MEDIA_DIRECTORY);
|
||||||
|
Url::parse(url)
|
||||||
|
.map(|url| {
|
||||||
|
if !url.has_host() {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
file_path.push(url.host_str().unwrap());
|
||||||
|
for segment in url.path_segments().expect("FIXME") {
|
||||||
|
file_path.push(segment);
|
||||||
|
}
|
||||||
|
// TODO: handle query
|
||||||
|
// HINT: Use characters which must be percent-encoded in path as separator between path and query
|
||||||
|
// HINT: handle extension
|
||||||
|
})
|
||||||
|
.unwrap_or_else(|err| {
|
||||||
|
warn!("Failed to parse url: {} {}", &url, err);
|
||||||
|
let ext = url
|
||||||
|
.rsplit('.')
|
||||||
|
.next()
|
||||||
|
.map(ToOwned::to_owned)
|
||||||
|
.unwrap_or_else(|| String::from("png"));
|
||||||
|
file_path.push(format!("{}.{}", GUID::rand().to_string(), ext));
|
||||||
|
});
|
||||||
|
file_path
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
comments::Comment, notifications::*, posts::Post, schema::mentions, users::User, Connection,
|
comments::Comment, db_conn::DbConn, notifications::*, posts::Post, schema::mentions,
|
||||||
Error, PlumeRocket, Result,
|
users::User, Connection, Error, Result,
|
||||||
};
|
};
|
||||||
use activitypub::link;
|
use activitypub::link;
|
||||||
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl};
|
use diesel::{self, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
@@ -52,8 +52,8 @@ impl Mention {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_activity(c: &PlumeRocket, ment: &str) -> Result<link::Mention> {
|
pub fn build_activity(conn: &DbConn, ment: &str) -> Result<link::Mention> {
|
||||||
let user = User::find_by_fqn(c, ment)?;
|
let user = User::find_by_fqn(conn, ment)?;
|
||||||
let mut mention = link::Mention::default();
|
let mut mention = link::Mention::default();
|
||||||
mention.link_props.set_href_string(user.ap_url)?;
|
mention.link_props.set_href_string(user.ap_url)?;
|
||||||
mention.link_props.set_name_string(format!("@{}", ment))?;
|
mention.link_props.set_name_string(format!("@{}", ment))?;
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ use crate::{Connection, Error, Result};
|
|||||||
use diesel::connection::{Connection as Conn, SimpleConnection};
|
use diesel::connection::{Connection as Conn, SimpleConnection};
|
||||||
use migrations_internals::{setup_database, MigrationConnection};
|
use migrations_internals::{setup_database, MigrationConnection};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
#[allow(dead_code)] //variants might not be constructed if not required by current migrations
|
#[allow(dead_code)] //variants might not be constructed if not required by current migrations
|
||||||
enum Action {
|
enum Action {
|
||||||
@@ -26,7 +27,7 @@ struct ComplexMigration {
|
|||||||
|
|
||||||
impl ComplexMigration {
|
impl ComplexMigration {
|
||||||
fn run(&self, conn: &Connection, path: &Path) -> Result<()> {
|
fn run(&self, conn: &Connection, path: &Path) -> Result<()> {
|
||||||
println!("Running migration {}", self.name);
|
info!("Running migration {}", self.name);
|
||||||
for step in self.up {
|
for step in self.up {
|
||||||
step.run(conn, path)?
|
step.run(conn, path)?
|
||||||
}
|
}
|
||||||
@@ -34,7 +35,7 @@ impl ComplexMigration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn revert(&self, conn: &Connection, path: &Path) -> Result<()> {
|
fn revert(&self, conn: &Connection, path: &Path) -> Result<()> {
|
||||||
println!("Reverting migration {}", self.name);
|
info!("Reverting migration {}", self.name);
|
||||||
for step in self.down {
|
for step in self.down {
|
||||||
step.run(conn, path)?
|
step.run(conn, path)?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ pub use self::module::PlumeRocket;
|
|||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
mod module {
|
mod module {
|
||||||
use crate::{db_conn::DbConn, search, users};
|
use crate::{search, users};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
request::{self, FlashMessage, FromRequest, Request},
|
request::{self, FlashMessage, FromRequest, Request},
|
||||||
Outcome, State,
|
Outcome, State,
|
||||||
@@ -12,7 +12,6 @@ mod module {
|
|||||||
|
|
||||||
/// Common context needed by most routes and operations on models
|
/// Common context needed by most routes and operations on models
|
||||||
pub struct PlumeRocket {
|
pub struct PlumeRocket {
|
||||||
pub conn: DbConn,
|
|
||||||
pub intl: rocket_i18n::I18n,
|
pub intl: rocket_i18n::I18n,
|
||||||
pub user: Option<users::User>,
|
pub user: Option<users::User>,
|
||||||
pub searcher: Arc<search::Searcher>,
|
pub searcher: Arc<search::Searcher>,
|
||||||
@@ -24,14 +23,12 @@ mod module {
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<PlumeRocket, ()> {
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<PlumeRocket, ()> {
|
||||||
let conn = request.guard::<DbConn>()?;
|
|
||||||
let intl = request.guard::<rocket_i18n::I18n>()?;
|
let intl = request.guard::<rocket_i18n::I18n>()?;
|
||||||
let user = request.guard::<users::User>().succeeded();
|
let user = request.guard::<users::User>().succeeded();
|
||||||
let worker = request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()?;
|
let worker = request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()?;
|
||||||
let searcher = request.guard::<'_, State<'_, Arc<search::Searcher>>>()?;
|
let searcher = request.guard::<'_, State<'_, Arc<search::Searcher>>>()?;
|
||||||
let flash_msg = request.guard::<FlashMessage<'_, '_>>().succeeded();
|
let flash_msg = request.guard::<FlashMessage<'_, '_>>().succeeded();
|
||||||
Outcome::Success(PlumeRocket {
|
Outcome::Success(PlumeRocket {
|
||||||
conn,
|
|
||||||
intl,
|
intl,
|
||||||
user,
|
user,
|
||||||
flash_msg: flash_msg.map(|f| (f.name().into(), f.msg().into())),
|
flash_msg: flash_msg.map(|f| (f.name().into(), f.msg().into())),
|
||||||
@@ -44,7 +41,7 @@ mod module {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod module {
|
mod module {
|
||||||
use crate::{db_conn::DbConn, search, users};
|
use crate::{search, users};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
request::{self, FromRequest, Request},
|
request::{self, FromRequest, Request},
|
||||||
Outcome, State,
|
Outcome, State,
|
||||||
@@ -54,7 +51,6 @@ mod module {
|
|||||||
|
|
||||||
/// Common context needed by most routes and operations on models
|
/// Common context needed by most routes and operations on models
|
||||||
pub struct PlumeRocket {
|
pub struct PlumeRocket {
|
||||||
pub conn: DbConn,
|
|
||||||
pub user: Option<users::User>,
|
pub user: Option<users::User>,
|
||||||
pub searcher: Arc<search::Searcher>,
|
pub searcher: Arc<search::Searcher>,
|
||||||
pub worker: Arc<ScheduledThreadPool>,
|
pub worker: Arc<ScheduledThreadPool>,
|
||||||
@@ -64,12 +60,10 @@ mod module {
|
|||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
fn from_request(request: &'a Request<'r>) -> request::Outcome<PlumeRocket, ()> {
|
fn from_request(request: &'a Request<'r>) -> request::Outcome<PlumeRocket, ()> {
|
||||||
let conn = request.guard::<DbConn>()?;
|
|
||||||
let user = request.guard::<users::User>().succeeded();
|
let user = request.guard::<users::User>().succeeded();
|
||||||
let worker = request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()?;
|
let worker = request.guard::<'_, State<'_, Arc<ScheduledThreadPool>>>()?;
|
||||||
let searcher = request.guard::<'_, State<'_, Arc<search::Searcher>>>()?;
|
let searcher = request.guard::<'_, State<'_, Arc<search::Searcher>>>()?;
|
||||||
Outcome::Success(PlumeRocket {
|
Outcome::Success(PlumeRocket {
|
||||||
conn,
|
|
||||||
user,
|
user,
|
||||||
worker: worker.clone(),
|
worker: worker.clone(),
|
||||||
searcher: searcher.clone(),
|
searcher: searcher.clone(),
|
||||||
|
|||||||
+134
-60
@@ -1,7 +1,7 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ap_url, blogs::Blog, instance::Instance, medias::Media, mentions::Mention, post_authors::*,
|
ap_url, blogs::Blog, db_conn::DbConn, instance::Instance, medias::Media, mentions::Mention,
|
||||||
safe_string::SafeString, schema::posts, search::Searcher, tags::*, timeline::*, users::User,
|
post_authors::*, safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User,
|
||||||
Connection, Error, PlumeRocket, Result, CONFIG,
|
Connection, Error, PostEvent::*, Result, CONFIG, POST_CHAN,
|
||||||
};
|
};
|
||||||
use activitypub::{
|
use activitypub::{
|
||||||
activity::{Create, Delete, Update},
|
activity::{Create, Delete, Update},
|
||||||
@@ -12,6 +12,7 @@ use activitypub::{
|
|||||||
use chrono::{NaiveDateTime, TimeZone, Utc};
|
use chrono::{NaiveDateTime, TimeZone, Utc};
|
||||||
use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
use diesel::{self, BelongingToDsl, ExpressionMethods, QueryDsl, RunQueryDsl, SaveChangesDsl};
|
||||||
use heck::KebabCase;
|
use heck::KebabCase;
|
||||||
|
use once_cell::sync::Lazy;
|
||||||
use plume_common::{
|
use plume_common::{
|
||||||
activity_pub::{
|
activity_pub::{
|
||||||
inbox::{AsObject, FromId},
|
inbox::{AsObject, FromId},
|
||||||
@@ -19,12 +20,15 @@ use plume_common::{
|
|||||||
},
|
},
|
||||||
utils::md_to_html,
|
utils::md_to_html,
|
||||||
};
|
};
|
||||||
use serde_json;
|
use riker::actors::{Publish, Tell};
|
||||||
use std::collections::HashSet;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
||||||
|
|
||||||
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
static BLOG_FQN_CACHE: Lazy<Mutex<HashMap<i32, String>>> = Lazy::new(|| Mutex::new(HashMap::new()));
|
||||||
|
|
||||||
|
#[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)]
|
||||||
#[changeset_options(treat_none_as_null = "true")]
|
#[changeset_options(treat_none_as_null = "true")]
|
||||||
pub struct Post {
|
pub struct Post {
|
||||||
pub id: i32,
|
pub id: i32,
|
||||||
@@ -63,7 +67,7 @@ impl Post {
|
|||||||
find_by!(posts, find_by_ap_url, ap_url as &str);
|
find_by!(posts, find_by_ap_url, ap_url as &str);
|
||||||
|
|
||||||
last!(posts);
|
last!(posts);
|
||||||
pub fn insert(conn: &Connection, new: NewPost, searcher: &Searcher) -> Result<Self> {
|
pub fn insert(conn: &Connection, new: NewPost) -> Result<Self> {
|
||||||
diesel::insert_into(posts::table)
|
diesel::insert_into(posts::table)
|
||||||
.values(new)
|
.values(new)
|
||||||
.execute(conn)?;
|
.execute(conn)?;
|
||||||
@@ -78,23 +82,29 @@ impl Post {
|
|||||||
let _: Post = post.save_changes(conn)?;
|
let _: Post = post.save_changes(conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
searcher.add_document(conn, &post)?;
|
if post.published {
|
||||||
|
post.publish_published();
|
||||||
|
}
|
||||||
|
|
||||||
Ok(post)
|
Ok(post)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&self, conn: &Connection, searcher: &Searcher) -> Result<Self> {
|
pub fn update(&self, conn: &Connection) -> Result<Self> {
|
||||||
diesel::update(self).set(self).execute(conn)?;
|
diesel::update(self).set(self).execute(conn)?;
|
||||||
let post = Self::get(conn, self.id)?;
|
let post = Self::get(conn, self.id)?;
|
||||||
searcher.update_document(conn, &post)?;
|
// TODO: Call publish_published() when newly published
|
||||||
|
if post.published {
|
||||||
|
self.publish_updated();
|
||||||
|
}
|
||||||
Ok(post)
|
Ok(post)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
pub fn delete(&self, conn: &Connection) -> Result<()> {
|
||||||
for m in Mention::list_for_post(&conn, self.id)? {
|
for m in Mention::list_for_post(&conn, self.id)? {
|
||||||
m.delete(conn)?;
|
m.delete(conn)?;
|
||||||
}
|
}
|
||||||
diesel::delete(self).execute(conn)?;
|
diesel::delete(self).execute(conn)?;
|
||||||
searcher.delete_document(self);
|
self.publish_deleted();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,8 +134,7 @@ impl Post {
|
|||||||
.filter(posts::published.eq(true))
|
.filter(posts::published.eq(true))
|
||||||
.count()
|
.count()
|
||||||
.load(conn)?
|
.load(conn)?
|
||||||
.iter()
|
.get(0)
|
||||||
.next()
|
|
||||||
.cloned()
|
.cloned()
|
||||||
.ok_or(Error::NotFound)
|
.ok_or(Error::NotFound)
|
||||||
}
|
}
|
||||||
@@ -269,6 +278,24 @@ impl Post {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// This method exists for use in templates to reduce database access.
|
||||||
|
/// This should not be used for other purpose.
|
||||||
|
///
|
||||||
|
/// This caches query result. The best way to cache query result is holding it in `Post`s field
|
||||||
|
/// but Diesel doesn't allow it currently.
|
||||||
|
/// If sometime Diesel allow it, this method should be removed.
|
||||||
|
pub fn get_blog_fqn(&self, conn: &Connection) -> String {
|
||||||
|
if let Some(blog_fqn) = BLOG_FQN_CACHE.lock().unwrap().get(&self.blog_id) {
|
||||||
|
return blog_fqn.to_string();
|
||||||
|
}
|
||||||
|
let blog_fqn = self.get_blog(conn).unwrap().fqn;
|
||||||
|
BLOG_FQN_CACHE
|
||||||
|
.lock()
|
||||||
|
.unwrap()
|
||||||
|
.insert(self.blog_id, blog_fqn.clone());
|
||||||
|
blog_fqn
|
||||||
|
}
|
||||||
|
|
||||||
pub fn count_likes(&self, conn: &Connection) -> Result<i64> {
|
pub fn count_likes(&self, conn: &Connection) -> Result<i64> {
|
||||||
use crate::schema::likes;
|
use crate::schema::likes;
|
||||||
likes::table
|
likes::table
|
||||||
@@ -288,17 +315,16 @@ impl Post {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_receivers_urls(&self, conn: &Connection) -> Result<Vec<String>> {
|
pub fn get_receivers_urls(&self, conn: &Connection) -> Result<Vec<String>> {
|
||||||
let followers = self
|
Ok(self
|
||||||
.get_authors(conn)?
|
.get_authors(conn)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter_map(|a| a.get_followers(conn).ok())
|
.filter_map(|a| a.get_followers(conn).ok())
|
||||||
.collect::<Vec<Vec<User>>>();
|
.fold(vec![], |mut acc, f| {
|
||||||
Ok(followers.into_iter().fold(vec![], |mut acc, f| {
|
for x in f {
|
||||||
for x in f {
|
acc.push(x.ap_url);
|
||||||
acc.push(x.ap_url);
|
}
|
||||||
}
|
acc
|
||||||
acc
|
}))
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_activity(&self, conn: &Connection) -> Result<LicensedArticle> {
|
pub fn to_activity(&self, conn: &Connection) -> Result<LicensedArticle> {
|
||||||
@@ -548,19 +574,48 @@ impl Post {
|
|||||||
.set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?;
|
.set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?;
|
||||||
Ok(act)
|
Ok(act)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn publish_published(&self) {
|
||||||
|
POST_CHAN.tell(
|
||||||
|
Publish {
|
||||||
|
msg: PostPublished(Arc::new(self.clone())),
|
||||||
|
topic: "post.published".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn publish_updated(&self) {
|
||||||
|
POST_CHAN.tell(
|
||||||
|
Publish {
|
||||||
|
msg: PostUpdated(Arc::new(self.clone())),
|
||||||
|
topic: "post.updated".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn publish_deleted(&self) {
|
||||||
|
POST_CHAN.tell(
|
||||||
|
Publish {
|
||||||
|
msg: PostDeleted(Arc::new(self.clone())),
|
||||||
|
topic: "post.deleted".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Post {
|
impl FromId<DbConn> for Post {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = LicensedArticle;
|
type Object = LicensedArticle;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Self::find_by_ap_url(&c.conn, id)
|
Self::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, article: LicensedArticle) -> Result<Self> {
|
fn from_activity(conn: &DbConn, article: LicensedArticle) -> Result<Self> {
|
||||||
let conn = &*c.conn;
|
let conn = conn;
|
||||||
let searcher = &c.searcher;
|
|
||||||
let license = article.custom_props.license_string().unwrap_or_default();
|
let license = article.custom_props.license_string().unwrap_or_default();
|
||||||
let article = article.object;
|
let article = article.object;
|
||||||
|
|
||||||
@@ -570,12 +625,15 @@ impl FromId<PlumeRocket> for Post {
|
|||||||
.into_iter()
|
.into_iter()
|
||||||
.fold((None, vec![]), |(blog, mut authors), link| {
|
.fold((None, vec![]), |(blog, mut authors), link| {
|
||||||
let url = link;
|
let url = link;
|
||||||
match User::from_id(&c, &url, None) {
|
match User::from_id(conn, &url, None, CONFIG.proxy()) {
|
||||||
Ok(u) => {
|
Ok(u) => {
|
||||||
authors.push(u);
|
authors.push(u);
|
||||||
(blog, authors)
|
(blog, authors)
|
||||||
}
|
}
|
||||||
Err(_) => (blog.or_else(|| Blog::from_id(&c, &url, None).ok()), authors),
|
Err(_) => (
|
||||||
|
blog.or_else(|| Blog::from_id(conn, &url, None, CONFIG.proxy()).ok()),
|
||||||
|
authors,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -583,9 +641,10 @@ impl FromId<PlumeRocket> for Post {
|
|||||||
.object_props
|
.object_props
|
||||||
.icon_object::<Image>()
|
.icon_object::<Image>()
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|img| Media::from_activity(&c, &img).ok().map(|m| m.id));
|
.and_then(|img| Media::from_activity(conn, &img).ok().map(|m| m.id));
|
||||||
|
|
||||||
let title = article.object_props.name_string()?;
|
let title = article.object_props.name_string()?;
|
||||||
|
// TODO: upsert
|
||||||
let post = Post::insert(
|
let post = Post::insert(
|
||||||
conn,
|
conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
@@ -605,7 +664,6 @@ impl FromId<PlumeRocket> for Post {
|
|||||||
source: article.ap_object_props.source_object::<Source>()?.content,
|
source: article.ap_object_props.source_object::<Source>()?.content,
|
||||||
cover_id: cover,
|
cover_id: cover,
|
||||||
},
|
},
|
||||||
searcher,
|
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
for author in authors {
|
for author in authors {
|
||||||
@@ -644,33 +702,33 @@ impl FromId<PlumeRocket> for Post {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Timeline::add_to_all_timelines(c, &post, Kind::Original)?;
|
Timeline::add_to_all_timelines(conn, &post, Kind::Original)?;
|
||||||
|
|
||||||
Ok(post)
|
Ok(post)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Create, &PlumeRocket> for Post {
|
impl AsObject<User, Create, &DbConn> for Post {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = Post;
|
type Output = Post;
|
||||||
|
|
||||||
fn activity(self, _c: &PlumeRocket, _actor: User, _id: &str) -> Result<Post> {
|
fn activity(self, _conn: &DbConn, _actor: User, _id: &str) -> Result<Post> {
|
||||||
// TODO: check that _actor is actually one of the author?
|
// TODO: check that _actor is actually one of the author?
|
||||||
Ok(self)
|
Ok(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Delete, &PlumeRocket> for Post {
|
impl AsObject<User, Delete, &DbConn> for Post {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
let can_delete = self
|
let can_delete = self
|
||||||
.get_authors(&c.conn)?
|
.get_authors(conn)?
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.any(|a| actor.id == a.id);
|
.any(|a| actor.id == a.id);
|
||||||
if can_delete {
|
if can_delete {
|
||||||
self.delete(&c.conn, &c.searcher).map(|_| ())
|
self.delete(conn).map(|_| ())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Unauthorized)
|
Err(Error::Unauthorized)
|
||||||
}
|
}
|
||||||
@@ -688,16 +746,16 @@ pub struct PostUpdate {
|
|||||||
pub tags: Option<serde_json::Value>,
|
pub tags: Option<serde_json::Value>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for PostUpdate {
|
impl FromId<DbConn> for PostUpdate {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = LicensedArticle;
|
type Object = LicensedArticle;
|
||||||
|
|
||||||
fn from_db(_: &PlumeRocket, _: &str) -> Result<Self> {
|
fn from_db(_: &DbConn, _: &str) -> Result<Self> {
|
||||||
// Always fail because we always want to deserialize the AP object
|
// Always fail because we always want to deserialize the AP object
|
||||||
Err(Error::NotFound)
|
Err(Error::NotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, updated: LicensedArticle) -> Result<Self> {
|
fn from_activity(conn: &DbConn, updated: LicensedArticle) -> Result<Self> {
|
||||||
Ok(PostUpdate {
|
Ok(PostUpdate {
|
||||||
ap_url: updated.object.object_props.id_string()?,
|
ap_url: updated.object.object_props.id_string()?,
|
||||||
title: updated.object.object_props.name_string().ok(),
|
title: updated.object.object_props.name_string().ok(),
|
||||||
@@ -708,7 +766,7 @@ impl FromId<PlumeRocket> for PostUpdate {
|
|||||||
.object_props
|
.object_props
|
||||||
.icon_object::<Image>()
|
.icon_object::<Image>()
|
||||||
.ok()
|
.ok()
|
||||||
.and_then(|img| Media::from_activity(&c, &img).ok().map(|m| m.id)),
|
.and_then(|img| Media::from_activity(conn, &img).ok().map(|m| m.id)),
|
||||||
source: updated
|
source: updated
|
||||||
.object
|
.object
|
||||||
.ap_object_props
|
.ap_object_props
|
||||||
@@ -721,14 +779,13 @@ impl FromId<PlumeRocket> for PostUpdate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Update, &PlumeRocket> for PostUpdate {
|
impl AsObject<User, Update, &DbConn> for PostUpdate {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
let conn = &*c.conn;
|
let mut post =
|
||||||
let searcher = &c.searcher;
|
Post::from_id(conn, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?;
|
||||||
let mut post = Post::from_id(c, &self.ap_url, None).map_err(|(_, e)| e)?;
|
|
||||||
|
|
||||||
if !post.is_author(conn, actor.id)? {
|
if !post.is_author(conn, actor.id)? {
|
||||||
// TODO: maybe the author was added in the meantime
|
// TODO: maybe the author was added in the meantime
|
||||||
@@ -789,7 +846,7 @@ impl AsObject<User, Update, &PlumeRocket> for PostUpdate {
|
|||||||
post.update_hashtags(conn, hashtags)?;
|
post.update_hashtags(conn, hashtags)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
post.update(conn, searcher)?;
|
post.update(conn)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -800,24 +857,42 @@ impl IntoId for Post {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum PostEvent {
|
||||||
|
PostPublished(Arc<Post>),
|
||||||
|
PostUpdated(Arc<Post>),
|
||||||
|
PostDeleted(Arc<Post>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<PostEvent> for Arc<Post> {
|
||||||
|
fn from(event: PostEvent) -> Self {
|
||||||
|
use PostEvent::*;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
PostPublished(post) => post,
|
||||||
|
PostUpdated(post) => post,
|
||||||
|
PostDeleted(post) => post,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::inbox::{inbox, tests::fill_database, InboxResult};
|
use crate::inbox::{inbox, tests::fill_database, InboxResult};
|
||||||
use crate::safe_string::SafeString;
|
use crate::safe_string::SafeString;
|
||||||
use crate::tests::rockets;
|
use crate::tests::db;
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
|
|
||||||
// creates a post, get it's Create activity, delete the post,
|
// creates a post, get it's Create activity, delete the post,
|
||||||
// "send" the Create to the inbox, and check it works
|
// "send" the Create to the inbox, and check it works
|
||||||
#[test]
|
#[test]
|
||||||
fn self_federation() {
|
fn self_federation() {
|
||||||
let r = rockets();
|
let conn = &db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (_, users, blogs) = fill_database(&r);
|
let (_, users, blogs) = fill_database(&conn);
|
||||||
let post = Post::insert(
|
let post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "yo".into(),
|
slug: "yo".into(),
|
||||||
@@ -831,23 +906,22 @@ mod tests {
|
|||||||
source: "Hello".into(),
|
source: "Hello".into(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
PostAuthor::insert(
|
PostAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPostAuthor {
|
NewPostAuthor {
|
||||||
post_id: post.id,
|
post_id: post.id,
|
||||||
author_id: users[0].id,
|
author_id: users[0].id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let create = post.create_activity(conn).unwrap();
|
let create = post.create_activity(&conn).unwrap();
|
||||||
post.delete(conn, &r.searcher).unwrap();
|
post.delete(&conn).unwrap();
|
||||||
|
|
||||||
match inbox(&r, serde_json::to_value(create).unwrap()).unwrap() {
|
match inbox(&conn, serde_json::to_value(create).unwrap()).unwrap() {
|
||||||
InboxResult::Post(p) => {
|
InboxResult::Post(p) => {
|
||||||
assert!(p.is_author(conn, users[0].id).unwrap());
|
assert!(p.is_author(&conn, users[0].id).unwrap());
|
||||||
assert_eq!(p.source, "Hello".to_owned());
|
assert_eq!(p.source, "Hello".to_owned());
|
||||||
assert_eq!(p.blog_id, blogs[0].id);
|
assert_eq!(p.blog_id, blogs[0].id);
|
||||||
assert_eq!(p.content, SafeString::new("Hello"));
|
assert_eq!(p.content, SafeString::new("Hello"));
|
||||||
|
|||||||
@@ -0,0 +1,125 @@
|
|||||||
|
use crate::{
|
||||||
|
db_conn::{DbConn, DbPool},
|
||||||
|
follows,
|
||||||
|
posts::{LicensedArticle, Post},
|
||||||
|
users::{User, UserEvent},
|
||||||
|
ACTOR_SYS, CONFIG, USER_CHAN,
|
||||||
|
};
|
||||||
|
use activitypub::activity::Create;
|
||||||
|
use plume_common::activity_pub::inbox::FromId;
|
||||||
|
use riker::actors::{Actor, ActorFactoryArgs, ActorRefFactory, Context, Sender, Subscribe, Tell};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use tracing::{error, info, warn};
|
||||||
|
|
||||||
|
pub struct RemoteFetchActor {
|
||||||
|
conn: DbPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoteFetchActor {
|
||||||
|
pub fn init(conn: DbPool) {
|
||||||
|
ACTOR_SYS
|
||||||
|
.actor_of_args::<RemoteFetchActor, _>("remote-fetch", conn)
|
||||||
|
.expect("Failed to initialize remote fetch actor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for RemoteFetchActor {
|
||||||
|
type Msg = UserEvent;
|
||||||
|
|
||||||
|
fn pre_start(&mut self, ctx: &Context<Self::Msg>) {
|
||||||
|
USER_CHAN.tell(
|
||||||
|
Subscribe {
|
||||||
|
actor: Box::new(ctx.myself()),
|
||||||
|
topic: "*".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&mut self, _ctx: &Context<Self::Msg>, msg: Self::Msg, _sender: Sender) {
|
||||||
|
use UserEvent::*;
|
||||||
|
|
||||||
|
match msg {
|
||||||
|
RemoteUserFound(user) => match self.conn.get() {
|
||||||
|
Ok(conn) => {
|
||||||
|
let conn = DbConn(conn);
|
||||||
|
// Don't call these functions in parallel
|
||||||
|
// for the case database connections limit is too small
|
||||||
|
fetch_and_cache_articles(&user, &conn);
|
||||||
|
fetch_and_cache_followers(&user, &conn);
|
||||||
|
if user.needs_update() {
|
||||||
|
fetch_and_cache_user(&user, &conn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Failed to get database connection");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActorFactoryArgs<DbPool> for RemoteFetchActor {
|
||||||
|
fn create_args(conn: DbPool) -> Self {
|
||||||
|
Self { conn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_and_cache_articles(user: &Arc<User>, conn: &DbConn) {
|
||||||
|
let create_acts = user.fetch_outbox::<Create>();
|
||||||
|
match create_acts {
|
||||||
|
Ok(create_acts) => {
|
||||||
|
for create_act in create_acts {
|
||||||
|
match create_act.create_props.object_object::<LicensedArticle>() {
|
||||||
|
Ok(article) => {
|
||||||
|
Post::from_activity(conn, article)
|
||||||
|
.expect("Article from remote user couldn't be saved");
|
||||||
|
info!("Fetched article from remote user");
|
||||||
|
}
|
||||||
|
Err(e) => warn!("Error while fetching articles in background: {:?}", e),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to fetch outboxes: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_and_cache_followers(user: &Arc<User>, conn: &DbConn) {
|
||||||
|
let follower_ids = user.fetch_followers_ids();
|
||||||
|
match follower_ids {
|
||||||
|
Ok(user_ids) => {
|
||||||
|
for user_id in user_ids {
|
||||||
|
let follower = User::from_id(conn, &user_id, None, CONFIG.proxy());
|
||||||
|
match follower {
|
||||||
|
Ok(follower) => {
|
||||||
|
let inserted = follows::Follow::insert(
|
||||||
|
conn,
|
||||||
|
follows::NewFollow {
|
||||||
|
follower_id: follower.id,
|
||||||
|
following_id: user.id,
|
||||||
|
ap_url: String::new(),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if inserted.is_err() {
|
||||||
|
error!("Couldn't save follower for remote user: {:?}", user_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Couldn't fetch follower: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to fetch follower: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fetch_and_cache_user(user: &Arc<User>, conn: &DbConn) {
|
||||||
|
if user.refetch(conn).is_err() {
|
||||||
|
error!("Couldn't update user info: {:?}", user);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
notifications::*, posts::Post, schema::reshares, timeline::*, users::User, Connection, Error,
|
db_conn::DbConn, notifications::*, posts::Post, schema::reshares, timeline::*, users::User,
|
||||||
PlumeRocket, Result,
|
Connection, Error, Result, CONFIG,
|
||||||
};
|
};
|
||||||
use activitypub::activity::{Announce, Undo};
|
use activitypub::activity::{Announce, Undo};
|
||||||
use chrono::NaiveDateTime;
|
use chrono::NaiveDateTime;
|
||||||
@@ -107,12 +107,12 @@ impl Reshare {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Announce, &PlumeRocket> for Post {
|
impl AsObject<User, Announce, &DbConn> for Post {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = Reshare;
|
type Output = Reshare;
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, id: &str) -> Result<Reshare> {
|
fn activity(self, conn: &DbConn, actor: User, id: &str) -> Result<Reshare> {
|
||||||
let conn = &*c.conn;
|
let conn = conn;
|
||||||
let reshare = Reshare::insert(
|
let reshare = Reshare::insert(
|
||||||
conn,
|
conn,
|
||||||
NewReshare {
|
NewReshare {
|
||||||
@@ -123,49 +123,58 @@ impl AsObject<User, Announce, &PlumeRocket> for Post {
|
|||||||
)?;
|
)?;
|
||||||
reshare.notify(conn)?;
|
reshare.notify(conn)?;
|
||||||
|
|
||||||
Timeline::add_to_all_timelines(c, &self, Kind::Reshare(&actor))?;
|
Timeline::add_to_all_timelines(conn, &self, Kind::Reshare(&actor))?;
|
||||||
Ok(reshare)
|
Ok(reshare)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for Reshare {
|
impl FromId<DbConn> for Reshare {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = Announce;
|
type Object = Announce;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Reshare::find_by_ap_url(&c.conn, id)
|
Reshare::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, act: Announce) -> Result<Self> {
|
fn from_activity(conn: &DbConn, act: Announce) -> Result<Self> {
|
||||||
let res = Reshare::insert(
|
let res = Reshare::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewReshare {
|
NewReshare {
|
||||||
post_id: Post::from_id(c, &act.announce_props.object_link::<Id>()?, None)
|
post_id: Post::from_id(
|
||||||
.map_err(|(_, e)| e)?
|
conn,
|
||||||
.id,
|
&act.announce_props.object_link::<Id>()?,
|
||||||
user_id: User::from_id(c, &act.announce_props.actor_link::<Id>()?, None)
|
None,
|
||||||
.map_err(|(_, e)| e)?
|
CONFIG.proxy(),
|
||||||
.id,
|
)
|
||||||
|
.map_err(|(_, e)| e)?
|
||||||
|
.id,
|
||||||
|
user_id: User::from_id(
|
||||||
|
conn,
|
||||||
|
&act.announce_props.actor_link::<Id>()?,
|
||||||
|
None,
|
||||||
|
CONFIG.proxy(),
|
||||||
|
)
|
||||||
|
.map_err(|(_, e)| e)?
|
||||||
|
.id,
|
||||||
ap_url: act.object_props.id_string()?,
|
ap_url: act.object_props.id_string()?,
|
||||||
},
|
},
|
||||||
)?;
|
)?;
|
||||||
res.notify(&c.conn)?;
|
res.notify(conn)?;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Undo, &PlumeRocket> for Reshare {
|
impl AsObject<User, Undo, &DbConn> for Reshare {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
let conn = &*c.conn;
|
|
||||||
if actor.id == self.user_id {
|
if actor.id == self.user_id {
|
||||||
diesel::delete(&self).execute(conn)?;
|
diesel::delete(&self).execute(&**conn)?;
|
||||||
|
|
||||||
// delete associated notification if any
|
// delete associated notification if any
|
||||||
if let Ok(notif) = Notification::find(&conn, notification_kind::RESHARE, self.id) {
|
if let Ok(notif) = Notification::find(&conn, notification_kind::RESHARE, self.id) {
|
||||||
diesel::delete(¬if).execute(conn)?;
|
diesel::delete(¬if).execute(&**conn)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -11,14 +11,13 @@ use std::{
|
|||||||
borrow::{Borrow, Cow},
|
borrow::{Borrow, Cow},
|
||||||
fmt::{self, Display},
|
fmt::{self, Display},
|
||||||
io::Write,
|
io::Write,
|
||||||
iter,
|
|
||||||
ops::Deref,
|
ops::Deref,
|
||||||
};
|
};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CLEAN: Builder<'static> = {
|
static ref CLEAN: Builder<'static> = {
|
||||||
let mut b = Builder::new();
|
let mut b = Builder::new();
|
||||||
b.add_generic_attributes(iter::once("id"))
|
b.add_generic_attributes(&["id", "dir"])
|
||||||
.add_tags(&["iframe", "video", "audio", "label", "input"])
|
.add_tags(&["iframe", "video", "audio", "label", "input"])
|
||||||
.id_prefix(Some("postcontent-"))
|
.id_prefix(Some("postcontent-"))
|
||||||
.url_relative(UrlRelative::Custom(Box::new(url_add_prefix)))
|
.url_relative(UrlRelative::Custom(Box::new(url_add_prefix)))
|
||||||
@@ -82,6 +81,7 @@ lazy_static! {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn url_add_prefix(url: &str) -> Option<Cow<'_, str>> {
|
fn url_add_prefix(url: &str) -> Option<Cow<'_, str>> {
|
||||||
if url.starts_with('#') && !url.starts_with("#postcontent-") {
|
if url.starts_with('#') && !url.starts_with("#postcontent-") {
|
||||||
//if start with an #
|
//if start with an #
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
use super::Searcher;
|
||||||
|
use crate::{db_conn::DbPool, posts::PostEvent, ACTOR_SYS, POST_CHAN};
|
||||||
|
use riker::actors::{Actor, ActorFactoryArgs, ActorRefFactory, Context, Sender, Subscribe, Tell};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
use tracing::error;
|
||||||
|
|
||||||
|
pub struct SearchActor {
|
||||||
|
searcher: Arc<Searcher>,
|
||||||
|
conn: DbPool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SearchActor {
|
||||||
|
pub fn init(searcher: Arc<Searcher>, conn: DbPool) {
|
||||||
|
ACTOR_SYS
|
||||||
|
.actor_of_args::<SearchActor, _>("search", (searcher, conn))
|
||||||
|
.expect("Failed to initialize searcher actor");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Actor for SearchActor {
|
||||||
|
type Msg = PostEvent;
|
||||||
|
|
||||||
|
fn pre_start(&mut self, ctx: &Context<Self::Msg>) {
|
||||||
|
POST_CHAN.tell(
|
||||||
|
Subscribe {
|
||||||
|
actor: Box::new(ctx.myself()),
|
||||||
|
topic: "*".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn recv(&mut self, _ctx: &Context<Self::Msg>, msg: Self::Msg, _sender: Sender) {
|
||||||
|
use PostEvent::*;
|
||||||
|
|
||||||
|
// Wait for transaction commited
|
||||||
|
sleep(Duration::from_millis(500));
|
||||||
|
|
||||||
|
match msg {
|
||||||
|
PostPublished(post) => {
|
||||||
|
let conn = self.conn.get();
|
||||||
|
match conn {
|
||||||
|
Ok(conn) => {
|
||||||
|
self.searcher
|
||||||
|
.add_document(&conn, &post)
|
||||||
|
.unwrap_or_else(|e| error!("{:?}", e));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Failed to get database connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PostUpdated(post) => {
|
||||||
|
let conn = self.conn.get();
|
||||||
|
match conn {
|
||||||
|
Ok(_) => {
|
||||||
|
self.searcher
|
||||||
|
.update_document(&conn.unwrap(), &post)
|
||||||
|
.unwrap_or_else(|e| error!("{:?}", e));
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Failed to get database connection");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
PostDeleted(post) => self.searcher.delete_document(&post),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ActorFactoryArgs<(Arc<Searcher>, DbPool)> for SearchActor {
|
||||||
|
fn create_args((searcher, conn): (Arc<Searcher>, DbPool)) -> Self {
|
||||||
|
Self { searcher, conn }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use crate::diesel::Connection;
|
||||||
|
use crate::{
|
||||||
|
blog_authors::{BlogAuthor, NewBlogAuthor},
|
||||||
|
blogs::{Blog, NewBlog},
|
||||||
|
db_conn::{DbPool, PragmaForeignKey},
|
||||||
|
instance::{Instance, NewInstance},
|
||||||
|
post_authors::{NewPostAuthor, PostAuthor},
|
||||||
|
posts::{NewPost, Post},
|
||||||
|
safe_string::SafeString,
|
||||||
|
search::{actor::SearchActor, tests::get_searcher, Query},
|
||||||
|
users::{NewUser, User},
|
||||||
|
Connection as Conn, CONFIG,
|
||||||
|
};
|
||||||
|
use diesel::r2d2::ConnectionManager;
|
||||||
|
use plume_common::utils::random_hex;
|
||||||
|
use std::str::FromStr;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::thread::sleep;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn post_updated() {
|
||||||
|
// Need to commit so that searcher on another thread retrieve records.
|
||||||
|
// So, build DbPool instead of using DB_POOL for testing.
|
||||||
|
let manager = ConnectionManager::<Conn>::new(CONFIG.database_url.as_str());
|
||||||
|
let db_pool = DbPool::builder()
|
||||||
|
.connection_customizer(Box::new(PragmaForeignKey))
|
||||||
|
.build(manager)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
let searcher = Arc::new(get_searcher(&CONFIG.search_tokenizers));
|
||||||
|
SearchActor::init(searcher.clone(), db_pool.clone());
|
||||||
|
let conn = db_pool.clone().get().unwrap();
|
||||||
|
|
||||||
|
let title = random_hex()[..8].to_owned();
|
||||||
|
let (_instance, _user, blog) = fill_database(&conn);
|
||||||
|
let author = &blog.list_authors(&conn).unwrap()[0];
|
||||||
|
|
||||||
|
let post = Post::insert(
|
||||||
|
&conn,
|
||||||
|
NewPost {
|
||||||
|
blog_id: blog.id,
|
||||||
|
slug: title.clone(),
|
||||||
|
title: title.clone(),
|
||||||
|
content: SafeString::new(""),
|
||||||
|
published: true,
|
||||||
|
license: "CC-BY-SA".to_owned(),
|
||||||
|
ap_url: "".to_owned(),
|
||||||
|
creation_date: None,
|
||||||
|
subtitle: "".to_owned(),
|
||||||
|
source: "".to_owned(),
|
||||||
|
cover_id: None,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
PostAuthor::insert(
|
||||||
|
&conn,
|
||||||
|
NewPostAuthor {
|
||||||
|
post_id: post.id,
|
||||||
|
author_id: author.id,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let post_id = post.id;
|
||||||
|
|
||||||
|
// Wait for searcher on another thread add document asynchronously
|
||||||
|
sleep(Duration::from_millis(700));
|
||||||
|
searcher.commit();
|
||||||
|
assert_eq!(
|
||||||
|
searcher.search_document(&conn, Query::from_str(&title).unwrap(), (0, 1))[0].id,
|
||||||
|
post_id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn fill_database(conn: &Conn) -> (Instance, User, Blog) {
|
||||||
|
conn.transaction::<(Instance, User, Blog), diesel::result::Error, _>(|| {
|
||||||
|
let instance = Instance::insert(
|
||||||
|
conn,
|
||||||
|
NewInstance {
|
||||||
|
default_license: "CC-0-BY-SA".to_string(),
|
||||||
|
local: false,
|
||||||
|
long_description: SafeString::new("Good morning"),
|
||||||
|
long_description_html: "<p>Good morning</p>".to_string(),
|
||||||
|
short_description: SafeString::new("Hello"),
|
||||||
|
short_description_html: "<p>Hello</p>".to_string(),
|
||||||
|
name: random_hex().to_string(),
|
||||||
|
open_registrations: true,
|
||||||
|
public_domain: random_hex().to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let user = User::insert(
|
||||||
|
conn,
|
||||||
|
NewUser {
|
||||||
|
username: random_hex().to_string(),
|
||||||
|
display_name: random_hex().to_string(),
|
||||||
|
outbox_url: random_hex().to_string(),
|
||||||
|
inbox_url: random_hex().to_string(),
|
||||||
|
summary: "".to_string(),
|
||||||
|
email: None,
|
||||||
|
hashed_password: None,
|
||||||
|
instance_id: instance.id,
|
||||||
|
ap_url: random_hex().to_string(),
|
||||||
|
private_key: None,
|
||||||
|
public_key: "".to_string(),
|
||||||
|
shared_inbox_url: None,
|
||||||
|
followers_endpoint: random_hex().to_string(),
|
||||||
|
avatar_id: None,
|
||||||
|
summary_html: SafeString::new(""),
|
||||||
|
role: 0,
|
||||||
|
fqn: random_hex().to_string(),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
let mut blog = NewBlog::default();
|
||||||
|
blog.instance_id = instance.id;
|
||||||
|
blog.actor_id = random_hex().to_string();
|
||||||
|
blog.ap_url = random_hex().to_string();
|
||||||
|
blog.inbox_url = random_hex().to_string();
|
||||||
|
blog.outbox_url = random_hex().to_string();
|
||||||
|
let blog = Blog::insert(conn, blog).unwrap();
|
||||||
|
BlogAuthor::insert(
|
||||||
|
conn,
|
||||||
|
NewBlogAuthor {
|
||||||
|
blog_id: blog.id,
|
||||||
|
author_id: user.id,
|
||||||
|
is_owner: true,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
Ok((instance, user, blog))
|
||||||
|
})
|
||||||
|
.unwrap()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
pub mod actor;
|
||||||
mod query;
|
mod query;
|
||||||
mod searcher;
|
mod searcher;
|
||||||
mod tokenizer;
|
mod tokenizer;
|
||||||
@@ -7,12 +8,7 @@ pub use self::tokenizer::TokenizerKind;
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::{Query, Searcher, TokenizerKind};
|
use super::{Query, Searcher};
|
||||||
use diesel::Connection;
|
|
||||||
use plume_common::utils::random_hex;
|
|
||||||
use std::env::temp_dir;
|
|
||||||
use std::str::FromStr;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
blogs::tests::fill_database,
|
blogs::tests::fill_database,
|
||||||
config::SearchTokenizerConfig,
|
config::SearchTokenizerConfig,
|
||||||
@@ -22,6 +18,10 @@ pub(crate) mod tests {
|
|||||||
tests::db,
|
tests::db,
|
||||||
CONFIG,
|
CONFIG,
|
||||||
};
|
};
|
||||||
|
use diesel::Connection;
|
||||||
|
use plume_common::utils::random_hex;
|
||||||
|
use std::env::temp_dir;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
pub(crate) fn get_searcher(tokenizers: &SearchTokenizerConfig) -> Searcher {
|
pub(crate) fn get_searcher(tokenizers: &SearchTokenizerConfig) -> Searcher {
|
||||||
let dir = temp_dir().join(&format!("plume-test-{}", random_hex()));
|
let dir = temp_dir().join(&format!("plume-test-{}", random_hex()));
|
||||||
@@ -144,7 +144,6 @@ pub(crate) mod tests {
|
|||||||
source: "".to_owned(),
|
source: "".to_owned(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
PostAuthor::insert(
|
PostAuthor::insert(
|
||||||
@@ -155,7 +154,7 @@ pub(crate) mod tests {
|
|||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
searcher.add_document(&conn, &post).unwrap();
|
||||||
searcher.commit();
|
searcher.commit();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
searcher.search_document(conn, Query::from_str(&title).unwrap(), (0, 1))[0].id,
|
searcher.search_document(conn, Query::from_str(&title).unwrap(), (0, 1))[0].id,
|
||||||
@@ -164,7 +163,8 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
let newtitle = random_hex()[..8].to_owned();
|
let newtitle = random_hex()[..8].to_owned();
|
||||||
post.title = newtitle.clone();
|
post.title = newtitle.clone();
|
||||||
post.update(conn, &searcher).unwrap();
|
post.update(conn).unwrap();
|
||||||
|
searcher.update_document(conn, &post).unwrap();
|
||||||
searcher.commit();
|
searcher.commit();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
searcher.search_document(conn, Query::from_str(&newtitle).unwrap(), (0, 1))[0].id,
|
searcher.search_document(conn, Query::from_str(&newtitle).unwrap(), (0, 1))[0].id,
|
||||||
@@ -174,7 +174,7 @@ pub(crate) mod tests {
|
|||||||
.search_document(conn, Query::from_str(&title).unwrap(), (0, 1))
|
.search_document(conn, Query::from_str(&title).unwrap(), (0, 1))
|
||||||
.is_empty());
|
.is_empty());
|
||||||
|
|
||||||
post.delete(conn, &searcher).unwrap();
|
searcher.delete_document(&post);
|
||||||
searcher.commit();
|
searcher.commit();
|
||||||
assert!(searcher
|
assert!(searcher
|
||||||
.search_document(conn, Query::from_str(&newtitle).unwrap(), (0, 1))
|
.search_document(conn, Query::from_str(&newtitle).unwrap(), (0, 1))
|
||||||
@@ -213,7 +213,6 @@ pub(crate) mod tests {
|
|||||||
source: "".to_owned(),
|
source: "".to_owned(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
config::SearchTokenizerConfig, instance::Instance, posts::Post, schema::posts,
|
config::SearchTokenizerConfig, instance::Instance, posts::Post, schema::posts,
|
||||||
search::query::PlumeQuery, tags::Tag, Connection, Result,
|
search::query::PlumeQuery, tags::Tag, Connection, Error, Result,
|
||||||
};
|
};
|
||||||
use chrono::Datelike;
|
use chrono::{Datelike, Utc};
|
||||||
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
use diesel::{ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use std::fs;
|
||||||
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
||||||
use tantivy::{
|
use tantivy::{
|
||||||
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
||||||
ReloadPolicy, TantivyError, Term,
|
ReloadPolicy, TantivyError, Term,
|
||||||
};
|
};
|
||||||
|
use tracing::warn;
|
||||||
use whatlang::{detect as detect_lang, Lang};
|
use whatlang::{detect as detect_lang, Lang};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -67,6 +69,58 @@ impl Searcher {
|
|||||||
schema_builder.build()
|
schema_builder.build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn open_or_recreate(path: &dyn AsRef<Path>, tokenizers: &SearchTokenizerConfig) -> Self {
|
||||||
|
let mut open_searcher = Self::open(path, tokenizers);
|
||||||
|
if let Err(Error::Search(SearcherError::InvalidIndexDataError)) = open_searcher {
|
||||||
|
if Self::create(path, tokenizers).is_err() {
|
||||||
|
let backup_path = format!("{}.{}", path.as_ref().display(), Utc::now().timestamp());
|
||||||
|
let backup_path = Path::new(&backup_path);
|
||||||
|
fs::rename(path, backup_path)
|
||||||
|
.expect("main: error on backing up search index directory for recreating");
|
||||||
|
if Self::create(path, tokenizers).is_ok() {
|
||||||
|
if fs::remove_dir_all(backup_path).is_err() {
|
||||||
|
warn!(
|
||||||
|
"error on removing backup directory: {}. it remains",
|
||||||
|
backup_path.display()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
panic!("main: error on recreating search index in new index format. remove search index and run `plm search init` manually");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
open_searcher = Self::open(path, tokenizers);
|
||||||
|
}
|
||||||
|
match open_searcher {
|
||||||
|
Ok(s) => s,
|
||||||
|
Err(Error::Search(e)) => match e {
|
||||||
|
SearcherError::WriteLockAcquisitionError => panic!(
|
||||||
|
r#"
|
||||||
|
Your search index is locked. Plume can't start. To fix this issue
|
||||||
|
make sure no other Plume instance is started, and run:
|
||||||
|
|
||||||
|
plm search unlock
|
||||||
|
|
||||||
|
Then try to restart Plume.
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
SearcherError::IndexOpeningError => panic!(
|
||||||
|
r#"
|
||||||
|
Plume was unable to open the search index. If you created the index
|
||||||
|
before, make sure to run Plume in the same directory it was created in, or
|
||||||
|
to set SEARCH_INDEX accordingly. If you did not yet create the search
|
||||||
|
index, run this command:
|
||||||
|
|
||||||
|
plm search init
|
||||||
|
|
||||||
|
Then try to restart Plume
|
||||||
|
"#
|
||||||
|
),
|
||||||
|
e => Err(e).unwrap(),
|
||||||
|
},
|
||||||
|
_ => panic!("Unexpected error while opening search index"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create(path: &dyn AsRef<Path>, tokenizers: &SearchTokenizerConfig) -> Result<Self> {
|
pub fn create(path: &dyn AsRef<Path>, tokenizers: &SearchTokenizerConfig) -> Result<Self> {
|
||||||
let schema = Self::schema();
|
let schema = Self::schema();
|
||||||
|
|
||||||
|
|||||||
+134
-135
@@ -1,8 +1,9 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
|
db_conn::DbConn,
|
||||||
lists::List,
|
lists::List,
|
||||||
posts::Post,
|
posts::Post,
|
||||||
schema::{posts, timeline, timeline_definition},
|
schema::{posts, timeline, timeline_definition},
|
||||||
Connection, Error, PlumeRocket, Result,
|
Connection, Error, Result,
|
||||||
};
|
};
|
||||||
use diesel::{self, BoolExpressionMethods, ExpressionMethods, QueryDsl, RunQueryDsl};
|
use diesel::{self, BoolExpressionMethods, ExpressionMethods, QueryDsl, RunQueryDsl};
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
@@ -208,14 +209,14 @@ impl Timeline {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_to_all_timelines(rocket: &PlumeRocket, post: &Post, kind: Kind<'_>) -> Result<()> {
|
pub fn add_to_all_timelines(conn: &DbConn, post: &Post, kind: Kind<'_>) -> Result<()> {
|
||||||
let timelines = timeline_definition::table
|
let timelines = timeline_definition::table
|
||||||
.load::<Self>(rocket.conn.deref())
|
.load::<Self>(conn.deref())
|
||||||
.map_err(Error::from)?;
|
.map_err(Error::from)?;
|
||||||
|
|
||||||
for t in timelines {
|
for t in timelines {
|
||||||
if t.matches(rocket, post, kind)? {
|
if t.matches(conn, post, kind)? {
|
||||||
t.add_post(&rocket.conn, post)?;
|
t.add_post(conn, post)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -231,9 +232,9 @@ impl Timeline {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn matches(&self, rocket: &PlumeRocket, post: &Post, kind: Kind<'_>) -> Result<bool> {
|
pub fn matches(&self, conn: &DbConn, post: &Post, kind: Kind<'_>) -> Result<bool> {
|
||||||
let query = TimelineQuery::parse(&self.query)?;
|
let query = TimelineQuery::parse(&self.query)?;
|
||||||
query.matches(rocket, self, post, kind)
|
query.matches(conn, self, post, kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,7 +249,7 @@ mod tests {
|
|||||||
posts::NewPost,
|
posts::NewPost,
|
||||||
safe_string::SafeString,
|
safe_string::SafeString,
|
||||||
tags::Tag,
|
tags::Tag,
|
||||||
tests::{db, rockets},
|
tests::db,
|
||||||
users::tests as userTests,
|
users::tests as userTests,
|
||||||
};
|
};
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
@@ -257,63 +258,69 @@ mod tests {
|
|||||||
fn test_timeline() {
|
fn test_timeline() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let users = userTests::fill_database(conn);
|
let users = userTests::fill_database(&conn);
|
||||||
|
|
||||||
let mut tl1_u1 = Timeline::new_for_user(
|
let mut tl1_u1 = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"all".to_owned(),
|
"all".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
List::new(conn, "languages I speak", Some(&users[1]), ListType::Prefix).unwrap();
|
List::new(
|
||||||
|
&conn,
|
||||||
|
"languages I speak",
|
||||||
|
Some(&users[1]),
|
||||||
|
ListType::Prefix,
|
||||||
|
)
|
||||||
|
.unwrap();
|
||||||
let tl2_u1 = Timeline::new_for_user(
|
let tl2_u1 = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"another timeline".to_owned(),
|
"another timeline".to_owned(),
|
||||||
"followed".to_owned(),
|
"followed".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let tl1_u2 = Timeline::new_for_user(
|
let tl1_u2 = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[1].id,
|
users[1].id,
|
||||||
"english posts".to_owned(),
|
"english posts".to_owned(),
|
||||||
"lang in \"languages I speak\"".to_owned(),
|
"lang in \"languages I speak\"".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let tl1_instance = Timeline::new_for_instance(
|
let tl1_instance = Timeline::new_for_instance(
|
||||||
conn,
|
&conn,
|
||||||
"english posts".to_owned(),
|
"english posts".to_owned(),
|
||||||
"license in [cc]".to_owned(),
|
"license in [cc]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(tl1_u1, Timeline::get(conn, tl1_u1.id).unwrap());
|
assert_eq!(tl1_u1, Timeline::get(&conn, tl1_u1.id).unwrap());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tl2_u1,
|
tl2_u1,
|
||||||
Timeline::find_for_user_by_name(conn, Some(users[0].id), "another timeline")
|
Timeline::find_for_user_by_name(&conn, Some(users[0].id), "another timeline")
|
||||||
.unwrap()
|
.unwrap()
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tl1_instance,
|
tl1_instance,
|
||||||
Timeline::find_for_user_by_name(conn, None, "english posts").unwrap()
|
Timeline::find_for_user_by_name(&conn, None, "english posts").unwrap()
|
||||||
);
|
);
|
||||||
|
|
||||||
let tl_u1 = Timeline::list_for_user(conn, Some(users[0].id)).unwrap();
|
let tl_u1 = Timeline::list_for_user(&conn, Some(users[0].id)).unwrap();
|
||||||
assert_eq!(3, tl_u1.len()); // it is not 2 because there is a "Your feed" tl created for each user automatically
|
assert_eq!(3, tl_u1.len()); // it is not 2 because there is a "Your feed" tl created for each user automatically
|
||||||
assert!(tl_u1.iter().fold(false, |res, tl| { res || *tl == tl1_u1 }));
|
assert!(tl_u1.iter().fold(false, |res, tl| { res || *tl == tl1_u1 }));
|
||||||
assert!(tl_u1.iter().fold(false, |res, tl| { res || *tl == tl2_u1 }));
|
assert!(tl_u1.iter().fold(false, |res, tl| { res || *tl == tl2_u1 }));
|
||||||
|
|
||||||
let tl_instance = Timeline::list_for_user(conn, None).unwrap();
|
let tl_instance = Timeline::list_for_user(&conn, None).unwrap();
|
||||||
assert_eq!(3, tl_instance.len()); // there are also the local and federated feed by default
|
assert_eq!(3, tl_instance.len()); // there are also the local and federated feed by default
|
||||||
assert!(tl_instance
|
assert!(tl_instance
|
||||||
.iter()
|
.iter()
|
||||||
.fold(false, |res, tl| { res || *tl == tl1_instance }));
|
.fold(false, |res, tl| { res || *tl == tl1_instance }));
|
||||||
|
|
||||||
tl1_u1.name = "My Super TL".to_owned();
|
tl1_u1.name = "My Super TL".to_owned();
|
||||||
let new_tl1_u2 = tl1_u2.update(conn).unwrap();
|
let new_tl1_u2 = tl1_u2.update(&conn).unwrap();
|
||||||
|
|
||||||
let tl_u2 = Timeline::list_for_user(conn, Some(users[1].id)).unwrap();
|
let tl_u2 = Timeline::list_for_user(&conn, Some(users[1].id)).unwrap();
|
||||||
assert_eq!(2, tl_u2.len()); // same here
|
assert_eq!(2, tl_u2.len()); // same here
|
||||||
assert!(tl_u2
|
assert!(tl_u2
|
||||||
.iter()
|
.iter()
|
||||||
@@ -327,48 +334,48 @@ mod tests {
|
|||||||
fn test_timeline_creation_error() {
|
fn test_timeline_creation_error() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let users = userTests::fill_database(conn);
|
let users = userTests::fill_database(&conn);
|
||||||
|
|
||||||
assert!(Timeline::new_for_user(
|
assert!(Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"invalid keyword".to_owned(),
|
"invalid keyword".to_owned(),
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(Timeline::new_for_instance(
|
assert!(Timeline::new_for_instance(
|
||||||
conn,
|
&conn,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"invalid keyword".to_owned(),
|
"invalid keyword".to_owned(),
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
assert!(Timeline::new_for_user(
|
assert!(Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"author in non_existant_list".to_owned(),
|
"author in non_existant_list".to_owned(),
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(Timeline::new_for_instance(
|
assert!(Timeline::new_for_instance(
|
||||||
conn,
|
&conn,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"lang in dont-exist".to_owned(),
|
"lang in dont-exist".to_owned(),
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
List::new(conn, "friends", Some(&users[0]), ListType::User).unwrap();
|
List::new(&conn, "friends", Some(&users[0]), ListType::User).unwrap();
|
||||||
List::new(conn, "idk", None, ListType::Blog).unwrap();
|
List::new(&conn, "idk", None, ListType::Blog).unwrap();
|
||||||
|
|
||||||
assert!(Timeline::new_for_user(
|
assert!(Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"blog in friends".to_owned(),
|
"blog in friends".to_owned(),
|
||||||
)
|
)
|
||||||
.is_err());
|
.is_err());
|
||||||
assert!(Timeline::new_for_instance(
|
assert!(Timeline::new_for_instance(
|
||||||
conn,
|
&conn,
|
||||||
"my timeline".to_owned(),
|
"my timeline".to_owned(),
|
||||||
"not author in idk".to_owned(),
|
"not author in idk".to_owned(),
|
||||||
)
|
)
|
||||||
@@ -380,13 +387,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_simple_match() {
|
fn test_simple_match() {
|
||||||
let r = &rockets();
|
let conn = &db();
|
||||||
let conn = &r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
|
|
||||||
let gnu_tl = Timeline::new_for_user(
|
let gnu_tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"GNU timeline".to_owned(),
|
"GNU timeline".to_owned(),
|
||||||
"license in [AGPL, LGPL, GPL]".to_owned(),
|
"license in [AGPL, LGPL, GPL]".to_owned(),
|
||||||
@@ -394,7 +400,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let gnu_post = Post::insert(
|
let gnu_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug".to_string(),
|
slug: "slug".to_string(),
|
||||||
@@ -408,13 +414,12 @@ mod tests {
|
|||||||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(gnu_tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(gnu_tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
|
|
||||||
let non_free_post = Post::insert(
|
let non_free_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug2".to_string(),
|
slug: "slug2".to_string(),
|
||||||
@@ -428,10 +433,11 @@ mod tests {
|
|||||||
source: "so is Microsoft".to_string(),
|
source: "so is Microsoft".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!gnu_tl.matches(r, &non_free_post, Kind::Original).unwrap());
|
assert!(!gnu_tl
|
||||||
|
.matches(&conn, &non_free_post, Kind::Original)
|
||||||
|
.unwrap());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -439,12 +445,11 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_complex_match() {
|
fn test_complex_match() {
|
||||||
let r = &rockets();
|
let conn = &db();
|
||||||
let conn = &r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
Follow::insert(
|
Follow::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewFollow {
|
NewFollow {
|
||||||
follower_id: users[0].id,
|
follower_id: users[0].id,
|
||||||
following_id: users[1].id,
|
following_id: users[1].id,
|
||||||
@@ -454,11 +459,11 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let fav_blogs_list =
|
let fav_blogs_list =
|
||||||
List::new(conn, "fav_blogs", Some(&users[0]), ListType::Blog).unwrap();
|
List::new(&conn, "fav_blogs", Some(&users[0]), ListType::Blog).unwrap();
|
||||||
fav_blogs_list.add_blogs(conn, &[blogs[0].id]).unwrap();
|
fav_blogs_list.add_blogs(&conn, &[blogs[0].id]).unwrap();
|
||||||
|
|
||||||
let my_tl = Timeline::new_for_user(
|
let my_tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"My timeline".to_owned(),
|
"My timeline".to_owned(),
|
||||||
"blog in fav_blogs and not has_cover or local and followed exclude likes"
|
"blog in fav_blogs and not has_cover or local and followed exclude likes"
|
||||||
@@ -467,7 +472,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let post = Post::insert(
|
let post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "about-linux".to_string(),
|
slug: "about-linux".to_string(),
|
||||||
@@ -481,13 +486,12 @@ mod tests {
|
|||||||
subtitle: "".to_string(),
|
subtitle: "".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(my_tl.matches(r, &post, Kind::Original).unwrap()); // matches because of "blog in fav_blogs" (and there is no cover)
|
assert!(my_tl.matches(&conn, &post, Kind::Original).unwrap()); // matches because of "blog in fav_blogs" (and there is no cover)
|
||||||
|
|
||||||
let post = Post::insert(
|
let post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[1].id,
|
blog_id: blogs[1].id,
|
||||||
slug: "about-linux-2".to_string(),
|
slug: "about-linux-2".to_string(),
|
||||||
@@ -503,10 +507,9 @@ mod tests {
|
|||||||
subtitle: "".to_string(),
|
subtitle: "".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!my_tl.matches(r, &post, Kind::Like(&users[1])).unwrap());
|
assert!(!my_tl.matches(&conn, &post, Kind::Like(&users[1])).unwrap());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -514,20 +517,19 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_add_to_all_timelines() {
|
fn test_add_to_all_timelines() {
|
||||||
let r = &rockets();
|
let conn = &db();
|
||||||
let conn = &r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
|
|
||||||
let gnu_tl = Timeline::new_for_user(
|
let gnu_tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"GNU timeline".to_owned(),
|
"GNU timeline".to_owned(),
|
||||||
"license in [AGPL, LGPL, GPL]".to_owned(),
|
"license in [AGPL, LGPL, GPL]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let non_gnu_tl = Timeline::new_for_user(
|
let non_gnu_tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Stallman disapproved timeline".to_owned(),
|
"Stallman disapproved timeline".to_owned(),
|
||||||
"not license in [AGPL, LGPL, GPL]".to_owned(),
|
"not license in [AGPL, LGPL, GPL]".to_owned(),
|
||||||
@@ -535,7 +537,7 @@ mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let gnu_post = Post::insert(
|
let gnu_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug".to_string(),
|
slug: "slug".to_string(),
|
||||||
@@ -549,12 +551,11 @@ mod tests {
|
|||||||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let non_free_post = Post::insert(
|
let non_free_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug2".to_string(),
|
slug: "slug2".to_string(),
|
||||||
@@ -568,17 +569,16 @@ mod tests {
|
|||||||
source: "so is Microsoft".to_string(),
|
source: "so is Microsoft".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
Timeline::add_to_all_timelines(r, &gnu_post, Kind::Original).unwrap();
|
Timeline::add_to_all_timelines(&conn, &gnu_post, Kind::Original).unwrap();
|
||||||
Timeline::add_to_all_timelines(r, &non_free_post, Kind::Original).unwrap();
|
Timeline::add_to_all_timelines(&conn, &non_free_post, Kind::Original).unwrap();
|
||||||
|
|
||||||
let res = gnu_tl.get_latest(conn, 2).unwrap();
|
let res = gnu_tl.get_latest(&conn, 2).unwrap();
|
||||||
assert_eq!(res.len(), 1);
|
assert_eq!(res.len(), 1);
|
||||||
assert_eq!(res[0].id, gnu_post.id);
|
assert_eq!(res[0].id, gnu_post.id);
|
||||||
let res = non_gnu_tl.get_latest(conn, 2).unwrap();
|
let res = non_gnu_tl.get_latest(&conn, 2).unwrap();
|
||||||
assert_eq!(res.len(), 1);
|
assert_eq!(res.len(), 1);
|
||||||
assert_eq!(res[0].id, non_free_post.id);
|
assert_eq!(res[0].id, non_free_post.id);
|
||||||
|
|
||||||
@@ -588,13 +588,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_matches_lists_direct() {
|
fn test_matches_lists_direct() {
|
||||||
let r = &rockets();
|
let conn = &db();
|
||||||
let conn = &r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
|
|
||||||
let gnu_post = Post::insert(
|
let gnu_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug".to_string(),
|
slug: "slug".to_string(),
|
||||||
@@ -608,65 +607,66 @@ mod tests {
|
|||||||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gnu_post
|
gnu_post
|
||||||
.update_tags(conn, vec![Tag::build_activity("free".to_owned()).unwrap()])
|
.update_tags(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()])
|
||||||
.unwrap();
|
.unwrap();
|
||||||
PostAuthor::insert(
|
PostAuthor::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPostAuthor {
|
NewPostAuthor {
|
||||||
post_id: gnu_post.id,
|
post_id: gnu_post.id,
|
||||||
author_id: blogs[0].list_authors(conn).unwrap()[0].id,
|
author_id: blogs[0].list_authors(&conn).unwrap()[0].id,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"blog timeline".to_owned(),
|
"blog timeline".to_owned(),
|
||||||
format!("blog in [{}]", blogs[0].fqn),
|
format!("blog in [{}]", blogs[0].fqn),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"blog timeline".to_owned(),
|
"blog timeline".to_owned(),
|
||||||
"blog in [no_one@nowhere]".to_owned(),
|
"blog in [no_one@nowhere]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"author timeline".to_owned(),
|
"author timeline".to_owned(),
|
||||||
format!(
|
format!(
|
||||||
"author in [{}]",
|
"author in [{}]",
|
||||||
blogs[0].list_authors(conn).unwrap()[0].fqn
|
blogs[0].list_authors(&conn).unwrap()[0].fqn
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"author timeline".to_owned(),
|
"author timeline".to_owned(),
|
||||||
format!("author in [{}]", users[2].fqn),
|
format!("author in [{}]", users[2].fqn),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Reshare(&users[2])).unwrap());
|
assert!(tl
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Like(&users[2])).unwrap());
|
.matches(&conn, &gnu_post, Kind::Reshare(&users[2]))
|
||||||
tl.delete(conn).unwrap();
|
.unwrap());
|
||||||
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Like(&users[2])).unwrap());
|
||||||
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"author timeline".to_owned(),
|
"author timeline".to_owned(),
|
||||||
format!(
|
format!(
|
||||||
@@ -675,48 +675,50 @@ mod tests {
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Reshare(&users[2])).unwrap());
|
assert!(!tl
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Like(&users[2])).unwrap());
|
.matches(&conn, &gnu_post, Kind::Reshare(&users[2]))
|
||||||
tl.delete(conn).unwrap();
|
.unwrap());
|
||||||
|
assert!(tl.matches(&conn, &gnu_post, Kind::Like(&users[2])).unwrap());
|
||||||
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"tag timeline".to_owned(),
|
"tag timeline".to_owned(),
|
||||||
"tags in [free]".to_owned(),
|
"tags in [free]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"tag timeline".to_owned(),
|
"tag timeline".to_owned(),
|
||||||
"tags in [private]".to_owned(),
|
"tags in [private]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"english timeline".to_owned(),
|
"english timeline".to_owned(),
|
||||||
"lang in [en]".to_owned(),
|
"lang in [en]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"franco-italian timeline".to_owned(),
|
"franco-italian timeline".to_owned(),
|
||||||
"lang in [fr, it]".to_owned(),
|
"lang in [fr, it]".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -726,12 +728,12 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_matches_lists_saved() {
|
fn test_matches_lists_saved() {
|
||||||
let r = &rockets();
|
let r = &rockets();
|
||||||
let conn = &r.conn;
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
|
|
||||||
let gnu_post = Post::insert(
|
let gnu_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug".to_string(),
|
slug: "slug".to_string(),
|
||||||
@@ -745,11 +747,10 @@ mod tests {
|
|||||||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
gnu_post.update_tags(conn, vec![Tag::build_activity("free".to_owned()).unwrap()]).unwrap();
|
gnu_post.update_tags(&conn, vec![Tag::build_activity("free".to_owned()).unwrap()]).unwrap();
|
||||||
PostAuthor::insert(conn, NewPostAuthor {post_id: gnu_post.id, author_id: blogs[0].list_authors(conn).unwrap()[0].id}).unwrap();
|
PostAuthor::insert(&conn, NewPostAuthor {post_id: gnu_post.id, author_id: blogs[0].list_authors(&conn).unwrap()[0].id}).unwrap();
|
||||||
|
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
|
|
||||||
@@ -759,13 +760,12 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_matches_keyword() {
|
fn test_matches_keyword() {
|
||||||
let r = &rockets();
|
let conn = &db();
|
||||||
let conn = &r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let (users, blogs) = blogTests::fill_database(conn);
|
let (users, blogs) = blogTests::fill_database(&conn);
|
||||||
|
|
||||||
let gnu_post = Post::insert(
|
let gnu_post = Post::insert(
|
||||||
conn,
|
&conn,
|
||||||
NewPost {
|
NewPost {
|
||||||
blog_id: blogs[0].id,
|
blog_id: blogs[0].id,
|
||||||
slug: "slug".to_string(),
|
slug: "slug".to_string(),
|
||||||
@@ -779,66 +779,65 @@ mod tests {
|
|||||||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||||
cover_id: None,
|
cover_id: None,
|
||||||
},
|
},
|
||||||
&r.searcher,
|
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Linux title".to_owned(),
|
"Linux title".to_owned(),
|
||||||
"title contains Linux".to_owned(),
|
"title contains Linux".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Microsoft title".to_owned(),
|
"Microsoft title".to_owned(),
|
||||||
"title contains Microsoft".to_owned(),
|
"title contains Microsoft".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Linux subtitle".to_owned(),
|
"Linux subtitle".to_owned(),
|
||||||
"subtitle contains Stallman".to_owned(),
|
"subtitle contains Stallman".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Microsoft subtitle".to_owned(),
|
"Microsoft subtitle".to_owned(),
|
||||||
"subtitle contains Nadella".to_owned(),
|
"subtitle contains Nadella".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Linux content".to_owned(),
|
"Linux content".to_owned(),
|
||||||
"content contains Linux".to_owned(),
|
"content contains Linux".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
let tl = Timeline::new_for_user(
|
let tl = Timeline::new_for_user(
|
||||||
conn,
|
&conn,
|
||||||
users[0].id,
|
users[0].id,
|
||||||
"Microsoft content".to_owned(),
|
"Microsoft content".to_owned(),
|
||||||
"subtitle contains Windows".to_owned(),
|
"subtitle contains Windows".to_owned(),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert!(!tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
assert!(!tl.matches(&conn, &gnu_post, Kind::Original).unwrap());
|
||||||
tl.delete(conn).unwrap();
|
tl.delete(&conn).unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
blogs::Blog,
|
blogs::Blog,
|
||||||
|
db_conn::DbConn,
|
||||||
lists::{self, ListType},
|
lists::{self, ListType},
|
||||||
posts::Post,
|
posts::Post,
|
||||||
tags::Tag,
|
tags::Tag,
|
||||||
timeline::Timeline,
|
timeline::Timeline,
|
||||||
users::User,
|
users::User,
|
||||||
PlumeRocket, Result,
|
Result,
|
||||||
};
|
};
|
||||||
use plume_common::activity_pub::inbox::AsActor;
|
use plume_common::activity_pub::inbox::AsActor;
|
||||||
use whatlang::{self, Lang};
|
use whatlang::{self, Lang};
|
||||||
@@ -160,19 +161,19 @@ enum TQ<'a> {
|
|||||||
impl<'a> TQ<'a> {
|
impl<'a> TQ<'a> {
|
||||||
fn matches(
|
fn matches(
|
||||||
&self,
|
&self,
|
||||||
rocket: &PlumeRocket,
|
conn: &DbConn,
|
||||||
timeline: &Timeline,
|
timeline: &Timeline,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
kind: Kind<'_>,
|
kind: Kind<'_>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
match self {
|
match self {
|
||||||
TQ::Or(inner) => inner.iter().try_fold(false, |s, e| {
|
TQ::Or(inner) => inner.iter().try_fold(false, |s, e| {
|
||||||
e.matches(rocket, timeline, post, kind).map(|r| s || r)
|
e.matches(conn, timeline, post, kind).map(|r| s || r)
|
||||||
}),
|
}),
|
||||||
TQ::And(inner) => inner.iter().try_fold(true, |s, e| {
|
TQ::And(inner) => inner.iter().try_fold(true, |s, e| {
|
||||||
e.matches(rocket, timeline, post, kind).map(|r| s && r)
|
e.matches(conn, timeline, post, kind).map(|r| s && r)
|
||||||
}),
|
}),
|
||||||
TQ::Arg(inner, invert) => Ok(inner.matches(rocket, timeline, post, kind)? ^ invert),
|
TQ::Arg(inner, invert) => Ok(inner.matches(conn, timeline, post, kind)? ^ invert),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,15 +206,15 @@ enum Arg<'a> {
|
|||||||
impl<'a> Arg<'a> {
|
impl<'a> Arg<'a> {
|
||||||
pub fn matches(
|
pub fn matches(
|
||||||
&self,
|
&self,
|
||||||
rocket: &PlumeRocket,
|
conn: &DbConn,
|
||||||
timeline: &Timeline,
|
timeline: &Timeline,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
kind: Kind<'_>,
|
kind: Kind<'_>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
match self {
|
match self {
|
||||||
Arg::In(t, l) => t.matches(rocket, timeline, post, l, kind),
|
Arg::In(t, l) => t.matches(conn, timeline, post, l, kind),
|
||||||
Arg::Contains(t, v) => t.matches(post, v),
|
Arg::Contains(t, v) => t.matches(post, v),
|
||||||
Arg::Boolean(t) => t.matches(rocket, timeline, post, kind),
|
Arg::Boolean(t) => t.matches(conn, timeline, post, kind),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +231,7 @@ enum WithList {
|
|||||||
impl WithList {
|
impl WithList {
|
||||||
pub fn matches(
|
pub fn matches(
|
||||||
&self,
|
&self,
|
||||||
rocket: &PlumeRocket,
|
conn: &DbConn,
|
||||||
timeline: &Timeline,
|
timeline: &Timeline,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
list: &List<'_>,
|
list: &List<'_>,
|
||||||
@@ -238,39 +239,34 @@ impl WithList {
|
|||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
match list {
|
match list {
|
||||||
List::List(name) => {
|
List::List(name) => {
|
||||||
let list =
|
let list = lists::List::find_for_user_by_name(conn, timeline.user_id, &name)?;
|
||||||
lists::List::find_for_user_by_name(&rocket.conn, timeline.user_id, &name)?;
|
|
||||||
match (self, list.kind()) {
|
match (self, list.kind()) {
|
||||||
(WithList::Blog, ListType::Blog) => {
|
(WithList::Blog, ListType::Blog) => list.contains_blog(conn, post.blog_id),
|
||||||
list.contains_blog(&rocket.conn, post.blog_id)
|
|
||||||
}
|
|
||||||
(WithList::Author { boosts, likes }, ListType::User) => match kind {
|
(WithList::Author { boosts, likes }, ListType::User) => match kind {
|
||||||
Kind::Original => Ok(list
|
Kind::Original => Ok(list
|
||||||
.list_users(&rocket.conn)?
|
.list_users(conn)?
|
||||||
.iter()
|
.iter()
|
||||||
.any(|a| post.is_author(&rocket.conn, a.id).unwrap_or(false))),
|
.any(|a| post.is_author(conn, a.id).unwrap_or(false))),
|
||||||
Kind::Reshare(u) => {
|
Kind::Reshare(u) => {
|
||||||
if *boosts {
|
if *boosts {
|
||||||
list.contains_user(&rocket.conn, u.id)
|
list.contains_user(conn, u.id)
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Like(u) => {
|
Kind::Like(u) => {
|
||||||
if *likes {
|
if *likes {
|
||||||
list.contains_user(&rocket.conn, u.id)
|
list.contains_user(conn, u.id)
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
(WithList::License, ListType::Word) => {
|
(WithList::License, ListType::Word) => list.contains_word(conn, &post.license),
|
||||||
list.contains_word(&rocket.conn, &post.license)
|
|
||||||
}
|
|
||||||
(WithList::Tags, ListType::Word) => {
|
(WithList::Tags, ListType::Word) => {
|
||||||
let tags = Tag::for_post(&rocket.conn, post.id)?;
|
let tags = Tag::for_post(conn, post.id)?;
|
||||||
Ok(list
|
Ok(list
|
||||||
.list_words(&rocket.conn)?
|
.list_words(conn)?
|
||||||
.iter()
|
.iter()
|
||||||
.any(|s| tags.iter().any(|t| s == &t.tag)))
|
.any(|s| tags.iter().any(|t| s == &t.tag)))
|
||||||
}
|
}
|
||||||
@@ -285,7 +281,7 @@ impl WithList {
|
|||||||
})
|
})
|
||||||
.unwrap_or(Lang::Eng)
|
.unwrap_or(Lang::Eng)
|
||||||
.name();
|
.name();
|
||||||
list.contains_prefix(&rocket.conn, lang)
|
list.contains_prefix(conn, lang)
|
||||||
}
|
}
|
||||||
(_, _) => Err(QueryError::RuntimeError(format!(
|
(_, _) => Err(QueryError::RuntimeError(format!(
|
||||||
"The list '{}' is of the wrong type for this usage",
|
"The list '{}' is of the wrong type for this usage",
|
||||||
@@ -297,13 +293,13 @@ impl WithList {
|
|||||||
List::Array(list) => match self {
|
List::Array(list) => match self {
|
||||||
WithList::Blog => Ok(list
|
WithList::Blog => Ok(list
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|b| Blog::find_by_fqn(rocket, b).ok())
|
.filter_map(|b| Blog::find_by_fqn(conn, b).ok())
|
||||||
.any(|b| b.id == post.blog_id)),
|
.any(|b| b.id == post.blog_id)),
|
||||||
WithList::Author { boosts, likes } => match kind {
|
WithList::Author { boosts, likes } => match kind {
|
||||||
Kind::Original => Ok(list
|
Kind::Original => Ok(list
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|a| User::find_by_fqn(rocket, a).ok())
|
.filter_map(|a| User::find_by_fqn(&*conn, a).ok())
|
||||||
.any(|a| post.is_author(&rocket.conn, a.id).unwrap_or(false))),
|
.any(|a| post.is_author(conn, a.id).unwrap_or(false))),
|
||||||
Kind::Reshare(u) => {
|
Kind::Reshare(u) => {
|
||||||
if *boosts {
|
if *boosts {
|
||||||
Ok(list.iter().any(|user| &u.fqn == user))
|
Ok(list.iter().any(|user| &u.fqn == user))
|
||||||
@@ -321,7 +317,7 @@ impl WithList {
|
|||||||
},
|
},
|
||||||
WithList::License => Ok(list.iter().any(|s| s == &post.license)),
|
WithList::License => Ok(list.iter().any(|s| s == &post.license)),
|
||||||
WithList::Tags => {
|
WithList::Tags => {
|
||||||
let tags = Tag::for_post(&rocket.conn, post.id)?;
|
let tags = Tag::for_post(conn, post.id)?;
|
||||||
Ok(list.iter().any(|s| tags.iter().any(|t| s == &t.tag)))
|
Ok(list.iter().any(|s| tags.iter().any(|t| s == &t.tag)))
|
||||||
}
|
}
|
||||||
WithList::Lang => {
|
WithList::Lang => {
|
||||||
@@ -371,7 +367,7 @@ enum Bool {
|
|||||||
impl Bool {
|
impl Bool {
|
||||||
pub fn matches(
|
pub fn matches(
|
||||||
&self,
|
&self,
|
||||||
rocket: &PlumeRocket,
|
conn: &DbConn,
|
||||||
timeline: &Timeline,
|
timeline: &Timeline,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
kind: Kind<'_>,
|
kind: Kind<'_>,
|
||||||
@@ -384,21 +380,19 @@ impl Bool {
|
|||||||
let user = timeline.user_id.unwrap();
|
let user = timeline.user_id.unwrap();
|
||||||
match kind {
|
match kind {
|
||||||
Kind::Original => post
|
Kind::Original => post
|
||||||
.get_authors(&rocket.conn)?
|
.get_authors(conn)?
|
||||||
.iter()
|
.iter()
|
||||||
.try_fold(false, |s, a| {
|
.try_fold(false, |s, a| a.is_followed_by(conn, user).map(|r| s || r)),
|
||||||
a.is_followed_by(&rocket.conn, user).map(|r| s || r)
|
|
||||||
}),
|
|
||||||
Kind::Reshare(u) => {
|
Kind::Reshare(u) => {
|
||||||
if *boosts {
|
if *boosts {
|
||||||
u.is_followed_by(&rocket.conn, user)
|
u.is_followed_by(conn, user)
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Kind::Like(u) => {
|
Kind::Like(u) => {
|
||||||
if *likes {
|
if *likes {
|
||||||
u.is_followed_by(&rocket.conn, user)
|
u.is_followed_by(conn, user)
|
||||||
} else {
|
} else {
|
||||||
Ok(false)
|
Ok(false)
|
||||||
}
|
}
|
||||||
@@ -406,7 +400,7 @@ impl Bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Bool::HasCover => Ok(post.cover_id.is_some()),
|
Bool::HasCover => Ok(post.cover_id.is_some()),
|
||||||
Bool::Local => Ok(post.get_blog(&rocket.conn)?.is_local() && kind == Kind::Original),
|
Bool::Local => Ok(post.get_blog(conn)?.is_local() && kind == Kind::Original),
|
||||||
Bool::All => Ok(kind == Kind::Original),
|
Bool::All => Ok(kind == Kind::Original),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -642,12 +636,12 @@ impl<'a> TimelineQuery<'a> {
|
|||||||
|
|
||||||
pub fn matches(
|
pub fn matches(
|
||||||
&self,
|
&self,
|
||||||
rocket: &PlumeRocket,
|
conn: &DbConn,
|
||||||
timeline: &Timeline,
|
timeline: &Timeline,
|
||||||
post: &Post,
|
post: &Post,
|
||||||
kind: Kind<'_>,
|
kind: Kind<'_>,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
self.0.matches(rocket, timeline, post, kind)
|
self.0.matches(conn, timeline, post, kind)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn list_used_lists(&self) -> Vec<(String, ListType)> {
|
pub fn list_used_lists(&self) -> Vec<(String, ListType)> {
|
||||||
|
|||||||
+125
-76
@@ -1,8 +1,8 @@
|
|||||||
use crate::{
|
use crate::{
|
||||||
ap_url, blocklisted_emails::BlocklistedEmail, blogs::Blog, config::CONFIG, db_conn::DbConn,
|
ap_url, blocklisted_emails::BlocklistedEmail, blogs::Blog, db_conn::DbConn, follows::Follow,
|
||||||
follows::Follow, instance::*, medias::Media, notifications::Notification,
|
instance::*, medias::Media, notifications::Notification, post_authors::PostAuthor, posts::Post,
|
||||||
post_authors::PostAuthor, posts::Post, safe_string::SafeString, schema::users,
|
safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, Result,
|
||||||
search::Searcher, timeline::Timeline, Connection, Error, PlumeRocket, Result, ITEMS_PER_PAGE,
|
UserEvent::*, CONFIG, ITEMS_PER_PAGE, USER_CHAN,
|
||||||
};
|
};
|
||||||
use activitypub::{
|
use activitypub::{
|
||||||
activity::Delete,
|
activity::Delete,
|
||||||
@@ -11,7 +11,6 @@ use activitypub::{
|
|||||||
object::{Image, Tombstone},
|
object::{Image, Tombstone},
|
||||||
Activity, CustomObject, Endpoint,
|
Activity, CustomObject, Endpoint,
|
||||||
};
|
};
|
||||||
use bcrypt;
|
|
||||||
use chrono::{NaiveDateTime, Utc};
|
use chrono::{NaiveDateTime, Utc};
|
||||||
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
use diesel::{self, BelongingToDsl, ExpressionMethods, OptionalExtension, QueryDsl, RunQueryDsl};
|
||||||
use ldap3::{LdapConn, Scope, SearchEntry};
|
use ldap3::{LdapConn, Scope, SearchEntry};
|
||||||
@@ -34,14 +33,15 @@ use reqwest::{
|
|||||||
header::{HeaderValue, ACCEPT},
|
header::{HeaderValue, ACCEPT},
|
||||||
ClientBuilder,
|
ClientBuilder,
|
||||||
};
|
};
|
||||||
|
use riker::actors::{Publish, Tell};
|
||||||
use rocket::{
|
use rocket::{
|
||||||
outcome::IntoOutcome,
|
outcome::IntoOutcome,
|
||||||
request::{self, FromRequest, Request},
|
request::{self, FromRequest, Request},
|
||||||
};
|
};
|
||||||
use serde_json;
|
|
||||||
use std::{
|
use std::{
|
||||||
cmp::PartialEq,
|
cmp::PartialEq,
|
||||||
hash::{Hash, Hasher},
|
hash::{Hash, Hasher},
|
||||||
|
sync::Arc,
|
||||||
};
|
};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use webfinger::*;
|
use webfinger::*;
|
||||||
@@ -131,14 +131,14 @@ impl User {
|
|||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete(&self, conn: &Connection, searcher: &Searcher) -> Result<()> {
|
pub fn delete(&self, conn: &Connection) -> Result<()> {
|
||||||
use crate::schema::post_authors;
|
use crate::schema::post_authors;
|
||||||
|
|
||||||
for blog in Blog::find_for_author(conn, self)?
|
for blog in Blog::find_for_author(conn, self)?
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|b| b.count_authors(conn).map(|c| c <= 1).unwrap_or(false))
|
.filter(|b| b.count_authors(conn).map(|c| c <= 1).unwrap_or(false))
|
||||||
{
|
{
|
||||||
blog.delete(conn, searcher)?;
|
blog.delete(conn)?;
|
||||||
}
|
}
|
||||||
// delete the posts if they is the only author
|
// delete the posts if they is the only author
|
||||||
let all_their_posts_ids: Vec<i32> = post_authors::table
|
let all_their_posts_ids: Vec<i32> = post_authors::table
|
||||||
@@ -158,7 +158,7 @@ impl User {
|
|||||||
.unwrap_or(&0)
|
.unwrap_or(&0)
|
||||||
> &0;
|
> &0;
|
||||||
if !has_other_authors {
|
if !has_other_authors {
|
||||||
Post::get(conn, post_id)?.delete(conn, searcher)?;
|
Post::get(conn, post_id)?.delete(conn)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,29 +188,29 @@ impl User {
|
|||||||
users::table
|
users::table
|
||||||
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
.filter(users::instance_id.eq(Instance::get_local()?.id))
|
||||||
.count()
|
.count()
|
||||||
.get_result(conn)
|
.get_result(&*conn)
|
||||||
.map_err(Error::from)
|
.map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_by_fqn(c: &PlumeRocket, fqn: &str) -> Result<User> {
|
pub fn find_by_fqn(conn: &DbConn, fqn: &str) -> Result<User> {
|
||||||
let from_db = users::table
|
let from_db = users::table
|
||||||
.filter(users::fqn.eq(fqn))
|
.filter(users::fqn.eq(fqn))
|
||||||
.first(&*c.conn)
|
.first(&**conn)
|
||||||
.optional()?;
|
.optional()?;
|
||||||
if let Some(from_db) = from_db {
|
if let Some(from_db) = from_db {
|
||||||
Ok(from_db)
|
Ok(from_db)
|
||||||
} else {
|
} else {
|
||||||
User::fetch_from_webfinger(c, fqn)
|
User::fetch_from_webfinger(conn, fqn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_from_webfinger(c: &PlumeRocket, acct: &str) -> Result<User> {
|
fn fetch_from_webfinger(conn: &DbConn, acct: &str) -> Result<User> {
|
||||||
let link = resolve(acct.to_owned(), true)?
|
let link = resolve(acct.to_owned(), true)?
|
||||||
.links
|
.links
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
.find(|l| l.mime_type == Some(String::from("application/activity+json")))
|
||||||
.ok_or(Error::Webfinger)?;
|
.ok_or(Error::Webfinger)?;
|
||||||
User::from_id(c, link.href.as_ref()?, None).map_err(|(_, e)| e)
|
User::from_id(conn, link.href.as_ref()?, None, CONFIG.proxy()).map_err(|(_, e)| e)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_remote_interact_uri(acct: &str) -> Result<String> {
|
pub fn fetch_remote_interact_uri(acct: &str) -> Result<String> {
|
||||||
@@ -245,8 +245,8 @@ impl User {
|
|||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fetch_from_url(c: &PlumeRocket, url: &str) -> Result<User> {
|
pub fn fetch_from_url(conn: &DbConn, url: &str) -> Result<User> {
|
||||||
User::fetch(url).and_then(|json| User::from_activity(c, json))
|
User::fetch(url).and_then(|json| User::from_activity(conn, json))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refetch(&self, conn: &Connection) -> Result<()> {
|
pub fn refetch(&self, conn: &Connection) -> Result<()> {
|
||||||
@@ -293,6 +293,21 @@ impl User {
|
|||||||
bcrypt::hash(pass, 10).map_err(Error::from)
|
bcrypt::hash(pass, 10).map_err(Error::from)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn ldap_preconn(ldap_conn: &mut LdapConn) -> Result<()> {
|
||||||
|
let ldap = CONFIG.ldap.as_ref().unwrap();
|
||||||
|
|
||||||
|
if let Some((user, password)) = ldap.user.as_ref() {
|
||||||
|
let bind = ldap_conn
|
||||||
|
.simple_bind(user, password)
|
||||||
|
.map_err(|_| Error::NotFound)?;
|
||||||
|
|
||||||
|
if bind.success().is_err() {
|
||||||
|
return Err(Error::NotFound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn ldap_register(conn: &Connection, name: &str, password: &str) -> Result<User> {
|
fn ldap_register(conn: &Connection, name: &str, password: &str) -> Result<User> {
|
||||||
if CONFIG.ldap.is_none() {
|
if CONFIG.ldap.is_none() {
|
||||||
return Err(Error::NotFound);
|
return Err(Error::NotFound);
|
||||||
@@ -300,6 +315,9 @@ impl User {
|
|||||||
let ldap = CONFIG.ldap.as_ref().unwrap();
|
let ldap = CONFIG.ldap.as_ref().unwrap();
|
||||||
|
|
||||||
let mut ldap_conn = LdapConn::new(&ldap.addr).map_err(|_| Error::NotFound)?;
|
let mut ldap_conn = LdapConn::new(&ldap.addr).map_err(|_| Error::NotFound)?;
|
||||||
|
|
||||||
|
User::ldap_preconn(&mut ldap_conn)?;
|
||||||
|
|
||||||
let ldap_name = format!("{}={},{}", ldap.user_name_attr, name, ldap.base_dn);
|
let ldap_name = format!("{}={},{}", ldap.user_name_attr, name, ldap.base_dn);
|
||||||
let bind = ldap_conn
|
let bind = ldap_conn
|
||||||
.simple_bind(&ldap_name, password)
|
.simple_bind(&ldap_name, password)
|
||||||
@@ -346,6 +364,9 @@ impl User {
|
|||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
};
|
};
|
||||||
|
if User::ldap_preconn(&mut conn).is_err() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
let name = format!(
|
let name = format!(
|
||||||
"{}={},{}",
|
"{}={},{}",
|
||||||
ldap.user_name_attr, &self.username, ldap.base_dn
|
ldap.user_name_attr, &self.username, ldap.base_dn
|
||||||
@@ -832,11 +853,7 @@ impl User {
|
|||||||
|
|
||||||
pub fn webfinger(&self, conn: &Connection) -> Result<Webfinger> {
|
pub fn webfinger(&self, conn: &Connection) -> Result<Webfinger> {
|
||||||
Ok(Webfinger {
|
Ok(Webfinger {
|
||||||
subject: format!(
|
subject: format!("acct:{}", self.acct_authority(conn)?),
|
||||||
"acct:{}@{}",
|
|
||||||
self.username,
|
|
||||||
self.get_instance(conn)?.public_domain
|
|
||||||
),
|
|
||||||
aliases: vec![self.ap_url.clone()],
|
aliases: vec![self.ap_url.clone()],
|
||||||
links: vec![
|
links: vec![
|
||||||
Link {
|
Link {
|
||||||
@@ -874,6 +891,14 @@ impl User {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn acct_authority(&self, conn: &Connection) -> Result<String> {
|
||||||
|
Ok(format!(
|
||||||
|
"{}@{}",
|
||||||
|
self.username,
|
||||||
|
self.get_instance(conn)?.public_domain
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn set_avatar(&self, conn: &Connection, id: i32) -> Result<()> {
|
pub fn set_avatar(&self, conn: &Connection, id: i32) -> Result<()> {
|
||||||
diesel::update(self)
|
diesel::update(self)
|
||||||
.set(users::avatar_id.eq(id))
|
.set(users::avatar_id.eq(id))
|
||||||
@@ -893,6 +918,21 @@ impl User {
|
|||||||
self.fqn.clone()
|
self.fqn.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn remote_user_found(&self) {
|
||||||
|
tracing::trace!("{:?}", self);
|
||||||
|
self.publish_remote_user_found();
|
||||||
|
}
|
||||||
|
|
||||||
|
fn publish_remote_user_found(&self) {
|
||||||
|
USER_CHAN.tell(
|
||||||
|
Publish {
|
||||||
|
msg: RemoteUserFound(Arc::new(self.clone())),
|
||||||
|
topic: "user.remote_user_found".into(),
|
||||||
|
},
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'r> FromRequest<'a, 'r> for User {
|
impl<'a, 'r> FromRequest<'a, 'r> for User {
|
||||||
@@ -917,20 +957,20 @@ impl IntoId for User {
|
|||||||
|
|
||||||
impl Eq for User {}
|
impl Eq for User {}
|
||||||
|
|
||||||
impl FromId<PlumeRocket> for User {
|
impl FromId<DbConn> for User {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Object = CustomPerson;
|
type Object = CustomPerson;
|
||||||
|
|
||||||
fn from_db(c: &PlumeRocket, id: &str) -> Result<Self> {
|
fn from_db(conn: &DbConn, id: &str) -> Result<Self> {
|
||||||
Self::find_by_ap_url(&c.conn, id)
|
Self::find_by_ap_url(conn, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_activity(c: &PlumeRocket, acct: CustomPerson) -> Result<Self> {
|
fn from_activity(conn: &DbConn, acct: CustomPerson) -> Result<Self> {
|
||||||
let url = Url::parse(&acct.object.object_props.id_string()?)?;
|
let url = Url::parse(&acct.object.object_props.id_string()?)?;
|
||||||
let inst = url.host_str()?;
|
let inst = url.host_str()?;
|
||||||
let instance = Instance::find_by_domain(&c.conn, inst).or_else(|_| {
|
let instance = Instance::find_by_domain(conn, inst).or_else(|_| {
|
||||||
Instance::insert(
|
Instance::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewInstance {
|
NewInstance {
|
||||||
name: inst.to_owned(),
|
name: inst.to_owned(),
|
||||||
public_domain: inst.to_owned(),
|
public_domain: inst.to_owned(),
|
||||||
@@ -959,7 +999,7 @@ impl FromId<PlumeRocket> for User {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let user = User::insert(
|
let user = User::insert(
|
||||||
&c.conn,
|
conn,
|
||||||
NewUser {
|
NewUser {
|
||||||
display_name: acct
|
display_name: acct
|
||||||
.object
|
.object
|
||||||
@@ -1005,10 +1045,10 @@ impl FromId<PlumeRocket> for User {
|
|||||||
|
|
||||||
if let Ok(icon) = acct.object.object_props.icon_image() {
|
if let Ok(icon) = acct.object.object_props.icon_image() {
|
||||||
if let Ok(url) = icon.object_props.url_string() {
|
if let Ok(url) = icon.object_props.url_string() {
|
||||||
let avatar = Media::save_remote(&c.conn, url, &user);
|
let avatar = Media::save_remote(conn, url, &user);
|
||||||
|
|
||||||
if let Ok(avatar) = avatar {
|
if let Ok(avatar) = avatar {
|
||||||
user.set_avatar(&c.conn, avatar.id)?;
|
user.set_avatar(conn, avatar.id)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1017,7 +1057,7 @@ impl FromId<PlumeRocket> for User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsActor<&PlumeRocket> for User {
|
impl AsActor<&DbConn> for User {
|
||||||
fn get_inbox_url(&self) -> String {
|
fn get_inbox_url(&self) -> String {
|
||||||
self.inbox_url.clone()
|
self.inbox_url.clone()
|
||||||
}
|
}
|
||||||
@@ -1033,13 +1073,13 @@ impl AsActor<&PlumeRocket> for User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsObject<User, Delete, &PlumeRocket> for User {
|
impl AsObject<User, Delete, &DbConn> for User {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
type Output = ();
|
type Output = ();
|
||||||
|
|
||||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
fn activity(self, conn: &DbConn, actor: User, _id: &str) -> Result<()> {
|
||||||
if self.id == actor.id {
|
if self.id == actor.id {
|
||||||
self.delete(&c.conn, &c.searcher).map(|_| ())
|
self.delete(conn).map(|_| ())
|
||||||
} else {
|
} else {
|
||||||
Err(Error::Unauthorized)
|
Err(Error::Unauthorized)
|
||||||
}
|
}
|
||||||
@@ -1128,14 +1168,27 @@ impl NewUser {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum UserEvent {
|
||||||
|
RemoteUserFound(Arc<User>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<UserEvent> for Arc<User> {
|
||||||
|
fn from(event: UserEvent) -> Self {
|
||||||
|
use UserEvent::*;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
RemoteUserFound(user) => user,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) mod tests {
|
pub(crate) mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
config::CONFIG,
|
|
||||||
instance::{tests as instance_tests, Instance},
|
instance::{tests as instance_tests, Instance},
|
||||||
search::tests::get_searcher,
|
tests::db,
|
||||||
tests::{db, rockets},
|
|
||||||
Connection as Conn,
|
Connection as Conn,
|
||||||
};
|
};
|
||||||
use diesel::Connection;
|
use diesel::Connection;
|
||||||
@@ -1177,12 +1230,11 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn find_by() {
|
fn find_by() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
let test_user = NewUser::new_local(
|
let test_user = NewUser::new_local(
|
||||||
conn,
|
&conn,
|
||||||
"test".to_owned(),
|
"test".to_owned(),
|
||||||
"test user".to_owned(),
|
"test user".to_owned(),
|
||||||
Role::Normal,
|
Role::Normal,
|
||||||
@@ -1193,22 +1245,22 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
User::find_by_name(conn, "test", Instance::get_local().unwrap().id)
|
User::find_by_name(&conn, "test", Instance::get_local().unwrap().id)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.id
|
.id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
User::find_by_fqn(&r, &test_user.fqn).unwrap().id
|
User::find_by_fqn(&conn, &test_user.fqn).unwrap().id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
User::find_by_email(conn, "test@example.com").unwrap().id
|
User::find_by_email(&conn, "test@example.com").unwrap().id
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
test_user.id,
|
test_user.id,
|
||||||
User::find_by_ap_url(
|
User::find_by_ap_url(
|
||||||
conn,
|
&conn,
|
||||||
&format!(
|
&format!(
|
||||||
"https://{}/@/{}/",
|
"https://{}/@/{}/",
|
||||||
Instance::get_local().unwrap().public_domain,
|
Instance::get_local().unwrap().public_domain,
|
||||||
@@ -1226,13 +1278,11 @@ pub(crate) mod tests {
|
|||||||
fn delete() {
|
fn delete() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let inserted = fill_database(conn);
|
let inserted = fill_database(&conn);
|
||||||
|
|
||||||
assert!(User::get(conn, inserted[0].id).is_ok());
|
assert!(User::get(&conn, inserted[0].id).is_ok());
|
||||||
inserted[0]
|
inserted[0].delete(&conn).unwrap();
|
||||||
.delete(conn, &get_searcher(&CONFIG.search_tokenizers))
|
assert!(User::get(&conn, inserted[0].id).is_err());
|
||||||
.unwrap();
|
|
||||||
assert!(User::get(conn, inserted[0].id).is_err());
|
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1241,20 +1291,20 @@ pub(crate) mod tests {
|
|||||||
fn admin() {
|
fn admin() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let inserted = fill_database(conn);
|
let inserted = fill_database(&conn);
|
||||||
let local_inst = Instance::get_local().unwrap();
|
let local_inst = Instance::get_local().unwrap();
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
while local_inst.has_admin(conn).unwrap() {
|
while local_inst.has_admin(&conn).unwrap() {
|
||||||
assert!(i < 100); //prevent from looping indefinitelly
|
assert!(i < 100); //prevent from looping indefinitelly
|
||||||
local_inst
|
local_inst
|
||||||
.main_admin(conn)
|
.main_admin(&conn)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.set_role(conn, Role::Normal)
|
.set_role(&conn, Role::Normal)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
inserted[0].set_role(conn, Role::Admin).unwrap();
|
inserted[0].set_role(&conn, Role::Admin).unwrap();
|
||||||
assert_eq!(inserted[0].id, local_inst.main_admin(conn).unwrap().id);
|
assert_eq!(inserted[0].id, local_inst.main_admin(&conn).unwrap().id);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1263,9 +1313,9 @@ pub(crate) mod tests {
|
|||||||
fn auth() {
|
fn auth() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
let test_user = NewUser::new_local(
|
let test_user = NewUser::new_local(
|
||||||
conn,
|
&conn,
|
||||||
"test".to_owned(),
|
"test".to_owned(),
|
||||||
"test user".to_owned(),
|
"test user".to_owned(),
|
||||||
Role::Normal,
|
Role::Normal,
|
||||||
@@ -1276,10 +1326,10 @@ pub(crate) mod tests {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
User::login(conn, "test", "test_password").unwrap().id,
|
User::login(&conn, "test", "test_password").unwrap().id,
|
||||||
test_user.id
|
test_user.id
|
||||||
);
|
);
|
||||||
assert!(User::login(conn, "test", "other_password").is_err());
|
assert!(User::login(&conn, "test", "other_password").is_err());
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1288,26 +1338,26 @@ pub(crate) mod tests {
|
|||||||
fn get_local_page() {
|
fn get_local_page() {
|
||||||
let conn = &db();
|
let conn = &db();
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
fill_database(conn);
|
fill_database(&conn);
|
||||||
|
|
||||||
let page = User::get_local_page(conn, (0, 2)).unwrap();
|
let page = User::get_local_page(&conn, (0, 2)).unwrap();
|
||||||
assert_eq!(page.len(), 2);
|
assert_eq!(page.len(), 2);
|
||||||
assert!(page[0].username <= page[1].username);
|
assert!(page[0].username <= page[1].username);
|
||||||
|
|
||||||
let mut last_username = User::get_local_page(conn, (0, 1)).unwrap()[0]
|
let mut last_username = User::get_local_page(&conn, (0, 1)).unwrap()[0]
|
||||||
.username
|
.username
|
||||||
.clone();
|
.clone();
|
||||||
for i in 1..User::count_local(conn).unwrap() as i32 {
|
for i in 1..User::count_local(&conn).unwrap() as i32 {
|
||||||
let page = User::get_local_page(conn, (i, i + 1)).unwrap();
|
let page = User::get_local_page(&conn, (i, i + 1)).unwrap();
|
||||||
assert_eq!(page.len(), 1);
|
assert_eq!(page.len(), 1);
|
||||||
assert!(last_username <= page[0].username);
|
assert!(last_username <= page[0].username);
|
||||||
last_username = page[0].username.clone();
|
last_username = page[0].username.clone();
|
||||||
}
|
}
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
User::get_local_page(conn, (0, User::count_local(conn).unwrap() as i32 + 10))
|
User::get_local_page(&conn, (0, User::count_local(&conn).unwrap() as i32 + 10))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.len() as i64,
|
.len() as i64,
|
||||||
User::count_local(conn).unwrap()
|
User::count_local(&conn).unwrap()
|
||||||
);
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
@@ -1315,14 +1365,13 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn self_federation() {
|
fn self_federation() {
|
||||||
let r = rockets();
|
let conn = db();
|
||||||
let conn = &*r.conn;
|
|
||||||
conn.test_transaction::<_, (), _>(|| {
|
conn.test_transaction::<_, (), _>(|| {
|
||||||
let users = fill_database(conn);
|
let users = fill_database(&conn);
|
||||||
|
|
||||||
let ap_repr = users[0].to_activity(conn).unwrap();
|
let ap_repr = users[0].to_activity(&conn).unwrap();
|
||||||
users[0].delete(conn, &*r.searcher).unwrap();
|
users[0].delete(&conn).unwrap();
|
||||||
let user = User::from_activity(&r, ap_repr).unwrap();
|
let user = User::from_activity(&conn, ap_repr).unwrap();
|
||||||
|
|
||||||
assert_eq!(user.username, users[0].username);
|
assert_eq!(user.username, users[0].username);
|
||||||
assert_eq!(user.display_name, users[0].display_name);
|
assert_eq!(user.display_name, users[0].display_name);
|
||||||
@@ -1333,7 +1382,7 @@ pub(crate) mod tests {
|
|||||||
assert_eq!(user.public_key, users[0].public_key);
|
assert_eq!(user.public_key, users[0].public_key);
|
||||||
assert_eq!(user.shared_inbox_url, users[0].shared_inbox_url);
|
assert_eq!(user.shared_inbox_url, users[0].shared_inbox_url);
|
||||||
assert_eq!(user.followers_endpoint, users[0].followers_endpoint);
|
assert_eq!(user.followers_endpoint, users[0].followers_endpoint);
|
||||||
assert_eq!(user.avatar_url(conn), users[0].avatar_url(conn));
|
assert_eq!(user.avatar_url(&conn), users[0].avatar_url(&conn));
|
||||||
assert_eq!(user.fqn, users[0].fqn);
|
assert_eq!(user.fqn, users[0].fqn);
|
||||||
assert_eq!(user.summary_html, users[0].summary_html);
|
assert_eq!(user.summary_html, users[0].summary_html);
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -10,12 +10,17 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=6; plural=(n == 0) ? 0 : ((n == 1) ? 1 : ((n == 2) ? 2 : ((n == 3) ? 3 : ((n == 6) ? 4 : 5))));\n"
|
"Plural-Forms: nplurals=6; plural=(n == 0) ? 0 : ((n == 1) ? 1 : ((n == 2) ? "
|
||||||
|
"2 : ((n == 3) ? 3 : ((n == 6) ? 4 : 5))));\n"
|
||||||
"X-Generator: crowdin.com\n"
|
"X-Generator: crowdin.com\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Language: cy\n"
|
"X-Crowdin-Language: cy\n"
|
||||||
"X-Crowdin-File: /master/po/plume-front/plume-front.pot\n"
|
"X-Crowdin-File: /master/po/plume-front/plume-front.pot\n"
|
||||||
|
|
||||||
|
# plume-front/src/editor.rs:189
|
||||||
|
msgid "Do you want to load the local autosave last edited at {}?"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:114
|
# plume-front/src/editor.rs:114
|
||||||
msgid "Open the rich text editor"
|
msgid "Open the rich text editor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -24,8 +29,8 @@ msgstr ""
|
|||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:147
|
# plume-front/src/editor.rs:319
|
||||||
msgid "Subtitle or summary"
|
msgid "Subtitle, or summary"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:154
|
# plume-front/src/editor.rs:154
|
||||||
@@ -55,4 +60,3 @@ msgstr ""
|
|||||||
# plume-front/src/editor.rs:259
|
# plume-front/src/editor.rs:259
|
||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -12,46 +12,46 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n"
|
||||||
|
|
||||||
# plume-front/src/editor.rs:189
|
# plume-front/src/editor.rs:188
|
||||||
msgid "Do you want to load the local autosave last edited at {}?"
|
msgid "Do you want to load the local autosave last edited at {}?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:282
|
# plume-front/src/editor.rs:281
|
||||||
msgid "Open the rich text editor"
|
msgid "Open the rich text editor"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:315
|
# plume-front/src/editor.rs:314
|
||||||
msgid "Title"
|
msgid "Title"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:319
|
# plume-front/src/editor.rs:318
|
||||||
msgid "Subtitle, or summary"
|
msgid "Subtitle, or summary"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:326
|
# plume-front/src/editor.rs:325
|
||||||
msgid "Write your article here. Markdown is supported."
|
msgid "Write your article here. Markdown is supported."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:337
|
# plume-front/src/editor.rs:336
|
||||||
msgid "Around {} characters left"
|
msgid "Around {} characters left"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:414
|
# plume-front/src/editor.rs:413
|
||||||
msgid "Tags"
|
msgid "Tags"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:415
|
# plume-front/src/editor.rs:414
|
||||||
msgid "License"
|
msgid "License"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:418
|
# plume-front/src/editor.rs:417
|
||||||
msgid "Cover"
|
msgid "Cover"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:438
|
# plume-front/src/editor.rs:437
|
||||||
msgid "This is a draft"
|
msgid "This is a draft"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# plume-front/src/editor.rs:445
|
# plume-front/src/editor.rs:444
|
||||||
msgid "Publish"
|
msgid "Publish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+76
-27
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
|
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 "
|
||||||
|
"&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: ar\n"
|
"X-Crowdin-Language: ar\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "تم حذف مقالك."
|
msgstr "تم حذف مقالك."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr "لم يتم العثور على المقال الذي تحاول حذفه. ربما سبق حذفه؟"
|
msgstr "لم يتم العثور على المقال الذي تحاول حذفه. ربما سبق حذفه؟"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr "تعذر العثور عن معلومات حسابك. المرجو التحقق من صحة إسم المستخدم."
|
msgstr "تعذر العثور عن معلومات حسابك. المرجو التحقق من صحة إسم المستخدم."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "التسجيلات مُغلقة على مثيل الخادم هذ."
|
msgstr "التسجيلات مُغلقة على مثيل الخادم هذ."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr "لقد تم إنشاء حسابك. ما عليك إلّا الولوج الآن للتمكّن مِن استعماله."
|
msgstr "لقد تم إنشاء حسابك. ما عليك إلّا الولوج الآن للتمكّن مِن استعماله."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,8 +448,11 @@ msgstr "كلمة السر"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "المعذرة، لاكن التسجيل مغلق في هذا المثيل بالدات. يمكنك إجاد مثيل آخر للتسجيل."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"المعذرة، لاكن التسجيل مغلق في هذا المثيل بالدات. يمكنك إجاد مثيل آخر للتسجيل."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0} اشتراكات"
|
msgstr "{0} اشتراكات"
|
||||||
@@ -471,8 +481,10 @@ msgstr "تعديل حسابك"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "ملفك الشخصي"
|
msgstr "ملفك الشخصي"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "لتغير الصورة التشخيصية قم أولا برفعها إلى الألبوم ثم قم بتعينها من هنالك."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"لتغير الصورة التشخيصية قم أولا برفعها إلى الألبوم ثم قم بتعينها من هنالك."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "تحميل صورة رمزية"
|
msgstr "تحميل صورة رمزية"
|
||||||
@@ -543,8 +555,13 @@ msgstr "نعتذر عن الإزعاج. إن كنت تضن أن هذه مشكل
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "الرمز المميز CSRF غير صالح"
|
msgstr "الرمز المميز CSRF غير صالح"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "هناكخطأم ما في رمز CSRF. تحقق أن الكوكيز مفعل في متصفحك وأعد تحميل الصفحة. إذا واجهتهذا الخطأ منجديد يرجى التبليغ."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"هناكخطأم ما في رمز CSRF. تحقق أن الكوكيز مفعل في متصفحك وأعد تحميل الصفحة. "
|
||||||
|
"إذا واجهتهذا الخطأ منجديد يرجى التبليغ."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "ليست لديك التصريحات اللازمة للقيام بذلك."
|
msgstr "ليست لديك التصريحات اللازمة للقيام بذلك."
|
||||||
@@ -627,13 +644,21 @@ msgstr "الرخصة الافتراضية للمقال"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "احفظ هذه الإعدادات"
|
msgstr "احفظ هذه الإعدادات"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr "إذا كنت تصفح هذا الموقع كزائر ، لا يتم تجميع أي بيانات عنك."
|
msgstr "إذا كنت تصفح هذا الموقع كزائر ، لا يتم تجميع أي بيانات عنك."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +667,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +679,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +761,11 @@ msgstr "العنوان الثانوي"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "المحتوى"
|
msgstr "المحتوى"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "يكنك رفع الوسائط للألبوم ومن ثم نسخ شفرة الماركداون في مقالاتك لإدراجها."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"يكنك رفع الوسائط للألبوم ومن ثم نسخ شفرة الماركداون في مقالاتك لإدراجها."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "تحميل وسائط"
|
msgstr "تحميل وسائط"
|
||||||
@@ -795,8 +830,12 @@ msgstr "لم أعد أرغب في دعم هذا"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "رقّي"
|
msgstr "رقّي"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}قم بتسجيل الدخول{1} أو {2}استخدم حسابك على الفديفرس{3} إن كنت ترغب في التفاعل مع هذا المقال"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}قم بتسجيل الدخول{1} أو {2}استخدم حسابك على الفديفرس{3} إن كنت ترغب في "
|
||||||
|
"التفاعل مع هذا المقال"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "التعليقات"
|
msgstr "التعليقات"
|
||||||
@@ -852,8 +891,12 @@ msgstr "تحديث الكلمة السرية"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "تحقق من علبة الوارد الخاصة بك!"
|
msgstr "تحقق من علبة الوارد الخاصة بك!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "لقد أرسلنا رسالة للعنوان الذي توصلنا به من طرفك تضمنرابط لإعادت تحديد كلمة المرور."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"لقد أرسلنا رسالة للعنوان الذي توصلنا به من طرفك تضمنرابط لإعادت تحديد كلمة "
|
||||||
|
"المرور."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "أرسل رابط إعادة تعيين الكلمة السرية"
|
msgstr "أرسل رابط إعادة تعيين الكلمة السرية"
|
||||||
@@ -861,7 +904,9 @@ msgstr "أرسل رابط إعادة تعيين الكلمة السرية"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -876,7 +921,8 @@ msgstr "انشاء مدونة"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "تعديل \"{}\""
|
msgstr "تعديل \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr "يمكن رفع الصور إلى ألبومك من أجل إستعمالها كأيقونة المدونة أو الشعار."
|
msgstr "يمكن رفع الصور إلى ألبومك من أجل إستعمالها كأيقونة المدونة أو الشعار."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -942,8 +988,12 @@ msgstr "بلوم محرك لامركزي للمدونات."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "يمكن للمحررين أن يديرو العديد من المدونات كل واحدة كموقع منفرد."
|
msgstr "يمكن للمحررين أن يديرو العديد من المدونات كل واحدة كموقع منفرد."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "ستكون المقالات معروضة على مواقع بلومالأخرى حيث يمكنكم التفاعل معها مباشرة عبر أية منصة أخرى مثل ماستدون."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"ستكون المقالات معروضة على مواقع بلومالأخرى حيث يمكنكم التفاعل معها مباشرة "
|
||||||
|
"عبر أية منصة أخرى مثل ماستدون."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "إقرأ القواعد بالتفصيل"
|
msgstr "إقرأ القواعد بالتفصيل"
|
||||||
@@ -1022,4 +1072,3 @@ msgstr "نشرتحت هذا الترخيص"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "رخصة المقال"
|
msgstr "رخصة المقال"
|
||||||
|
|
||||||
|
|||||||
+133
-44
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Статията е изтрита."
|
msgstr "Статията е изтрита."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Изглежда, че статията, която се опитвате да изтриете не съществува. Може би вече я няма?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Изглежда, че статията, която се опитвате да изтриете не съществува. Може би "
|
||||||
|
"вече я няма?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Не можа да се получи достатъчно информация за профила ви. Моля, уверете се, че потребителското ви име е правилно."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Не можа да се получи достатъчно информация за профила ви. Моля, уверете се, "
|
||||||
|
"че потребителското ви име е правилно."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -247,7 +255,9 @@ msgstr "Вашата парола бе успешно възстановена."
|
|||||||
|
|
||||||
# src/routes/user.rs:141
|
# src/routes/user.rs:141
|
||||||
msgid "To access your dashboard, you need to be logged in"
|
msgid "To access your dashboard, you need to be logged in"
|
||||||
msgstr "За да получите достъп до таблото си за управление, трябва да сте влезли в профила си"
|
msgstr ""
|
||||||
|
"За да получите достъп до таблото си за управление, трябва да сте влезли в "
|
||||||
|
"профила си"
|
||||||
|
|
||||||
# src/routes/user.rs:163
|
# src/routes/user.rs:163
|
||||||
msgid "You are no longer following {}."
|
msgid "You are no longer following {}."
|
||||||
@@ -282,8 +292,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Регистрациите са затворени в тази инстанция."
|
msgstr "Регистрациите са затворени в тази инстанция."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Вашият акаунт беше създаден. Сега просто трябва да влезете за да можете да го използвате."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Вашият акаунт беше създаден. Сега просто трябва да влезете за да можете да "
|
||||||
|
"го използвате."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Качи медия"
|
msgstr "Качи медия"
|
||||||
@@ -441,8 +455,12 @@ msgstr "Парола"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Потвърждение на парола"
|
msgstr "Потвърждение на парола"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Извиняваме се, но регистрациите са затворени за тази конкретна инстанция. Можете обаче да намерите друга."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Извиняваме се, но регистрациите са затворени за тази конкретна инстанция. "
|
||||||
|
"Можете обаче да намерите друга."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0} абонаменти"
|
msgstr "{0} абонаменти"
|
||||||
@@ -454,7 +472,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Вашият Блог"
|
msgstr "Вашият Блог"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Все още нямате блог. Създайте свой собствен или поискайте да се присъедините към някой друг."
|
msgstr ""
|
||||||
|
"Все още нямате блог. Създайте свой собствен или поискайте да се присъедините "
|
||||||
|
"към някой друг."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Започнете нов блог"
|
msgstr "Започнете нов блог"
|
||||||
@@ -471,8 +491,10 @@ msgstr "Редактирайте профила си"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Вашият профил"
|
msgstr "Вашият профил"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "За да промените аватара си, качете го в галерията и след това го изберете."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"За да промените аватара си, качете го в галерията и след това го изберете."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Качете аватар"
|
msgstr "Качете аватар"
|
||||||
@@ -502,13 +524,17 @@ msgid "Danger zone"
|
|||||||
msgstr "Опасна зона"
|
msgstr "Опасна зона"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr "Бъдете много внимателни, всяко действие предприето тук не може да бъде отменено."
|
msgstr ""
|
||||||
|
"Бъдете много внимателни, всяко действие предприето тук не може да бъде "
|
||||||
|
"отменено."
|
||||||
|
|
||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Изтриване на вашият профил"
|
msgstr "Изтриване на вашият профил"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "За съжаление, като администратор не можете да напуснете своята собствена инстанция."
|
msgstr ""
|
||||||
|
"За съжаление, като администратор не можете да напуснете своята собствена "
|
||||||
|
"инстанция."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Последни статии"
|
msgstr "Последни статии"
|
||||||
@@ -538,13 +564,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Възникна грешка от ваша страна."
|
msgstr "Възникна грешка от ваша страна."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Извиняваме се за това. Ако смятате, че това е грешка, моля докладвайте я."
|
msgstr ""
|
||||||
|
"Извиняваме се за това. Ако смятате, че това е грешка, моля докладвайте я."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Невалиден CSRF token (маркер)"
|
msgstr "Невалиден CSRF token (маркер)"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Нещо не е наред с вашия CSRF token (маркер). Уверете се, че бисквитките са активирани в браузъра и опитайте да заредите отново тази страница. Ако продължите да виждате това съобщение за грешка, моля, подайте сигнал за това."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Нещо не е наред с вашия CSRF token (маркер). Уверете се, че бисквитките са "
|
||||||
|
"активирани в браузъра и опитайте да заредите отново тази страница. Ако "
|
||||||
|
"продължите да виждате това съобщение за грешка, моля, подайте сигнал за това."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Не сте упълномощени."
|
msgstr "Не сте упълномощени."
|
||||||
@@ -627,14 +660,29 @@ msgstr "Лиценз по подразбиране"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Запаметете тези настройки"
|
msgstr "Запаметете тези настройки"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr "Ако разглеждате този сайт като посетител, не се събират данни за вас."
|
msgstr "Ако разглеждате този сайт като посетител, не се събират данни за вас."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Като регистриран потребител трябва да предоставите потребителско име (което не е задължително да е вашето истинско име), вашия функционален имейл адрес и парола за да можете да влезете, да напишете статии и коментари. Съдържанието, което изпращате се съхранява докато не го изтриете."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Като регистриран потребител трябва да предоставите потребителско име (което "
|
||||||
|
"не е задължително да е вашето истинско име), вашия функционален имейл адрес "
|
||||||
|
"и парола за да можете да влезете, да напишете статии и коментари. "
|
||||||
|
"Съдържанието, което изпращате се съхранява докато не го изтриете."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Когато влезете в системата, съхраняваме две „бисквитки“, една за отваряне на сесията, а втората за да попречи на други хора да действат от ваше име. Ние не съхраняваме никакви други бисквитки."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Когато влезете в системата, съхраняваме две „бисквитки“, една за отваряне на "
|
||||||
|
"сесията, а втората за да попречи на други хора да действат от ваше име. Ние "
|
||||||
|
"не съхраняваме никакви други бисквитки."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Имейли в череният списък"
|
msgstr "Имейли в череният списък"
|
||||||
@@ -642,8 +690,14 @@ msgstr "Имейли в череният списък"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Имейл адрес"
|
msgstr "Имейл адрес"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "Имейл адресът, който искате да блокирате. За да блокирате домейните можете да използвате широкообхватен синтаксис, например '*@example.com' блокира всички адреси от example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"Имейл адресът, който искате да блокирате. За да блокирате домейните можете "
|
||||||
|
"да използвате широкообхватен синтаксис, например '*@example.com' блокира "
|
||||||
|
"всички адреси от example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Бележка"
|
msgstr "Бележка"
|
||||||
@@ -651,14 +705,22 @@ msgstr "Бележка"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Уведомяване на потребителя?"
|
msgstr "Уведомяване на потребителя?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "По желание, показва съобщение на потребителя, когато той се опита да създаде акаунт с този адрес"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"По желание, показва съобщение на потребителя, когато той се опита да създаде "
|
||||||
|
"акаунт с този адрес"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Известие за блокиране от списък"
|
msgstr "Известие за блокиране от списък"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Съобщението, което трябва да се покаже, когато потребителят се опита да създаде акаунт с този имейл адрес"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Съобщението, което трябва да се покаже, когато потребителят се опита да "
|
||||||
|
"създаде акаунт с този имейл адрес"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Добавяне на адрес в черният списък"
|
msgstr "Добавяне на адрес в черният списък"
|
||||||
@@ -729,8 +791,12 @@ msgstr "Подзаглавие"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Съдържание"
|
msgstr "Съдържание"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Можете да качвате мултимедия в галерията си, а след това да копирате Markdown кода в статиите си за да я вмъкнете."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Можете да качвате мултимедия в галерията си, а след това да копирате "
|
||||||
|
"Markdown кода в статиите си за да я вмъкнете."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Качете медия"
|
msgstr "Качете медия"
|
||||||
@@ -787,8 +853,12 @@ msgstr "Не искам повече да го подсилвам"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Подсилване"
|
msgstr "Подсилване"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Влезте {1}или {2}използвайте акаунта си в Fediverse{3}, за да взаимодействате с тази статия"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Влезте {1}или {2}използвайте акаунта си в Fediverse{3}, за да "
|
||||||
|
"взаимодействате с тази статия"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Коментари"
|
msgstr "Коментари"
|
||||||
@@ -806,7 +876,8 @@ msgid "Are you sure?"
|
|||||||
msgstr "Сигурен ли си?"
|
msgstr "Сигурен ли си?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Тази статия все още е проект. Само вие и другите автори можете да я видите."
|
msgstr ""
|
||||||
|
"Тази статия все още е проект. Само вие и другите автори можете да я видите."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Само вие и другите автори можете да редактирате тази статия."
|
msgstr "Само вие и другите автори можете да редактирате тази статия."
|
||||||
@@ -844,8 +915,12 @@ msgstr "Обнови паролата"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Проверете си пощата!"
|
msgstr "Проверете си пощата!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Изпратихме емайл с връзка за възстановяване на паролата ви, на адреса който ни дадохте."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Изпратихме емайл с връзка за възстановяване на паролата ви, на адреса който "
|
||||||
|
"ни дадохте."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Изпращане на връзка за възстановяване на парола"
|
msgstr "Изпращане на връзка за възстановяване на парола"
|
||||||
@@ -853,8 +928,12 @@ msgstr "Изпращане на връзка за възстановяване
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Този токен е изтекъл"
|
msgstr "Този токен е изтекъл"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Моля, стартирайте процеса отново като щракнете <a href=\"/password-reset\">тук</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Моля, стартирайте процеса отново като щракнете <a href=\"/password-reset"
|
||||||
|
"\">тук</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Нов блог"
|
msgstr "Нов блог"
|
||||||
@@ -868,8 +947,11 @@ msgstr "Създайте блог"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "редактирам \"{}\""
|
msgstr "редактирам \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Можете да качвате изображения в галерията си и да ги използвате като икони на блога или банери."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Можете да качвате изображения в галерията си и да ги използвате като икони "
|
||||||
|
"на блога или банери."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Качване на изображения"
|
msgstr "Качване на изображения"
|
||||||
@@ -887,7 +969,9 @@ msgid "Update blog"
|
|||||||
msgstr "Актуализация блог"
|
msgstr "Актуализация блог"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Бъдете много внимателни, всяко действие, предприето тук не може да бъде отменено."
|
msgstr ""
|
||||||
|
"Бъдете много внимателни, всяко действие, предприето тук не може да бъде "
|
||||||
|
"отменено."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "Сигурни ли сте, че искате да изтриете окончателно този блог?"
|
msgstr "Сигурни ли сте, че искате да изтриете окончателно този блог?"
|
||||||
@@ -928,10 +1012,16 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Pluma е децентрализиран двигател за блогове."
|
msgstr "Pluma е децентрализиран двигател за блогове."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Авторите могат да управляват множество блогове, всеки като свой уникален уебсайт."
|
msgstr ""
|
||||||
|
"Авторите могат да управляват множество блогове, всеки като свой уникален "
|
||||||
|
"уебсайт."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Статиите се виждат и на други Plume инстанции като можете да взаимодействате с тях директно и от други платформи като Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Статиите се виждат и на други Plume инстанции като можете да взаимодействате "
|
||||||
|
"с тях директно и от други платформи като Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Прочетете подробните правила"
|
msgstr "Прочетете подробните правила"
|
||||||
@@ -1010,4 +1100,3 @@ msgstr "Публикувано под този лиценз"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Лиценз на статията"
|
msgstr "Лиценз на статията"
|
||||||
|
|
||||||
|
|||||||
+125
-42
@@ -214,12 +214,19 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "S’ha suprimit el vostre article."
|
msgstr "S’ha suprimit el vostre article."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Sembla que l'article que intentes esborrar no existeix. Potser ja no hi és?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Sembla que l'article que intentes esborrar no existeix. Potser ja no hi és?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "No s'ha pogut obtenir informació sobre el teu compte. Si us plau, assegura't que el teu nom d'usuari és correcte."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"No s'ha pogut obtenir informació sobre el teu compte. Si us plau, assegura't "
|
||||||
|
"que el teu nom d'usuari és correcte."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +289,11 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "El registre d'aquesta instància és tancat."
|
msgstr "El registre d'aquesta instància és tancat."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "S'ha creat el teu compte. Ara cal iniciar sessió per a començar a usar-lo."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"S'ha creat el teu compte. Ara cal iniciar sessió per a començar a usar-lo."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Carregar Mèdia"
|
msgstr "Carregar Mèdia"
|
||||||
@@ -292,7 +302,9 @@ msgid "Description"
|
|||||||
msgstr "Descripció"
|
msgstr "Descripció"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Molt útil per a persones amb deficiències visuals aixó com informació sobre llicències"
|
msgstr ""
|
||||||
|
"Molt útil per a persones amb deficiències visuals aixó com informació sobre "
|
||||||
|
"llicències"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Advertència sobre el contingut"
|
msgstr "Advertència sobre el contingut"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Contrasenya"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Confirmació de la contrasenya"
|
msgstr "Confirmació de la contrasenya"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Disculpa, el registre d'aquesta instància és tancat. Pots trobar-ne un altre diferent."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Disculpa, el registre d'aquesta instància és tancat. Pots trobar-ne un altre "
|
||||||
|
"diferent."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Subscripcions de {0}"
|
msgstr "Subscripcions de {0}"
|
||||||
@@ -454,7 +470,8 @@ msgid "Your Blogs"
|
|||||||
msgstr "Els vostres blogs"
|
msgstr "Els vostres blogs"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Encara no tens cap bloc. Crea el teu propi o pregunta per a unir-te a un."
|
msgstr ""
|
||||||
|
"Encara no tens cap bloc. Crea el teu propi o pregunta per a unir-te a un."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Inicia un nou bloc"
|
msgstr "Inicia un nou bloc"
|
||||||
@@ -471,8 +488,11 @@ msgstr "Edita el teu compte"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "El vostre perfil"
|
msgstr "El vostre perfil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Per a canviar el teu avatar, puja'l a la teva galeria i desprès selecciona'l allà."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Per a canviar el teu avatar, puja'l a la teva galeria i desprès selecciona'l "
|
||||||
|
"allà."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Puja un avatar"
|
msgstr "Puja un avatar"
|
||||||
@@ -508,7 +528,8 @@ msgid "Delete your account"
|
|||||||
msgstr "Elimina el teu compte"
|
msgstr "Elimina el teu compte"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Ho sentim però com a admin, no pots abandonar la teva pròpia instància."
|
msgstr ""
|
||||||
|
"Ho sentim però com a admin, no pots abandonar la teva pròpia instància."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Darrers articles"
|
msgstr "Darrers articles"
|
||||||
@@ -543,8 +564,14 @@ msgstr "Disculpa-n's. Si creus que això és un error, si us plau reporta-ho."
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Token CSRF invalid"
|
msgstr "Token CSRF invalid"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Alguna cosa no és correcte amb el teu token CSRF. Assegura't que no bloqueges les galetes en el teu navegador i prova refrescant la pàgina. Si continues veient aquest missatge d'error, si us plau informa-ho."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Alguna cosa no és correcte amb el teu token CSRF. Assegura't que no "
|
||||||
|
"bloqueges les galetes en el teu navegador i prova refrescant la pàgina. Si "
|
||||||
|
"continues veient aquest missatge d'error, si us plau informa-ho."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "No estàs autoritzat."
|
msgstr "No estàs autoritzat."
|
||||||
@@ -627,14 +654,31 @@ msgstr "Llicència per defecte dels articles"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Desa aquests paràmetres"
|
msgstr "Desa aquests paràmetres"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Si estàs navegant aquest lloc com a visitant cap dada sobre tu serà recollida."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Si estàs navegant aquest lloc com a visitant cap dada sobre tu serà "
|
||||||
|
"recollida."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Com a usuari registrat has de proporcionar un nom d'usuari (que no ha de ser el teu nom real), una adreça de correu funcional i una contrasenya per a poder ser capaç d'iniciar sessió, escriure articles i comentar-los. El contingut que enviïs es guarda fins que tu l'esborris."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Com a usuari registrat has de proporcionar un nom d'usuari (que no ha de ser "
|
||||||
|
"el teu nom real), una adreça de correu funcional i una contrasenya per a "
|
||||||
|
"poder ser capaç d'iniciar sessió, escriure articles i comentar-los. El "
|
||||||
|
"contingut que enviïs es guarda fins que tu l'esborris."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Quan inicies sessió guardem dues galetes, una per a mantenir la sessió oberta i l l'altre per a evitar que d'altres persones actuïn en el teu nom. No guardem cap altre galeta."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Quan inicies sessió guardem dues galetes, una per a mantenir la sessió "
|
||||||
|
"oberta i l l'altre per a evitar que d'altres persones actuïn en el teu nom. "
|
||||||
|
"No guardem cap altre galeta."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Llista de bloqueig d'adreces de correu"
|
msgstr "Llista de bloqueig d'adreces de correu"
|
||||||
@@ -642,8 +686,14 @@ msgstr "Llista de bloqueig d'adreces de correu"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Adreça de correu electrònic"
|
msgstr "Adreça de correu electrònic"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "L'adreça de correu electrònic que desitges bloquejar. Per a bloquejar dominis pots usar la sintaxi global, per exemple '*@exemple.com' bloqueja totes les adreces de exemple.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"L'adreça de correu electrònic que desitges bloquejar. Per a bloquejar "
|
||||||
|
"dominis pots usar la sintaxi global, per exemple '*@exemple.com' bloqueja "
|
||||||
|
"totes les adreces de exemple.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Nota"
|
msgstr "Nota"
|
||||||
@@ -651,14 +701,22 @@ msgstr "Nota"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Notificar l'usuari?"
|
msgstr "Notificar l'usuari?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Opcional, mostra un missatge al usuari quan intenta crear un compte amb aquesta adreça"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Opcional, mostra un missatge al usuari quan intenta crear un compte amb "
|
||||||
|
"aquesta adreça"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Notificacions de la llista de bloqueig"
|
msgstr "Notificacions de la llista de bloqueig"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "El missatge per a ser mostrat quan l'usuari intenta crear un compte amb aquesta adreça de correu"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"El missatge per a ser mostrat quan l'usuari intenta crear un compte amb "
|
||||||
|
"aquesta adreça de correu"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Afegir adreça a la llista de bloquejos"
|
msgstr "Afegir adreça a la llista de bloquejos"
|
||||||
@@ -729,8 +787,12 @@ msgstr "Subtítol"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Contingut"
|
msgstr "Contingut"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Pots pujar Mèdia a la teva galeria i desprès copiar el codi Markdown dels teus articles per a inserir-los."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Pots pujar Mèdia a la teva galeria i desprès copiar el codi Markdown dels "
|
||||||
|
"teus articles per a inserir-los."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Pujar Mèdia"
|
msgstr "Pujar Mèdia"
|
||||||
@@ -787,8 +849,12 @@ msgstr "Ja no vull impulsar més això"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Impuls"
|
msgstr "Impuls"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Inicia sessió{1}, o {2}usa el teu compte del Fedivers{3} per a interactuar amb aquest article"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Inicia sessió{1}, o {2}usa el teu compte del Fedivers{3} per a "
|
||||||
|
"interactuar amb aquest article"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Comentaris"
|
msgstr "Comentaris"
|
||||||
@@ -806,7 +872,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "N’esteu segur?"
|
msgstr "N’esteu segur?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Aquest article és encara un esborrany. Només tu i altres autors podeu veure'l."
|
msgstr ""
|
||||||
|
"Aquest article és encara un esborrany. Només tu i altres autors podeu "
|
||||||
|
"veure'l."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Només tu i altres autors podeu editar aquest article."
|
msgstr "Només tu i altres autors podeu editar aquest article."
|
||||||
@@ -844,8 +912,12 @@ msgstr "Actualitza la contrasenya"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Reviseu la vostra safata d’entrada."
|
msgstr "Reviseu la vostra safata d’entrada."
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Hem enviat un correu a l'adreça que ens vas donar, amb un enllaç per a reiniciar la teva contrasenya."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Hem enviat un correu a l'adreça que ens vas donar, amb un enllaç per a "
|
||||||
|
"reiniciar la teva contrasenya."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Envia l'enllaç per a reiniciar la contrasenya"
|
msgstr "Envia l'enllaç per a reiniciar la contrasenya"
|
||||||
@@ -853,8 +925,11 @@ msgstr "Envia l'enllaç per a reiniciar la contrasenya"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Aquest token ha caducat"
|
msgstr "Aquest token ha caducat"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Si us plau inicia el procés clicant <a href=\"/password-reset\">aquí</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Si us plau inicia el procés clicant <a href=\"/password-reset\">aquí</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Blog nou"
|
msgstr "Blog nou"
|
||||||
@@ -868,8 +943,11 @@ msgstr "Crea un blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Edita «{}»"
|
msgstr "Edita «{}»"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Pots pujar imatges a la teva galeria per a usar-les com a icones o capçaleres del bloc."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Pots pujar imatges a la teva galeria per a usar-les com a icones o "
|
||||||
|
"capçaleres del bloc."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Pujar imatges"
|
msgstr "Pujar imatges"
|
||||||
@@ -928,10 +1006,16 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Plume és un motor de blocs descentralitzats."
|
msgstr "Plume és un motor de blocs descentralitzats."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Els autors poden gestionar diversos blocs, cadascun amb la seva pròpia pàgina."
|
msgstr ""
|
||||||
|
"Els autors poden gestionar diversos blocs, cadascun amb la seva pròpia "
|
||||||
|
"pàgina."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Els articles son visibles en altres instàncies Plume i pots interactuar directament amb ells des d'altres plataformes com ara Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Els articles son visibles en altres instàncies Plume i pots interactuar "
|
||||||
|
"directament amb ells des d'altres plataformes com ara Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Llegeix les normes detallades"
|
msgstr "Llegeix les normes detallades"
|
||||||
@@ -1010,4 +1094,3 @@ msgstr "Publicat segons aquesta llicència"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Llicència del article"
|
msgstr "Llicència del article"
|
||||||
|
|
||||||
|
|||||||
+112
-38
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Váš článek byl smazán."
|
msgstr "Váš článek byl smazán."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Zdá se, že článek, který jste se snažili smazat, neexistuje, možná je již pryč?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Zdá se, že článek, který jste se snažili smazat, neexistuje, možná je již "
|
||||||
|
"pryč?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Nemohli jsme zjistit dostatečné množství informací ohledne vašeho účtu. Prosím ověřte si, že vaše předzývka je správná."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Nemohli jsme zjistit dostatečné množství informací ohledne vašeho účtu. "
|
||||||
|
"Prosím ověřte si, že vaše předzývka je správná."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Registrace jsou na téhle instanci uzavřeny."
|
msgstr "Registrace jsou na téhle instanci uzavřeny."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Váš účet byl vytvořen. Nyní se stačí jenom přihlásit, než ho budete moci používat."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Váš účet byl vytvořen. Nyní se stačí jenom přihlásit, než ho budete moci "
|
||||||
|
"používat."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Nahrávaní médií"
|
msgstr "Nahrávaní médií"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Heslo"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Potvrzení hesla"
|
msgstr "Potvrzení hesla"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Omlouváme se, ale registrace je uzavřena na této konkrétní instanci. Můžete však najít jinou."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Omlouváme se, ale registrace je uzavřena na této konkrétní instanci. Můžete "
|
||||||
|
"však najít jinou."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Odběry uživatele {0}"
|
msgstr "Odběry uživatele {0}"
|
||||||
@@ -454,7 +470,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Vaše Blogy"
|
msgstr "Vaše Blogy"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Zatím nemáte žádný blog. Vytvořte si vlastní, nebo požádejte v nejakém o členství."
|
msgstr ""
|
||||||
|
"Zatím nemáte žádný blog. Vytvořte si vlastní, nebo požádejte v nejakém o "
|
||||||
|
"členství."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Začít nový blog"
|
msgstr "Začít nový blog"
|
||||||
@@ -471,8 +489,11 @@ msgstr "Upravit váš účet"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Váš profil"
|
msgstr "Váš profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Chcete-li změnit svůj avatar, nahrejte ho do své galérie a pak ho odtud zvolte."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Chcete-li změnit svůj avatar, nahrejte ho do své galérie a pak ho odtud "
|
||||||
|
"zvolte."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Nahrát avatara"
|
msgstr "Nahrát avatara"
|
||||||
@@ -502,13 +523,15 @@ msgid "Danger zone"
|
|||||||
msgstr "Nebezpečná zóna"
|
msgstr "Nebezpečná zóna"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr "Buďte velmi opatrný/á, jakákoliv zde provedená akce nemůže být zrušena."
|
msgstr ""
|
||||||
|
"Buďte velmi opatrný/á, jakákoliv zde provedená akce nemůže být zrušena."
|
||||||
|
|
||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Smazat váš účet"
|
msgstr "Smazat váš účet"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Omlouváme se, ale jako administrátor nemůžete opustit svou vlastní instanci."
|
msgstr ""
|
||||||
|
"Omlouváme se, ale jako administrátor nemůžete opustit svou vlastní instanci."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Nejposlednejší články"
|
msgstr "Nejposlednejší články"
|
||||||
@@ -543,8 +566,14 @@ msgstr "Omlouváme se. Pokud si myslíte, že jde o chybu, prosím nahlašte ji.
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Neplatný CSRF token"
|
msgstr "Neplatný CSRF token"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "S vaším tokenem CSRF něco není v pořádku. Ujistěte se, že máte v prohlížeči povolené cookies a zkuste obnovit stránku. Pokud tuto chybovou zprávu budete nadále vidět, prosím nahlašte ji."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"S vaším tokenem CSRF něco není v pořádku. Ujistěte se, že máte v prohlížeči "
|
||||||
|
"povolené cookies a zkuste obnovit stránku. Pokud tuto chybovou zprávu budete "
|
||||||
|
"nadále vidět, prosím nahlašte ji."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Nemáte oprávnění."
|
msgstr "Nemáte oprávnění."
|
||||||
@@ -627,14 +656,30 @@ msgstr "Výchozí licence článků"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Uložit tyhle nastavení"
|
msgstr "Uložit tyhle nastavení"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Pokud si tuto stránku prohlížete jako návštěvník, žádné údaje o vás nejsou shromažďovány."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Pokud si tuto stránku prohlížete jako návštěvník, žádné údaje o vás nejsou "
|
||||||
|
"shromažďovány."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Jako registrovaný uživatel musíte poskytnout uživatelské jméno (které nemusí být vaším skutečným jménem), funkční e-mailovou adresu a heslo, aby jste se mohl přihlásit, psát články a komentář."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Jako registrovaný uživatel musíte poskytnout uživatelské jméno (které nemusí "
|
||||||
|
"být vaším skutečným jménem), funkční e-mailovou adresu a heslo, aby jste se "
|
||||||
|
"mohl přihlásit, psát články a komentář."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Když se přihlásíte, ukládáme dvě cookies, jedno, aby bylo možné udržet vaše zasedání otevřené, druhé, aby se zabránilo jiným lidem jednat ve vašem jméně. Žádné další cookies neukládáme."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Když se přihlásíte, ukládáme dvě cookies, jedno, aby bylo možné udržet vaše "
|
||||||
|
"zasedání otevřené, druhé, aby se zabránilo jiným lidem jednat ve vašem "
|
||||||
|
"jméně. Žádné další cookies neukládáme."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -642,7 +687,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +699,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +781,12 @@ msgstr "Podtitul"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Obsah"
|
msgstr "Obsah"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Můžete nahrát média do své galerie, a pak zkopírovat jejich kód Markdown do vašich článků, pro vložení."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Můžete nahrát média do své galerie, a pak zkopírovat jejich kód Markdown do "
|
||||||
|
"vašich článků, pro vložení."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Nahrát média"
|
msgstr "Nahrát média"
|
||||||
@@ -791,8 +847,12 @@ msgstr "Už to nechci dále boostovat"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Boostnout"
|
msgstr "Boostnout"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Přihlasit se{1}, nebo {2}použít váš Fediverse účet{3} k interakci s tímto článkem"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Přihlasit se{1}, nebo {2}použít váš Fediverse účet{3} k interakci s tímto "
|
||||||
|
"článkem"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Komentáře"
|
msgstr "Komentáře"
|
||||||
@@ -810,7 +870,8 @@ msgid "Are you sure?"
|
|||||||
msgstr "Jste si jisti?"
|
msgstr "Jste si jisti?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Tento článek je stále konceptem. Jenom vy, a další autoři ho mohou vidět."
|
msgstr ""
|
||||||
|
"Tento článek je stále konceptem. Jenom vy, a další autoři ho mohou vidět."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Jenom vy, a další autoři mohou upravovat tento článek."
|
msgstr "Jenom vy, a další autoři mohou upravovat tento článek."
|
||||||
@@ -848,8 +909,12 @@ msgstr "Aktualizovat heslo"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Zkontrolujte svou příchozí poštu!"
|
msgstr "Zkontrolujte svou příchozí poštu!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Zaslali jsme email na adresu, kterou jste nám dodali, s odkazem na obnovu vášho hesla."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Zaslali jsme email na adresu, kterou jste nám dodali, s odkazem na obnovu "
|
||||||
|
"vášho hesla."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Poslat odkaz na obnovení hesla"
|
msgstr "Poslat odkaz na obnovení hesla"
|
||||||
@@ -857,7 +922,9 @@ msgstr "Poslat odkaz na obnovení hesla"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -872,8 +939,11 @@ msgstr "Vytvořit blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Upravit \"{}\""
|
msgstr "Upravit \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Můžete nahrát obrázky do své galerie, aby je šlo použít jako ikony blogu, nebo bannery."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Můžete nahrát obrázky do své galerie, aby je šlo použít jako ikony blogu, "
|
||||||
|
"nebo bannery."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Nahrát obrázky"
|
msgstr "Nahrát obrázky"
|
||||||
@@ -891,7 +961,8 @@ msgid "Update blog"
|
|||||||
msgstr "Aktualizovat blog"
|
msgstr "Aktualizovat blog"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Buďte velmi opatrný/á, jakákoliv zde provedená akce nemůže být vrácena."
|
msgstr ""
|
||||||
|
"Buďte velmi opatrný/á, jakákoliv zde provedená akce nemůže být vrácena."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -936,8 +1007,12 @@ msgstr "Plume je decentralizovaný blogování systém."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Autoři mohou spravovat vícero blogů, každý jako svou vlastní stránku."
|
msgstr "Autoři mohou spravovat vícero blogů, každý jako svou vlastní stránku."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Články jsou viditelné také na ostatních Plume instancích, a můžete s nimi narábět přímo i v rámci jiných platforem, jako je Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Články jsou viditelné také na ostatních Plume instancích, a můžete s nimi "
|
||||||
|
"narábět přímo i v rámci jiných platforem, jako je Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Přečtěte si podrobná pravidla"
|
msgstr "Přečtěte si podrobná pravidla"
|
||||||
@@ -1016,4 +1091,3 @@ msgstr "Zveřejněn pod touto licenci"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licence článku"
|
msgstr "Licence článku"
|
||||||
|
|
||||||
|
|||||||
+808
-515
File diff suppressed because it is too large
Load Diff
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+133
-44
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Dein Artikel wurde gelöscht."
|
msgstr "Dein Artikel wurde gelöscht."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Möglicherweise ist der zu löschende Artikel nicht (mehr) vorhanden. Wurde er vielleicht schon entfernt?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Möglicherweise ist der zu löschende Artikel nicht (mehr) vorhanden. Wurde er "
|
||||||
|
"vielleicht schon entfernt?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Wir konnten nicht genug Informationen über dein Konto finden. Bitte stelle sicher, dass dein Benutzername richtig ist."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Wir konnten nicht genug Informationen über dein Konto finden. Bitte stelle "
|
||||||
|
"sicher, dass dein Benutzername richtig ist."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Anmeldungen sind auf dieser Instanz aktuell nicht möglich."
|
msgstr "Anmeldungen sind auf dieser Instanz aktuell nicht möglich."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Dein Konto wurde erstellt. Jetzt musst du dich nur noch anmelden, um es nutzen zu können."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Dein Konto wurde erstellt. Jetzt musst du dich nur noch anmelden, um es "
|
||||||
|
"nutzen zu können."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Hochladen von Mediendateien"
|
msgstr "Hochladen von Mediendateien"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Passwort"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Passwort bestätigen"
|
msgstr "Passwort bestätigen"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Entschuldigung, Registrierungen sind auf dieser Instanz geschlossen. Du kannst jedoch eine andere finden."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Entschuldigung, Registrierungen sind auf dieser Instanz geschlossen. Du "
|
||||||
|
"kannst jedoch eine andere finden."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0}'s Abonnements"
|
msgstr "{0}'s Abonnements"
|
||||||
@@ -454,7 +470,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Deine Blogs"
|
msgstr "Deine Blogs"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Du hast noch keinen Blog. Erstelle deinen eigenen, oder frage, um dich einem anzuschließen."
|
msgstr ""
|
||||||
|
"Du hast noch keinen Blog. Erstelle deinen eigenen, oder frage, um dich einem "
|
||||||
|
"anzuschließen."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Neuen Blog beginnen"
|
msgstr "Neuen Blog beginnen"
|
||||||
@@ -471,8 +489,11 @@ msgstr "Eigenes Profil bearbeiten"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Dein Profil"
|
msgstr "Dein Profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Um dein Profilbild zu ändern, lade es in deine Galerie hoch und wähle es dort aus."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Um dein Profilbild zu ändern, lade es in deine Galerie hoch und wähle es "
|
||||||
|
"dort aus."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Ein Profilbild hochladen"
|
msgstr "Ein Profilbild hochladen"
|
||||||
@@ -508,7 +529,9 @@ msgid "Delete your account"
|
|||||||
msgstr "Eigenen Account löschen"
|
msgstr "Eigenen Account löschen"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Entschuldingung, aber als Administrator kannst du deine eigene Instanz nicht verlassen."
|
msgstr ""
|
||||||
|
"Entschuldingung, aber als Administrator kannst du deine eigene Instanz nicht "
|
||||||
|
"verlassen."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Neueste Artikel"
|
msgstr "Neueste Artikel"
|
||||||
@@ -538,13 +561,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Bei dir ist etwas schief gegangen."
|
msgstr "Bei dir ist etwas schief gegangen."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Das tut uns leid. Wenn du denkst, dass dies ein Bug ist, melde ihn bitte."
|
msgstr ""
|
||||||
|
"Das tut uns leid. Wenn du denkst, dass dies ein Bug ist, melde ihn bitte."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Ungültiges CSRF-Token"
|
msgstr "Ungültiges CSRF-Token"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Irgendetwas stimmt mit deinem CSRF token nicht. Vergewissere dich, dass Cookies in deinem Browser aktiviert sind und versuche diese Seite neu zu laden. Bitte melde diesen Fehler, falls er erneut auftritt."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Irgendetwas stimmt mit deinem CSRF token nicht. Vergewissere dich, dass "
|
||||||
|
"Cookies in deinem Browser aktiviert sind und versuche diese Seite neu zu "
|
||||||
|
"laden. Bitte melde diesen Fehler, falls er erneut auftritt."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Berechtigung fehlt"
|
msgstr "Berechtigung fehlt"
|
||||||
@@ -627,14 +657,31 @@ msgstr "Voreingestellte Artikel-Lizenz"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Diese Einstellungen speichern"
|
msgstr "Diese Einstellungen speichern"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Wenn Sie diese Website als Besucher nutzen, werden keine Daten über Sie erhoben."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Wenn Sie diese Website als Besucher nutzen, werden keine Daten über Sie "
|
||||||
|
"erhoben."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Als registrierter Benutzer müssen Sie Ihren Benutzernamen (der nicht Ihr richtiger Name sein muss), Ihre E-Mail-Adresse und ein Passwort angeben, um sich anmelden, Artikel schreiben und kommentieren zu können. Die von Ihnen übermittelten Inhalte werden gespeichert, bis Sie sie löschen."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Als registrierter Benutzer müssen Sie Ihren Benutzernamen (der nicht Ihr "
|
||||||
|
"richtiger Name sein muss), Ihre E-Mail-Adresse und ein Passwort angeben, um "
|
||||||
|
"sich anmelden, Artikel schreiben und kommentieren zu können. Die von Ihnen "
|
||||||
|
"übermittelten Inhalte werden gespeichert, bis Sie sie löschen."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Wenn Sie sich anmelden, speichern wir zwei Cookies, eines, um Ihre Sitzung offen zu halten, das andere, um zu verhindern, dass andere Personen in Ihrem Namen handeln. Wir speichern keine weiteren Cookies."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Wenn Sie sich anmelden, speichern wir zwei Cookies, eines, um Ihre Sitzung "
|
||||||
|
"offen zu halten, das andere, um zu verhindern, dass andere Personen in Ihrem "
|
||||||
|
"Namen handeln. Wir speichern keine weiteren Cookies."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Gesperrte E-Mail-Adressen"
|
msgstr "Gesperrte E-Mail-Adressen"
|
||||||
@@ -642,8 +689,14 @@ msgstr "Gesperrte E-Mail-Adressen"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "E‐Mail‐Adresse"
|
msgstr "E‐Mail‐Adresse"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "Die E-Mail-Adresse, die du sperren möchtest. Um bestimmte Domänen zu sperren, kannst du den Globbing-Syntax verwenden: Beispielsweise: *@example.com” sperrt alle Adressen von example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"Die E-Mail-Adresse, die du sperren möchtest. Um bestimmte Domänen zu "
|
||||||
|
"sperren, kannst du den Globbing-Syntax verwenden: Beispielsweise: *@example."
|
||||||
|
"com” sperrt alle Adressen von example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Notiz"
|
msgstr "Notiz"
|
||||||
@@ -651,14 +704,22 @@ msgstr "Notiz"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Benutzer benachrichtigen?"
|
msgstr "Benutzer benachrichtigen?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Optional: Dem Benutzer wird eine Nachricht angezeigt, wenn er versucht, ein Konto mit dieser Adresse zu erstellen"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Optional: Dem Benutzer wird eine Nachricht angezeigt, wenn er versucht, ein "
|
||||||
|
"Konto mit dieser Adresse zu erstellen"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Sperrlisten-Benachrichtigung"
|
msgstr "Sperrlisten-Benachrichtigung"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Die Nachricht, die angezeigt wird, wenn der Benutzer versucht, ein Konto mit dieser E-Mail-Adresse zu erstellen"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Die Nachricht, die angezeigt wird, wenn der Benutzer versucht, ein Konto mit "
|
||||||
|
"dieser E-Mail-Adresse zu erstellen"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Adresse zur Sperrliste hinzufügen"
|
msgstr "Adresse zur Sperrliste hinzufügen"
|
||||||
@@ -676,10 +737,12 @@ msgid "Blocklisted for:"
|
|||||||
msgstr "Gesperrt für:"
|
msgstr "Gesperrt für:"
|
||||||
|
|
||||||
msgid "Will notify them on account creation with this message:"
|
msgid "Will notify them on account creation with this message:"
|
||||||
msgstr "Du wirst beim Erstellen eines Kontos mit dieser Nachricht benachrichtigt:"
|
msgstr ""
|
||||||
|
"Du wirst beim Erstellen eines Kontos mit dieser Nachricht benachrichtigt:"
|
||||||
|
|
||||||
msgid "The user will be silently prevented from making an account"
|
msgid "The user will be silently prevented from making an account"
|
||||||
msgstr "Der Benutzer wird stillschweigend daran gehindert, ein Konto einzurichten"
|
msgstr ""
|
||||||
|
"Der Benutzer wird stillschweigend daran gehindert, ein Konto einzurichten"
|
||||||
|
|
||||||
msgid "Welcome to {}"
|
msgid "Welcome to {}"
|
||||||
msgstr "Willkommen bei {}"
|
msgstr "Willkommen bei {}"
|
||||||
@@ -729,8 +792,12 @@ msgstr "Untertitel"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Inhalt"
|
msgstr "Inhalt"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Du kannst Medien in deine Galerie hochladen und dann deren Markdown-Code in deine Artikel kopieren, um sie einzufügen."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Du kannst Medien in deine Galerie hochladen und dann deren Markdown-Code in "
|
||||||
|
"deine Artikel kopieren, um sie einzufügen."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Medien hochladen"
|
msgstr "Medien hochladen"
|
||||||
@@ -787,8 +854,12 @@ msgstr "Ich möchte das nicht mehr boosten"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Boosten"
|
msgstr "Boosten"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Anmelden{1} oder {2}Ihr Fediverse-Konto verwenden{3}, um mit diesem Artikel zu interagieren."
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Anmelden{1} oder {2}Ihr Fediverse-Konto verwenden{3}, um mit diesem "
|
||||||
|
"Artikel zu interagieren."
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Kommentare"
|
msgstr "Kommentare"
|
||||||
@@ -806,7 +877,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "Bist du dir sicher?"
|
msgstr "Bist du dir sicher?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Dieser Artikel ist noch ein Entwurf. Nur Sie und andere Autoren können ihn sehen."
|
msgstr ""
|
||||||
|
"Dieser Artikel ist noch ein Entwurf. Nur Sie und andere Autoren können ihn "
|
||||||
|
"sehen."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Nur Sie und andere Autoren können diesen Artikel bearbeiten."
|
msgstr "Nur Sie und andere Autoren können diesen Artikel bearbeiten."
|
||||||
@@ -844,8 +917,12 @@ msgstr "Passwort aktualisieren"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Posteingang prüfen!"
|
msgstr "Posteingang prüfen!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Wir haben eine Mail an die von dir angegebene Adresse gesendet, mit einem Link, um dein Passwort zurückzusetzen."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Wir haben eine Mail an die von dir angegebene Adresse gesendet, mit einem "
|
||||||
|
"Link, um dein Passwort zurückzusetzen."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Link zum Zurücksetzen des Passworts senden"
|
msgstr "Link zum Zurücksetzen des Passworts senden"
|
||||||
@@ -853,8 +930,12 @@ msgstr "Link zum Zurücksetzen des Passworts senden"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Diese Token ist veraltet"
|
msgstr "Diese Token ist veraltet"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Bitte starten Sie den Prozess erneut, indem Sie <a href=\"/password-reset\">hier</a> klicken."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Bitte starten Sie den Prozess erneut, indem Sie <a href=\"/password-reset"
|
||||||
|
"\">hier</a> klicken."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Neuer Blog"
|
msgstr "Neuer Blog"
|
||||||
@@ -868,8 +949,11 @@ msgstr "Blog erstellen"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "„{}” bearbeiten"
|
msgstr "„{}” bearbeiten"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Sie können Bilder in Ihre Galerie hochladen, um sie als Blog-Symbol oder Banner zu verwenden."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Sie können Bilder in Ihre Galerie hochladen, um sie als Blog-Symbol oder "
|
||||||
|
"Banner zu verwenden."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Bilder hochladen"
|
msgstr "Bilder hochladen"
|
||||||
@@ -887,7 +971,9 @@ msgid "Update blog"
|
|||||||
msgstr "Blog aktualisieren"
|
msgstr "Blog aktualisieren"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Seien Sie sehr vorsichtig, alle hier getroffenen Aktionen können nicht widerrufen werden."
|
msgstr ""
|
||||||
|
"Seien Sie sehr vorsichtig, alle hier getroffenen Aktionen können nicht "
|
||||||
|
"widerrufen werden."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "Möchten Sie diesen Blog wirklich dauerhaft löschen?"
|
msgstr "Möchten Sie diesen Blog wirklich dauerhaft löschen?"
|
||||||
@@ -930,8 +1016,12 @@ msgstr "Plume ist eine dezentrale Blogging-Engine."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Autoren können mehrere Blogs verwalten, jeden als eigene Website."
|
msgstr "Autoren können mehrere Blogs verwalten, jeden als eigene Website."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Artikel sind auch auf anderen Plume-Instanzen sichtbar und du kannst mit ihnen direkt von anderen Plattformen wie Mastodon interagieren."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Artikel sind auch auf anderen Plume-Instanzen sichtbar und du kannst mit "
|
||||||
|
"ihnen direkt von anderen Plattformen wie Mastodon interagieren."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Die detaillierten Regeln lesen"
|
msgstr "Die detaillierten Regeln lesen"
|
||||||
@@ -1010,4 +1100,3 @@ msgstr "Unter dieser Lizenz veröffentlicht"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Artikel-Lizenz"
|
msgstr "Artikel-Lizenz"
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Via artikolo estis forigita."
|
msgstr "Via artikolo estis forigita."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr "Pasvorto"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Konfirmo de la pasvorto"
|
msgstr "Konfirmo de la pasvorto"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,8 +479,10 @@ msgstr "Redakti vian konton"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Via profilo"
|
msgstr "Via profilo"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Por ĉanĝi vian profilbildon, retsendu ĝin en via bildaro kaj selektu ol kie."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Por ĉanĝi vian profilbildon, retsendu ĝin en via bildaro kaj selektu ol kie."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Retsendi profilbildo"
|
msgstr "Retsendi profilbildo"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Konservi ĉi tiujn agordojn"
|
msgstr "Konservi ĉi tiujn agordojn"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Enhavo"
|
msgstr "Enhavo"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +817,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +876,9 @@ msgstr "Ĝisdatigi pasvorton"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +887,9 @@ msgstr "Sendi ligilon por restarigi pasvorton"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +904,8 @@ msgstr "Krei blogon"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Redakti “{}”"
|
msgstr "Redakti “{}”"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +967,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1049,3 @@ msgstr "Eldonita sub ĉi tiu permesilo"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Artikola permesilo"
|
msgstr "Artikola permesilo"
|
||||||
|
|
||||||
|
|||||||
+131
-43
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Se ha eliminado el artículo."
|
msgstr "Se ha eliminado el artículo."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Parece que el artículo que intentaste eliminar no existe. ¿Tal vez ya haya desaparecido?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Parece que el artículo que intentaste eliminar no existe. ¿Tal vez ya haya "
|
||||||
|
"desaparecido?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "No se pudo obtener suficiente información sobre su cuenta. Por favor, asegúrese de que su nombre de usuario es correcto."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"No se pudo obtener suficiente información sobre su cuenta. Por favor, "
|
||||||
|
"asegúrese de que su nombre de usuario es correcto."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Los registros están cerrados en esta instancia."
|
msgstr "Los registros están cerrados en esta instancia."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Tu cuenta ha sido creada. Ahora solo necesitas iniciar sesión, antes de poder usarla."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Tu cuenta ha sido creada. Ahora solo necesitas iniciar sesión, antes de "
|
||||||
|
"poder usarla."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Subir medios"
|
msgstr "Subir medios"
|
||||||
@@ -292,7 +304,9 @@ msgid "Description"
|
|||||||
msgstr "Descripción"
|
msgstr "Descripción"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Útil para personas con discapacidad visual, tanto como información de licencias"
|
msgstr ""
|
||||||
|
"Útil para personas con discapacidad visual, tanto como información de "
|
||||||
|
"licencias"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Aviso de contenido"
|
msgstr "Aviso de contenido"
|
||||||
@@ -441,8 +455,12 @@ msgstr "Contraseña"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Confirmación de contraseña"
|
msgstr "Confirmación de contraseña"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Lo sentimos, pero las inscripciones están cerradas en esta instancia. Sin embargo, puede encontrar una instancia distinta."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Lo sentimos, pero las inscripciones están cerradas en esta instancia. Sin "
|
||||||
|
"embargo, puede encontrar una instancia distinta."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Suscripciones de {0}"
|
msgstr "Suscripciones de {0}"
|
||||||
@@ -471,7 +489,8 @@ msgstr "Edita tu cuenta"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Tu perfil"
|
msgstr "Tu perfil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr "Para cambiar tu avatar, súbalo a su galería y seleccione de ahí."
|
msgstr "Para cambiar tu avatar, súbalo a su galería y seleccione de ahí."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -508,7 +527,8 @@ msgid "Delete your account"
|
|||||||
msgstr "Eliminar tu cuenta"
|
msgstr "Eliminar tu cuenta"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Lo sentimos, pero como un administrador, no puede dejar su propia instancia."
|
msgstr ""
|
||||||
|
"Lo sentimos, pero como un administrador, no puede dejar su propia instancia."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Últimas publicaciones"
|
msgstr "Últimas publicaciones"
|
||||||
@@ -538,13 +558,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Algo ha salido mal de nuestro lado."
|
msgstr "Algo ha salido mal de nuestro lado."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Disculpe la molestia. Si cree que esto es un defecto, por favor repórtalo."
|
msgstr ""
|
||||||
|
"Disculpe la molestia. Si cree que esto es un defecto, por favor repórtalo."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Token CSRF inválido"
|
msgstr "Token CSRF inválido"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Hay un problema con su token CSRF. Asegúrase de que las cookies están habilitadas en su navegador, e intente recargar esta página. Si sigue viendo este mensaje de error, por favor infórmelo."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Hay un problema con su token CSRF. Asegúrase de que las cookies están "
|
||||||
|
"habilitadas en su navegador, e intente recargar esta página. Si sigue viendo "
|
||||||
|
"este mensaje de error, por favor infórmelo."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "No está autorizado."
|
msgstr "No está autorizado."
|
||||||
@@ -627,14 +654,32 @@ msgstr "Licencia del artículo por defecto"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Guardar estos ajustes"
|
msgstr "Guardar estos ajustes"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Si está navegando por este sitio como visitante, no se recopilan datos sobre usted."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Si está navegando por este sitio como visitante, no se recopilan datos sobre "
|
||||||
|
"usted."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Como usuario registrado, tienes que proporcionar tu nombre de usuario (que no tiene que ser tu nombre real), tu dirección de correo electrónico funcional y una contraseña, con el fin de poder iniciar sesión, escribir artículos y comentarios. El contenido que envíes se almacena hasta que lo elimines."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Como usuario registrado, tienes que proporcionar tu nombre de usuario (que "
|
||||||
|
"no tiene que ser tu nombre real), tu dirección de correo electrónico "
|
||||||
|
"funcional y una contraseña, con el fin de poder iniciar sesión, escribir "
|
||||||
|
"artículos y comentarios. El contenido que envíes se almacena hasta que lo "
|
||||||
|
"elimines."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Cuando inicias sesión, guardamos dos cookies, una para mantener tu sesión abierta, la segunda para evitar que otras personas actúen en tu nombre. No almacenamos ninguna otra cookie."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Cuando inicias sesión, guardamos dos cookies, una para mantener tu sesión "
|
||||||
|
"abierta, la segunda para evitar que otras personas actúen en tu nombre. No "
|
||||||
|
"almacenamos ninguna otra cookie."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Correos en la lista de bloqueos"
|
msgstr "Correos en la lista de bloqueos"
|
||||||
@@ -642,8 +687,14 @@ msgstr "Correos en la lista de bloqueos"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Dirección de correo electrónico"
|
msgstr "Dirección de correo electrónico"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "La dirección de correo electrónico que deseas bloquear. Para bloquear dominios, puedes usar sintaxis de globbing, por ejemplo '*@example.com' bloquea todas las direcciones de example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"La dirección de correo electrónico que deseas bloquear. Para bloquear "
|
||||||
|
"dominios, puedes usar sintaxis de globbing, por ejemplo '*@example.com' "
|
||||||
|
"bloquea todas las direcciones de example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Nota"
|
msgstr "Nota"
|
||||||
@@ -651,14 +702,22 @@ msgstr "Nota"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "¿Notificar al usuario?"
|
msgstr "¿Notificar al usuario?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Opcional, muestra un mensaje al usuario cuando intenta crear una cuenta con esa dirección"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Opcional, muestra un mensaje al usuario cuando intenta crear una cuenta con "
|
||||||
|
"esa dirección"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Notificación de bloqueo"
|
msgstr "Notificación de bloqueo"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "El mensaje que se mostrará cuando el usuario intente crear una cuenta con esta dirección de correo electrónico"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"El mensaje que se mostrará cuando el usuario intente crear una cuenta con "
|
||||||
|
"esta dirección de correo electrónico"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Añadir dirección bloqueada"
|
msgstr "Añadir dirección bloqueada"
|
||||||
@@ -673,7 +732,9 @@ msgid "Email address:"
|
|||||||
msgstr "Dirección de correo electrónico:"
|
msgstr "Dirección de correo electrónico:"
|
||||||
|
|
||||||
msgid "Blocklisted for:"
|
msgid "Blocklisted for:"
|
||||||
msgstr "Este texto no tiene información de contexto. El texto es usado en plume.pot. Posición en el archivo: 115:"
|
msgstr ""
|
||||||
|
"Este texto no tiene información de contexto. El texto es usado en plume.pot. "
|
||||||
|
"Posición en el archivo: 115:"
|
||||||
|
|
||||||
msgid "Will notify them on account creation with this message:"
|
msgid "Will notify them on account creation with this message:"
|
||||||
msgstr "Les notificará al crear la cuenta con este mensaje:"
|
msgstr "Les notificará al crear la cuenta con este mensaje:"
|
||||||
@@ -729,8 +790,12 @@ msgstr "Subtítulo"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Contenido"
|
msgstr "Contenido"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Puede subir los medios a su galería, y luego copiar su código Markdown en sus artículos para insertarlos."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Puede subir los medios a su galería, y luego copiar su código Markdown en "
|
||||||
|
"sus artículos para insertarlos."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Cargar medios"
|
msgstr "Cargar medios"
|
||||||
@@ -787,8 +852,12 @@ msgstr "Ya no quiero compartir esto"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Compartir"
|
msgstr "Compartir"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Inicie sesión{1}, o {2}utilice su cuenta del Fediverso{3} para interactuar con este artículo"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Inicie sesión{1}, o {2}utilice su cuenta del Fediverso{3} para "
|
||||||
|
"interactuar con este artículo"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Comentários"
|
msgstr "Comentários"
|
||||||
@@ -806,7 +875,8 @@ msgid "Are you sure?"
|
|||||||
msgstr "¿Está seguro?"
|
msgstr "¿Está seguro?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Este artículo sigue siendo un borrador. Sólo tú y otros autores pueden verlo."
|
msgstr ""
|
||||||
|
"Este artículo sigue siendo un borrador. Sólo tú y otros autores pueden verlo."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Sólo tú y otros autores pueden editar este artículo."
|
msgstr "Sólo tú y otros autores pueden editar este artículo."
|
||||||
@@ -844,8 +914,12 @@ msgstr "Actualizar contraseña"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Revise su bandeja de entrada!"
|
msgstr "Revise su bandeja de entrada!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Enviamos un correo a la dirección que nos dio, con un enlace para restablecer su contraseña."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Enviamos un correo a la dirección que nos dio, con un enlace para "
|
||||||
|
"restablecer su contraseña."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Enviar enlace de restablecimiento de contraseña"
|
msgstr "Enviar enlace de restablecimiento de contraseña"
|
||||||
@@ -853,8 +927,12 @@ msgstr "Enviar enlace de restablecimiento de contraseña"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Este token ha caducado"
|
msgstr "Este token ha caducado"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Por favor, vuelva a iniciar el proceso haciendo click <a href=\"/password-reset\">aquí</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Por favor, vuelva a iniciar el proceso haciendo click <a href=\"/password-"
|
||||||
|
"reset\">aquí</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Nuevo Blog"
|
msgstr "Nuevo Blog"
|
||||||
@@ -868,8 +946,11 @@ msgstr "Crear el blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Editar \"{}\""
|
msgstr "Editar \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Puede subir imágenes a su galería, para usarlas como iconos de blog, o banderas."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Puede subir imágenes a su galería, para usarlas como iconos de blog, o "
|
||||||
|
"banderas."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Subir imágenes"
|
msgstr "Subir imágenes"
|
||||||
@@ -887,7 +968,9 @@ msgid "Update blog"
|
|||||||
msgstr "Actualizar el blog"
|
msgstr "Actualizar el blog"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Tenga mucho cuidado, cualquier acción que se tome aquí no puede ser invertida."
|
msgstr ""
|
||||||
|
"Tenga mucho cuidado, cualquier acción que se tome aquí no puede ser "
|
||||||
|
"invertida."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "¿Está seguro que desea eliminar permanentemente este blog?"
|
msgstr "¿Está seguro que desea eliminar permanentemente este blog?"
|
||||||
@@ -928,10 +1011,16 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Plume es un motor de blogs descentralizado."
|
msgstr "Plume es un motor de blogs descentralizado."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Los autores pueden administrar múltiples blogs, cada uno como su propio sitio web."
|
msgstr ""
|
||||||
|
"Los autores pueden administrar múltiples blogs, cada uno como su propio "
|
||||||
|
"sitio web."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Los artículos también son visibles en otras instancias de Plume, y puede interactuar con ellos directamente desde otras plataformas como Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Los artículos también son visibles en otras instancias de Plume, y puede "
|
||||||
|
"interactuar con ellos directamente desde otras plataformas como Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Leer las reglas detalladas"
|
msgstr "Leer las reglas detalladas"
|
||||||
@@ -1010,4 +1099,3 @@ msgstr "Publicado bajo esta licencia"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licencia de artículo"
|
msgstr "Licencia de artículo"
|
||||||
|
|
||||||
|
|||||||
+125
-42
@@ -214,12 +214,19 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "نوشتهٔ شما پاک شده است."
|
msgstr "نوشتهٔ شما پاک شده است."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "به نظر میرسد نوشتهای را که میخواهید پاک کنید، وجود ندارد. قبلا پاک نشده است؟"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"به نظر میرسد نوشتهای را که میخواهید پاک کنید، وجود ندارد. قبلا پاک نشده است؟"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "نتوانستیم اطلاعات کافی درباره حساب شما دریافت کنیم. لطفا مطمئن شوید که نام کاربری درست است."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"نتوانستیم اطلاعات کافی درباره حساب شما دریافت کنیم. لطفا مطمئن شوید که نام "
|
||||||
|
"کاربری درست است."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +289,11 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "ثبتنام روی این نمونه بسته شده است."
|
msgstr "ثبتنام روی این نمونه بسته شده است."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "حساب شما ایجاد شده است. اکنون برای استفاده از آن تنها نیاز است که واردش شوید."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"حساب شما ایجاد شده است. اکنون برای استفاده از آن تنها نیاز است که واردش شوید."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "بارگذاری رسانه"
|
msgstr "بارگذاری رسانه"
|
||||||
@@ -441,8 +451,12 @@ msgstr "گذرواژه"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "تایید گذرواژه"
|
msgstr "تایید گذرواژه"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "معذرت میخواهیم. ثبتنام روی این نمونه خاص بسته شده است. با این حال شما میتوانید یک نمونه دیگر پیدا کنید."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"معذرت میخواهیم. ثبتنام روی این نمونه خاص بسته شده است. با این حال شما "
|
||||||
|
"میتوانید یک نمونه دیگر پیدا کنید."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "دنبالشوندگان {0}"
|
msgstr "دنبالشوندگان {0}"
|
||||||
@@ -454,7 +468,8 @@ msgid "Your Blogs"
|
|||||||
msgstr "بلاگهای شما"
|
msgstr "بلاگهای شما"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "شما هنوز هیچ بلاگی ندارید. یکی بسازید یا درخواست پیوستن به یکی را بدهید."
|
msgstr ""
|
||||||
|
"شما هنوز هیچ بلاگی ندارید. یکی بسازید یا درخواست پیوستن به یکی را بدهید."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "شروع یک بلاگ جدید"
|
msgstr "شروع یک بلاگ جدید"
|
||||||
@@ -471,8 +486,11 @@ msgstr "حسابتان را ویرایش کنید"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "نمایهٔ شما"
|
msgstr "نمایهٔ شما"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "برای تغییر تصویر حسابتان، ابتدا آن را در نگارخانه بارگذاری کرده و سپس از همان جا انتخابش کنید."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"برای تغییر تصویر حسابتان، ابتدا آن را در نگارخانه بارگذاری کرده و سپس از "
|
||||||
|
"همان جا انتخابش کنید."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "بارگذاری تصویر حساب"
|
msgstr "بارگذاری تصویر حساب"
|
||||||
@@ -538,13 +556,21 @@ msgid "Something broke on our side."
|
|||||||
msgstr "مشکلی سمت ما پیش آمد."
|
msgstr "مشکلی سمت ما پیش آمد."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "از این بابت متاسفیم. اگر فکر میکنید این اتفاق ناشی از یک اشکال فنی است، لطفا آن را گزارش کنید."
|
msgstr ""
|
||||||
|
"از این بابت متاسفیم. اگر فکر میکنید این اتفاق ناشی از یک اشکال فنی است، لطفا "
|
||||||
|
"آن را گزارش کنید."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "توکن CSRF نامعتبر"
|
msgstr "توکن CSRF نامعتبر"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "مشکلی در ارتباط با توکن CSRF ما وجود دارد. اطمینان حاصل کنید که کوکی در مرورگرتان فعال است و سپس این صفحه را مجددا فراخوانی کنید. اگر این پیام خطا را باز هم مشاهده کردید، موضوع را گزارش کنید."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"مشکلی در ارتباط با توکن CSRF ما وجود دارد. اطمینان حاصل کنید که کوکی در "
|
||||||
|
"مرورگرتان فعال است و سپس این صفحه را مجددا فراخوانی کنید. اگر این پیام خطا "
|
||||||
|
"را باز هم مشاهده کردید، موضوع را گزارش کنید."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "شما مجاز به این کار نیستید."
|
msgstr "شما مجاز به این کار نیستید."
|
||||||
@@ -627,14 +653,31 @@ msgstr "پروانه پیشفرض نوشته"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "ذخیره این تنظیمات"
|
msgstr "ذخیره این تنظیمات"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "اگر شما به عنوان یک بازدیدکننده در حال مرور این پایگاه هستید، هیچ دادهای درباره شما گردآوری نمیشود."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"اگر شما به عنوان یک بازدیدکننده در حال مرور این پایگاه هستید، هیچ دادهای "
|
||||||
|
"درباره شما گردآوری نمیشود."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "به عنوان یک کاربر ثبتنام شده، برای آنکه بتوانید وارد شده و مطلب بنویسید یا نظر بدهید، لازم است که نامکاربری (که لازم نیست نام واقعی شما باشد) و نشانی رایانامه فعال را ارائه کنید. محتوایی که میفرستید، تا زمانی که خودتان آن را پاک نکنید نگهداری میشود."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"به عنوان یک کاربر ثبتنام شده، برای آنکه بتوانید وارد شده و مطلب بنویسید یا "
|
||||||
|
"نظر بدهید، لازم است که نامکاربری (که لازم نیست نام واقعی شما باشد) و نشانی "
|
||||||
|
"رایانامه فعال را ارائه کنید. محتوایی که میفرستید، تا زمانی که خودتان آن را "
|
||||||
|
"پاک نکنید نگهداری میشود."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "وقتی وارد میشوید، ما دو کوکی ذخیره میکنیم. یکی برای باز نگهداشتن نشست جاری و دومی برای اجتناب از فعالیت دیگران از جانب شما. ما هیچ کوکی دیگری ذخیره نمیکنیم."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"وقتی وارد میشوید، ما دو کوکی ذخیره میکنیم. یکی برای باز نگهداشتن نشست جاری و "
|
||||||
|
"دومی برای اجتناب از فعالیت دیگران از جانب شما. ما هیچ کوکی دیگری ذخیره "
|
||||||
|
"نمیکنیم."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "رایانامههای مسدود شده"
|
msgstr "رایانامههای مسدود شده"
|
||||||
@@ -642,8 +685,14 @@ msgstr "رایانامههای مسدود شده"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "نشانی رایانامه"
|
msgstr "نشانی رایانامه"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "نشانی رایانامهای که میخواهید مسدود کنید. اگر میخواهید دامنهها را مسدود کنید، میتواند از نحو گِلاب استفاده کنید. مثلاً عبارت '*@example.com' تمام نشانیها از دامنه example.com را مسدود میکند"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"نشانی رایانامهای که میخواهید مسدود کنید. اگر میخواهید دامنهها را مسدود کنید، "
|
||||||
|
"میتواند از نحو گِلاب استفاده کنید. مثلاً عبارت '*@example.com' تمام نشانیها از "
|
||||||
|
"دامنه example.com را مسدود میکند"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "یادداشت"
|
msgstr "یادداشت"
|
||||||
@@ -651,14 +700,22 @@ msgstr "یادداشت"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "به کاربر اعلان شود؟"
|
msgstr "به کاربر اعلان شود؟"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "اختیاری، هنگامی که کاربر با آن نشانی تلاش برای ایجاد حساب کند، پیامی به او نشان میدهد"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"اختیاری، هنگامی که کاربر با آن نشانی تلاش برای ایجاد حساب کند، پیامی به او "
|
||||||
|
"نشان میدهد"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "اعلان مسدودسازی"
|
msgstr "اعلان مسدودسازی"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "پیامی که هنگام تلاش کاربر برای ساخت حساب با این نشانی رایانامه به او نشان داده میشود"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"پیامی که هنگام تلاش کاربر برای ساخت حساب با این نشانی رایانامه به او نشان "
|
||||||
|
"داده میشود"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "اضافه کردن نشانی مسدودشده"
|
msgstr "اضافه کردن نشانی مسدودشده"
|
||||||
@@ -729,8 +786,12 @@ msgstr "زیرعنوان"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "محتوا"
|
msgstr "محتوا"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "برای درج رسانه میتوانید آن را به نگارخانه خود افزوده و سپس به کمک کد مارکداونی که میگیرید وارد مطلبتان کنید."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"برای درج رسانه میتوانید آن را به نگارخانه خود افزوده و سپس به کمک کد "
|
||||||
|
"مارکداونی که میگیرید وارد مطلبتان کنید."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "بارگذاری رسانه"
|
msgstr "بارگذاری رسانه"
|
||||||
@@ -787,8 +848,12 @@ msgstr "دیگر نمیخوام این را تقویت کنم"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "تقویت"
|
msgstr "تقویت"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}وارد شوید{1} و یا {2}از حساب فدیورس خود{3} برای تعامل با این مطلب استفاده کنید"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}وارد شوید{1} و یا {2}از حساب فدیورس خود{3} برای تعامل با این مطلب استفاده "
|
||||||
|
"کنید"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "نظرات"
|
msgstr "نظرات"
|
||||||
@@ -806,7 +871,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "مطمئنید؟"
|
msgstr "مطمئنید؟"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "این مطلب هنوز یک پیشنویس است. تنها شما و دیگر نویسندگان میتوانید آن را ببینید."
|
msgstr ""
|
||||||
|
"این مطلب هنوز یک پیشنویس است. تنها شما و دیگر نویسندگان میتوانید آن را "
|
||||||
|
"ببینید."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "تنها شما و دیگر نویسندگان میتوانید این نوشته را ویرایش کنید."
|
msgstr "تنها شما و دیگر نویسندگان میتوانید این نوشته را ویرایش کنید."
|
||||||
@@ -844,8 +911,12 @@ msgstr "بهروزرسانی گذرواژه"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "صندوق پستی خود را بررسی کنید!"
|
msgstr "صندوق پستی خود را بررسی کنید!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "ما، یک رایانامه به نشانیای که به ما دادید فرستادهایم. با پیوندی که در آن است میتوانید گذرواژه خود را تغییر دهید."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"ما، یک رایانامه به نشانیای که به ما دادید فرستادهایم. با پیوندی که در آن است "
|
||||||
|
"میتوانید گذرواژه خود را تغییر دهید."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "فرستادن پیوند بازنشانی گذرواژه"
|
msgstr "فرستادن پیوند بازنشانی گذرواژه"
|
||||||
@@ -853,8 +924,11 @@ msgstr "فرستادن پیوند بازنشانی گذرواژه"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "این توکن منقضی شده است"
|
msgstr "این توکن منقضی شده است"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "لطفاً برای شروع فرایند، <a href=\"/password-reset\">اینجا</a> کلیک کنید."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"لطفاً برای شروع فرایند، <a href=\"/password-reset\">اینجا</a> کلیک کنید."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "بلاگ جدید"
|
msgstr "بلاگ جدید"
|
||||||
@@ -868,8 +942,11 @@ msgstr "ایجاد بلاگ"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "ویرایش «{}»"
|
msgstr "ویرایش «{}»"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "میتوانید تصاویرتان را در نگارخانه بارگذاری کرده و از آنها به عنوان شکلک و یا تصویر سردر بلاگ استفاده کنید."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"میتوانید تصاویرتان را در نگارخانه بارگذاری کرده و از آنها به عنوان شکلک و یا "
|
||||||
|
"تصویر سردر بلاگ استفاده کنید."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "بارگذاری تصاویر"
|
msgstr "بارگذاری تصاویر"
|
||||||
@@ -887,7 +964,8 @@ msgid "Update blog"
|
|||||||
msgstr "بهروزرسانی بلاگ"
|
msgstr "بهروزرسانی بلاگ"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "حواستان خیلی جمع باشد! هر اقدامی که اینجا انجام دهید غیرقابل بازگشت است."
|
msgstr ""
|
||||||
|
"حواستان خیلی جمع باشد! هر اقدامی که اینجا انجام دهید غیرقابل بازگشت است."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "آیا مطمئن هستید که میخواهید این بلاگ را برای همیشه حذف کنید؟"
|
msgstr "آیا مطمئن هستید که میخواهید این بلاگ را برای همیشه حذف کنید؟"
|
||||||
@@ -928,10 +1006,16 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "پلوم یک موتور بلاگنویسی غیرمتمرکز است."
|
msgstr "پلوم یک موتور بلاگنویسی غیرمتمرکز است."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "نویسندگان میتوانند چندین بلاگ را مدیریت کنند که هر کدامشان مانند یک پایگاه وب مستقل هستند."
|
msgstr ""
|
||||||
|
"نویسندگان میتوانند چندین بلاگ را مدیریت کنند که هر کدامشان مانند یک پایگاه "
|
||||||
|
"وب مستقل هستند."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "نوشتهها در سایر نمونههای پلوم نیز قابل مشاهده هستند و شما میتوانید با آنها به صورت مستقیم و از دیگر بنسازهها مانند ماستدون تعامل داشته باشید."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"نوشتهها در سایر نمونههای پلوم نیز قابل مشاهده هستند و شما میتوانید با آنها "
|
||||||
|
"به صورت مستقیم و از دیگر بنسازهها مانند ماستدون تعامل داشته باشید."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "قوانین کامل را مطالعه کنید"
|
msgstr "قوانین کامل را مطالعه کنید"
|
||||||
@@ -1010,4 +1094,3 @@ msgstr "منتشر شده تحت این پروانه"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "پروانهٔ نوشته"
|
msgstr "پروانهٔ نوشته"
|
||||||
|
|
||||||
|
|||||||
+62
-21
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Artikkelisi on poistettu."
|
msgstr "Artikkelisi on poistettu."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Näyttää siltä, että koetat poistaa artikkelia jota ei ole olemassa. Ehkä se on jo poistettu?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Näyttää siltä, että koetat poistaa artikkelia jota ei ole olemassa. Ehkä se "
|
||||||
|
"on jo poistettu?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Tunnuksestasi ei saatu haettua tarpeeksi tietoja. Varmistathan että käyttäjätunkuksesi on oikein."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Tunnuksestasi ei saatu haettua tarpeeksi tietoja. Varmistathan että "
|
||||||
|
"käyttäjätunkuksesi on oikein."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +290,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +451,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +483,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +556,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +643,21 @@ msgstr "Oletus lisenssi artikelleille"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Tallenna nämä asetukset"
|
msgstr "Tallenna nämä asetukset"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr "Jos aelailet tätä sivua vierailijana, sinusta ei kerätä yhtään dataa."
|
msgstr "Jos aelailet tätä sivua vierailijana, sinusta ei kerätä yhtään dataa."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +666,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +678,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +760,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +820,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +879,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +890,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +907,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +970,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1052,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+134
-43
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Votre article a été supprimé."
|
msgstr "Votre article a été supprimé."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Il semble que l'article que vous avez essayé de supprimer n'existe pas. Peut-être a-t-il déjà été supprimé ?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Il semble que l'article que vous avez essayé de supprimer n'existe pas. Peut-"
|
||||||
|
"être a-t-il déjà été supprimé ?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Nous n'avons pas pu obtenir assez d'informations à propos de votre compte. Veuillez vous assurer que votre nom d'utilisateur est correct."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Nous n'avons pas pu obtenir assez d'informations à propos de votre compte. "
|
||||||
|
"Veuillez vous assurer que votre nom d'utilisateur est correct."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Les inscriptions sont fermées dans cette instance."
|
msgstr "Les inscriptions sont fermées dans cette instance."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Votre compte a été créé. Vous avez juste à vous connecter, avant de pouvoir l'utiliser."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Votre compte a été créé. Vous avez juste à vous connecter, avant de pouvoir "
|
||||||
|
"l'utiliser."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Téléversement de média"
|
msgstr "Téléversement de média"
|
||||||
@@ -292,7 +304,9 @@ msgid "Description"
|
|||||||
msgstr "Description"
|
msgstr "Description"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Utile pour les personnes malvoyantes, ainsi que pour les informations de licence"
|
msgstr ""
|
||||||
|
"Utile pour les personnes malvoyantes, ainsi que pour les informations de "
|
||||||
|
"licence"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Avertissement"
|
msgstr "Avertissement"
|
||||||
@@ -441,8 +455,12 @@ msgstr "Mot de passe"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Confirmation du mot de passe"
|
msgstr "Confirmation du mot de passe"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Désolé, mais les inscriptions sont fermées sur cette instance en particulier. Vous pouvez, toutefois, en trouver une autre."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Désolé, mais les inscriptions sont fermées sur cette instance en "
|
||||||
|
"particulier. Vous pouvez, toutefois, en trouver une autre."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Abonnements de {0}"
|
msgstr "Abonnements de {0}"
|
||||||
@@ -454,7 +472,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Vos Blogs"
|
msgstr "Vos Blogs"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Vous n'avez pas encore de blog. Créez votre propre blog, ou demandez de vous joindre à un."
|
msgstr ""
|
||||||
|
"Vous n'avez pas encore de blog. Créez votre propre blog, ou demandez de vous "
|
||||||
|
"joindre à un."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Commencer un nouveau blog"
|
msgstr "Commencer un nouveau blog"
|
||||||
@@ -471,8 +491,11 @@ msgstr "Modifier votre compte"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Votre Profile"
|
msgstr "Votre Profile"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Pour modifier votre avatar, téléversez-le dans votre galerie et sélectionner à partir de là."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Pour modifier votre avatar, téléversez-le dans votre galerie et sélectionner "
|
||||||
|
"à partir de là."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Téléverser un avatar"
|
msgstr "Téléverser un avatar"
|
||||||
@@ -508,7 +531,9 @@ msgid "Delete your account"
|
|||||||
msgstr "Supprimer votre compte"
|
msgstr "Supprimer votre compte"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Désolé, mais en tant qu'administrateur, vous ne pouvez pas laisser votre propre instance."
|
msgstr ""
|
||||||
|
"Désolé, mais en tant qu'administrateur, vous ne pouvez pas laisser votre "
|
||||||
|
"propre instance."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Derniers articles"
|
msgstr "Derniers articles"
|
||||||
@@ -538,13 +563,21 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Nous avons cassé quelque chose."
|
msgstr "Nous avons cassé quelque chose."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Nous sommes désolé⋅e⋅s. Si vous pensez que c’est un bogue, merci de le signaler."
|
msgstr ""
|
||||||
|
"Nous sommes désolé⋅e⋅s. Si vous pensez que c’est un bogue, merci de le "
|
||||||
|
"signaler."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Jeton CSRF invalide"
|
msgstr "Jeton CSRF invalide"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Quelque chose ne va pas avec votre jeton CSRF. Assurez-vous que les cookies sont activés dans votre navigateur, et essayez de recharger cette page. Si vous continuez à voir cette erreur, merci de la signaler."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Quelque chose ne va pas avec votre jeton CSRF. Assurez-vous que les cookies "
|
||||||
|
"sont activés dans votre navigateur, et essayez de recharger cette page. Si "
|
||||||
|
"vous continuez à voir cette erreur, merci de la signaler."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Vous n’avez pas les droits."
|
msgstr "Vous n’avez pas les droits."
|
||||||
@@ -627,14 +660,32 @@ msgstr "Licence d'article par défaut"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Sauvegarder ces paramètres"
|
msgstr "Sauvegarder ces paramètres"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Si vous naviguez sur ce site en tant que visiteur, aucune donnée ne vous concernant n'est collectée."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Si vous naviguez sur ce site en tant que visiteur, aucune donnée ne vous "
|
||||||
|
"concernant n'est collectée."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "En tant qu'utilisateur enregistré, vous devez fournir votre nom d'utilisateur (qui n'est pas forcément votre vrai nom), votre adresse e-mail fonctionnelle et un mot de passe, afin de pouvoir vous connecter, écrire des articles et commenter. Le contenu que vous soumettez est stocké jusqu'à ce que vous le supprimiez."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"En tant qu'utilisateur enregistré, vous devez fournir votre nom "
|
||||||
|
"d'utilisateur (qui n'est pas forcément votre vrai nom), votre adresse e-mail "
|
||||||
|
"fonctionnelle et un mot de passe, afin de pouvoir vous connecter, écrire des "
|
||||||
|
"articles et commenter. Le contenu que vous soumettez est stocké jusqu'à ce "
|
||||||
|
"que vous le supprimiez."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Lorsque vous vous connectez, nous stockons deux cookies, l'un pour garder votre session ouverte, le second pour empêcher d'autres personnes d'agir en votre nom. Nous ne stockons aucun autre cookie."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Lorsque vous vous connectez, nous stockons deux cookies, l'un pour garder "
|
||||||
|
"votre session ouverte, le second pour empêcher d'autres personnes d'agir en "
|
||||||
|
"votre nom. Nous ne stockons aucun autre cookie."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Emails bloqués"
|
msgstr "Emails bloqués"
|
||||||
@@ -642,8 +693,14 @@ msgstr "Emails bloqués"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Adresse mail"
|
msgstr "Adresse mail"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "L'adresse e-mail que vous souhaitez bloquer. Pour bloquer des domaines, vous pouvez utiliser la syntaxe : '*@example.com' qui bloque toutes les adresses du domain exemple.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"L'adresse e-mail que vous souhaitez bloquer. Pour bloquer des domaines, vous "
|
||||||
|
"pouvez utiliser la syntaxe : '*@example.com' qui bloque toutes les adresses "
|
||||||
|
"du domain exemple.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Note"
|
msgstr "Note"
|
||||||
@@ -651,14 +708,21 @@ msgstr "Note"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Notifier l'utilisateurice ?"
|
msgstr "Notifier l'utilisateurice ?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Optionnel, affiche un message lors de la création d'un compte avec cette adresse"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Optionnel, affiche un message lors de la création d'un compte avec cette "
|
||||||
|
"adresse"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Notification de blocage"
|
msgstr "Notification de blocage"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Le message à afficher lors de la création d'un compte avec cette adresse mail"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Le message à afficher lors de la création d'un compte avec cette adresse mail"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Bloquer une adresse"
|
msgstr "Bloquer une adresse"
|
||||||
@@ -729,8 +793,12 @@ msgstr "Sous-titre"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Contenu"
|
msgstr "Contenu"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Vous pouvez télécharger des médias dans votre galerie, et copier leur code Markdown dans vos articles pour les insérer."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Vous pouvez télécharger des médias dans votre galerie, et copier leur code "
|
||||||
|
"Markdown dans vos articles pour les insérer."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Téléverser un média"
|
msgstr "Téléverser un média"
|
||||||
@@ -787,8 +855,12 @@ msgstr "Je ne veux plus le repartager"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Partager"
|
msgstr "Partager"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Connectez-vous{1}, ou {2}utilisez votre compte sur le Fediverse{3} pour interagir avec cet article"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Connectez-vous{1}, ou {2}utilisez votre compte sur le Fediverse{3} pour "
|
||||||
|
"interagir avec cet article"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Commentaires"
|
msgstr "Commentaires"
|
||||||
@@ -806,7 +878,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "Êtes-vous sûr⋅e ?"
|
msgstr "Êtes-vous sûr⋅e ?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Cet article est toujours un brouillon. Seuls vous et les autres auteur·e·s peuvent le voir."
|
msgstr ""
|
||||||
|
"Cet article est toujours un brouillon. Seuls vous et les autres auteur·e·s "
|
||||||
|
"peuvent le voir."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Seuls vous et les autres auteur·e·s peuvent modifier cet article."
|
msgstr "Seuls vous et les autres auteur·e·s peuvent modifier cet article."
|
||||||
@@ -844,8 +918,12 @@ msgstr "Mettre à jour le mot de passe"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Vérifiez votre boîte de réception!"
|
msgstr "Vérifiez votre boîte de réception!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Nous avons envoyé un mail à l'adresse que vous nous avez donnée, avec un lien pour réinitialiser votre mot de passe."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Nous avons envoyé un mail à l'adresse que vous nous avez donnée, avec un "
|
||||||
|
"lien pour réinitialiser votre mot de passe."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Envoyer un lien pour réinitialiser le mot de passe"
|
msgstr "Envoyer un lien pour réinitialiser le mot de passe"
|
||||||
@@ -853,8 +931,12 @@ msgstr "Envoyer un lien pour réinitialiser le mot de passe"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Ce jeton a expiré"
|
msgstr "Ce jeton a expiré"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Veuillez recommencer le processus en cliquant <a href=\"/password-reset\">ici</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Veuillez recommencer le processus en cliquant <a href=\"/password-reset"
|
||||||
|
"\">ici</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Nouveau Blog"
|
msgstr "Nouveau Blog"
|
||||||
@@ -868,8 +950,11 @@ msgstr "Créer le blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Modifier \"{}\""
|
msgstr "Modifier \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Vous pouvez téléverser des images dans votre galerie, pour les utiliser comme icônes de blog ou illustrations."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Vous pouvez téléverser des images dans votre galerie, pour les utiliser "
|
||||||
|
"comme icônes de blog ou illustrations."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Téléverser des images"
|
msgstr "Téléverser des images"
|
||||||
@@ -928,10 +1013,17 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Plume est un moteur de blog décentralisé."
|
msgstr "Plume est un moteur de blog décentralisé."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Les auteurs peuvent avoir plusieurs blogs, chacun étant comme un site indépendant."
|
msgstr ""
|
||||||
|
"Les auteurs peuvent avoir plusieurs blogs, chacun étant comme un site "
|
||||||
|
"indépendant."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Les articles sont également visibles sur d'autres instances Plume, et vous pouvez interagir avec eux directement à partir d'autres plateformes comme Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Les articles sont également visibles sur d'autres instances Plume, et vous "
|
||||||
|
"pouvez interagir avec eux directement à partir d'autres plateformes comme "
|
||||||
|
"Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Lire les règles détaillées"
|
msgstr "Lire les règles détaillées"
|
||||||
@@ -1010,4 +1102,3 @@ msgstr "Placé sous cette licence"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licence de l'article"
|
msgstr "Licence de l'article"
|
||||||
|
|
||||||
|
|||||||
+113
-38
@@ -214,12 +214,19 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Eliminouse o artigo."
|
msgstr "Eliminouse o artigo."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Semella que o artigo que quere eliminar non existe. Igual xa foi eliminado?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Semella que o artigo que quere eliminar non existe. Igual xa foi eliminado?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Non se puido obter información suficiente sobre a súa conta. Por favor asegúrese de que o nome de usuaria é correcto."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Non se puido obter información suficiente sobre a súa conta. Por favor "
|
||||||
|
"asegúrese de que o nome de usuaria é correcto."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +289,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "O rexistro está pechado en esta instancia."
|
msgstr "O rexistro está pechado en esta instancia."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr "Creouse a túa conta. Agora só tes que conectarte para poder utilizala."
|
msgstr "Creouse a túa conta. Agora só tes que conectarte para poder utilizala."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -292,7 +301,8 @@ msgid "Description"
|
|||||||
msgstr "Descrición"
|
msgstr "Descrición"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Útil para persoas con deficiencias visuais, así como información da licenza"
|
msgstr ""
|
||||||
|
"Útil para persoas con deficiencias visuais, así como información da licenza"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Aviso sobre o contido"
|
msgstr "Aviso sobre o contido"
|
||||||
@@ -441,8 +451,12 @@ msgstr "Contrasinal"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Confirmación do contrasinal"
|
msgstr "Confirmación do contrasinal"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Desculpe, pero o rexistro en esta instancia está pechado. Porén pode atopar outra no fediverso."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Desculpe, pero o rexistro en esta instancia está pechado. Porén pode atopar "
|
||||||
|
"outra no fediverso."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Suscricións de {0}"
|
msgstr "Suscricións de {0}"
|
||||||
@@ -471,8 +485,11 @@ msgstr "Edite a súa conta"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "O seu Perfil"
|
msgstr "O seu Perfil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Para cambiar o avatar, suba a imaxe a súa galería e despois escollaa desde alí."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Para cambiar o avatar, suba a imaxe a súa galería e despois escollaa desde "
|
||||||
|
"alí."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Subir un avatar"
|
msgstr "Subir un avatar"
|
||||||
@@ -508,7 +525,9 @@ msgid "Delete your account"
|
|||||||
msgstr "Eliminar a súa conta"
|
msgstr "Eliminar a súa conta"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Lamentámolo, pero como administradora, non pode deixar a súa propia instancia."
|
msgstr ""
|
||||||
|
"Lamentámolo, pero como administradora, non pode deixar a súa propia "
|
||||||
|
"instancia."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Últimos artigos"
|
msgstr "Últimos artigos"
|
||||||
@@ -543,8 +562,14 @@ msgstr "Lamentálmolo. Si cree que é un bug, infórmenos por favor."
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Testemuño CSRF non válido"
|
msgstr "Testemuño CSRF non válido"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Hai un problema co seu testemuño CSRF. Asegúrese de ter as cookies activadas no navegador, e recargue a páxina. Si persiste o aviso de este fallo, informe por favor."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Hai un problema co seu testemuño CSRF. Asegúrese de ter as cookies activadas "
|
||||||
|
"no navegador, e recargue a páxina. Si persiste o aviso de este fallo, "
|
||||||
|
"informe por favor."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Non ten permiso."
|
msgstr "Non ten permiso."
|
||||||
@@ -627,14 +652,29 @@ msgstr "Licenza por omisión dos artigos"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Gardar estas preferencias"
|
msgstr "Gardar estas preferencias"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr "Se estás lendo esta web como visitante non se recollen datos sobre ti."
|
msgstr "Se estás lendo esta web como visitante non se recollen datos sobre ti."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Como usuaria rexistrada, tes que proporcionar un nome de usuaria (que non ten que ser o teu nome real), un enderezo activo de correo electrónico e un contrasinal, para poder conectarte, escribir artigos e comentar. O contido que envíes permanece ata que o borres."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Como usuaria rexistrada, tes que proporcionar un nome de usuaria (que non "
|
||||||
|
"ten que ser o teu nome real), un enderezo activo de correo electrónico e un "
|
||||||
|
"contrasinal, para poder conectarte, escribir artigos e comentar. O contido "
|
||||||
|
"que envíes permanece ata que o borres."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Cando te conectas, gardamos dous testemuños, un para manter a sesión aberta e o segundo para previr que outra xente actúe no teu nome. Non gardamos máis testemuños."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Cando te conectas, gardamos dous testemuños, un para manter a sesión aberta "
|
||||||
|
"e o segundo para previr que outra xente actúe no teu nome. Non gardamos máis "
|
||||||
|
"testemuños."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Emails na lista de bloqueo"
|
msgstr "Emails na lista de bloqueo"
|
||||||
@@ -642,8 +682,14 @@ msgstr "Emails na lista de bloqueo"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Enderezo de email"
|
msgstr "Enderezo de email"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "O enderezo de email que queres bloquear. Para poder bloquear dominios, podes usar sintaxe globbing, por exemplo '*@exemplo.com' bloquea todos os enderezos de exemplo.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"O enderezo de email que queres bloquear. Para poder bloquear dominios, podes "
|
||||||
|
"usar sintaxe globbing, por exemplo '*@exemplo.com' bloquea todos os "
|
||||||
|
"enderezos de exemplo.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Nota"
|
msgstr "Nota"
|
||||||
@@ -651,14 +697,22 @@ msgstr "Nota"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Notificar a usuaria?"
|
msgstr "Notificar a usuaria?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Optativo, mostra unha mensaxe a usuaria cando intenta crear unha conta con ese enderezo"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Optativo, mostra unha mensaxe a usuaria cando intenta crear unha conta con "
|
||||||
|
"ese enderezo"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Notificación do bloqueo"
|
msgstr "Notificación do bloqueo"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "A mensaxe será amosada cando a usuaria intente crear unha conta on ese enderezo de email"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"A mensaxe será amosada cando a usuaria intente crear unha conta on ese "
|
||||||
|
"enderezo de email"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Engadir a lista de bloqueo"
|
msgstr "Engadir a lista de bloqueo"
|
||||||
@@ -729,8 +783,12 @@ msgstr "Subtítulo"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Contido"
|
msgstr "Contido"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Pode subir medios a galería e despois copiar o seu código Markdown nos artigos para incrustalos."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Pode subir medios a galería e despois copiar o seu código Markdown nos "
|
||||||
|
"artigos para incrustalos."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Subir medios"
|
msgstr "Subir medios"
|
||||||
@@ -787,8 +845,12 @@ msgstr "Xa non quero promocionar este artigo"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Promover"
|
msgstr "Promover"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Conectar{1}, ou {2}utilice a súa conta no Fediverso{3} para interactuar con este artigo"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Conectar{1}, ou {2}utilice a súa conta no Fediverso{3} para interactuar "
|
||||||
|
"con este artigo"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Comentarios"
|
msgstr "Comentarios"
|
||||||
@@ -844,8 +906,12 @@ msgstr "Actualizar contrasinal"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Comprobe o seu correo!"
|
msgstr "Comprobe o seu correo!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Enviamoslle un correo ao enderezo que nos deu, con unha ligazón para restablecer o contrasinal."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Enviamoslle un correo ao enderezo que nos deu, con unha ligazón para "
|
||||||
|
"restablecer o contrasinal."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Enviar ligazón para restablecer contrasinal"
|
msgstr "Enviar ligazón para restablecer contrasinal"
|
||||||
@@ -853,8 +919,11 @@ msgstr "Enviar ligazón para restablecer contrasinal"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "O testemuño caducou"
|
msgstr "O testemuño caducou"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Inicia o preceso de novo premendo <a href=\"/password-reset\">aquí</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Inicia o preceso de novo premendo <a href=\"/password-reset\">aquí</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Novo Blog"
|
msgstr "Novo Blog"
|
||||||
@@ -868,8 +937,10 @@ msgstr "Crear blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Editar \"{}\""
|
msgstr "Editar \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Pode subir imaxes a súa galería, e utilizalas como iconas do blog ou banners."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Pode subir imaxes a súa galería, e utilizalas como iconas do blog ou banners."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Subir imaxes"
|
msgstr "Subir imaxes"
|
||||||
@@ -928,10 +999,15 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Plume é un motor de publicación descentralizada."
|
msgstr "Plume é un motor de publicación descentralizada."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "As autoras poden xestionar múltiples blogs, cada un no seu propio sitio web."
|
msgstr ""
|
||||||
|
"As autoras poden xestionar múltiples blogs, cada un no seu propio sitio web."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Os artigos tamén son visibles en outras instancias Plume, e pode interactuar con eles directamente ou desde plataformas como Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Os artigos tamén son visibles en outras instancias Plume, e pode interactuar "
|
||||||
|
"con eles directamente ou desde plataformas como Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Lea o detalle das normas"
|
msgstr "Lea o detalle das normas"
|
||||||
@@ -1010,4 +1086,3 @@ msgstr "Publicado baixo esta licenza"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licenza do artigo"
|
msgstr "Licenza do artigo"
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
|
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n"
|
||||||
|
"%100==4 ? 2 : 3;\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: he\n"
|
"X-Crowdin-Language: he\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +448,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +480,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -791,7 +821,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -848,7 +880,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -857,7 +891,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -872,7 +908,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -936,7 +973,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1016,4 +1055,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+62
-21
@@ -214,12 +214,18 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "आपके अकाउंट के बारे में पर्याप्त जानकारी नहीं मिल पायी. कृपया जांच करें की आपका यूजरनाम सही है."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"आपके अकाउंट के बारे में पर्याप्त जानकारी नहीं मिल पायी. कृपया जांच करें की आपका यूजरनाम "
|
||||||
|
"सही है."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +288,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +449,9 @@ msgstr "पासवर्ड"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +481,8 @@ msgstr "अपने अकाउंट में बदलाव करें"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "आपकी प्रोफाइल"
|
msgstr "आपकी प्रोफाइल"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +554,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +641,21 @@ msgstr "डिफ़ॉल्ट आलेख लायसेंस"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "इन सेटिंग्स को सेव करें"
|
msgstr "इन सेटिंग्स को सेव करें"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +664,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +676,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +758,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,8 +818,12 @@ msgstr "मुझे अब इसे बूस्ट नहीं करना
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "बूस्ट"
|
msgstr "बूस्ट"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}लोग इन करें{1}, या {2}आपके फेडिवेर्से अकाउंट का इस्तेमाल करें{3} इस आर्टिकल से इंटरैक्ट करने के लिए"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}लोग इन करें{1}, या {2}आपके फेडिवेर्से अकाउंट का इस्तेमाल करें{3} इस आर्टिकल से इंटरैक्ट "
|
||||||
|
"करने के लिए"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "कमैंट्स"
|
msgstr "कमैंट्स"
|
||||||
@@ -844,7 +879,9 @@ msgstr "पासवर्ड अपडेट करें"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "आपका इनबॉक्स चेक करें"
|
msgstr "आपका इनबॉक्स चेक करें"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr "हमने आपके दिए गए इ-मेल पे पासवर्ड रिसेट लिंक भेज दिया है."
|
msgstr "हमने आपके दिए गए इ-मेल पे पासवर्ड रिसेट लिंक भेज दिया है."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +890,9 @@ msgstr "पासवर्ड रिसेट करने के लिए ल
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +907,8 @@ msgstr "ब्लॉग बनाएं"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "{0} में बदलाव करें"
|
msgstr "{0} में बदलाव करें"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr "आप गैलरी में फोटो दाल कर, उनका ब्लॉग आइकॉन या बैनर के लिए उपयोग कर सकते हैं"
|
msgstr "आप गैलरी में फोटो दाल कर, उनका ब्लॉग आइकॉन या बैनर के लिए उपयोग कर सकते हैं"
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +970,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1052,3 @@ msgstr "इस लिसेंसे के साथ पब्लिश कि
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "आर्टिकल लाइसेंस"
|
msgstr "आर्टिकल लाइसेंस"
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: hr\n"
|
"X-Crowdin-Language: hr\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +448,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +480,8 @@ msgstr "Uredite svoj račun"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Tvoj Profil"
|
msgstr "Tvoj Profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -789,7 +819,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -846,7 +878,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -855,7 +889,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -870,7 +906,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -933,7 +970,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1013,4 +1052,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+128
-42
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Il tuo articolo è stato eliminato."
|
msgstr "Il tuo articolo è stato eliminato."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Sembra che l'articolo che cerchi di eliminare non esista. Forse è già stato cancellato?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Sembra che l'articolo che cerchi di eliminare non esista. Forse è già stato "
|
||||||
|
"cancellato?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Non è stato possibile ottenere abbastanza informazioni sul tuo account. Per favore assicurati che il tuo nome utente sia corretto."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Non è stato possibile ottenere abbastanza informazioni sul tuo account. Per "
|
||||||
|
"favore assicurati che il tuo nome utente sia corretto."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Le registrazioni sono chiuse su questa istanza."
|
msgstr "Le registrazioni sono chiuse su questa istanza."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Il tuo account è stato creato. Ora devi solo effettuare l'accesso prima di poterlo utilizzare."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Il tuo account è stato creato. Ora devi solo effettuare l'accesso prima di "
|
||||||
|
"poterlo utilizzare."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Caricamento di un media"
|
msgstr "Caricamento di un media"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Password"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Conferma password"
|
msgstr "Conferma password"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Spiacenti, ma le registrazioni sono chiuse per questa istanza. Puoi comunque trovarne un'altra."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Spiacenti, ma le registrazioni sono chiuse per questa istanza. Puoi comunque "
|
||||||
|
"trovarne un'altra."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Iscrizioni di {0}"
|
msgstr "Iscrizioni di {0}"
|
||||||
@@ -454,7 +470,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "I Tuoi Blog"
|
msgstr "I Tuoi Blog"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Non hai ancora nessun blog. Creane uno tuo, o chiedi di unirti ad uno esistente."
|
msgstr ""
|
||||||
|
"Non hai ancora nessun blog. Creane uno tuo, o chiedi di unirti ad uno "
|
||||||
|
"esistente."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Inizia un nuovo blog"
|
msgstr "Inizia un nuovo blog"
|
||||||
@@ -471,8 +489,11 @@ msgstr "Modifica il tuo account"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Il Tuo Profilo"
|
msgstr "Il Tuo Profilo"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Per modificare la tua immagine di profilo, caricala nella tua galleria e poi selezionala da là."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Per modificare la tua immagine di profilo, caricala nella tua galleria e poi "
|
||||||
|
"selezionala da là."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Carica un'immagine di profilo"
|
msgstr "Carica un'immagine di profilo"
|
||||||
@@ -502,7 +523,8 @@ msgid "Danger zone"
|
|||||||
msgstr "Zona pericolosa"
|
msgstr "Zona pericolosa"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr "Fai molta attenzione, qualsiasi scelta fatta qui non può essere annullata."
|
msgstr ""
|
||||||
|
"Fai molta attenzione, qualsiasi scelta fatta qui non può essere annullata."
|
||||||
|
|
||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Elimina il tuo account"
|
msgstr "Elimina il tuo account"
|
||||||
@@ -543,8 +565,14 @@ msgstr "Scusa per questo. Se pensi sia un bug, per favore segnalacelo."
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Token CSRF non valido"
|
msgstr "Token CSRF non valido"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Qualcosa è andato storto con il tuo token CSRF. Assicurati di aver abilitato i cookies nel tuo browser, e prova a ricaricare questa pagina. Se l'errore si dovesse ripresentare, per favore segnalacelo."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Qualcosa è andato storto con il tuo token CSRF. Assicurati di aver abilitato "
|
||||||
|
"i cookies nel tuo browser, e prova a ricaricare questa pagina. Se l'errore "
|
||||||
|
"si dovesse ripresentare, per favore segnalacelo."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Non sei autorizzato."
|
msgstr "Non sei autorizzato."
|
||||||
@@ -627,14 +655,31 @@ msgstr "Licenza predefinita degli articoli"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Salva queste impostazioni"
|
msgstr "Salva queste impostazioni"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Se stai navigando in questo sito come visitatore, non vengono raccolti dati su di te."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Se stai navigando in questo sito come visitatore, non vengono raccolti dati "
|
||||||
|
"su di te."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Come utente registrato, devi fornire il tuo nome utente (che può anche non essere il tuo vero nome), un tuo indirizzo email funzionante e una password, per poter accedere, scrivere articoli e commenti. Il contenuto che invii è memorizzato fino a quando non lo elimini."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Come utente registrato, devi fornire il tuo nome utente (che può anche non "
|
||||||
|
"essere il tuo vero nome), un tuo indirizzo email funzionante e una password, "
|
||||||
|
"per poter accedere, scrivere articoli e commenti. Il contenuto che invii è "
|
||||||
|
"memorizzato fino a quando non lo elimini."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Quando accedi, conserviamo due cookie, uno per mantenere aperta la sessione, il secondo per impedire ad altre persone di agire al tuo posto. Non conserviamo nessun altro cookie."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Quando accedi, conserviamo due cookie, uno per mantenere aperta la sessione, "
|
||||||
|
"il secondo per impedire ad altre persone di agire al tuo posto. Non "
|
||||||
|
"conserviamo nessun altro cookie."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Email Blocklist"
|
msgstr "Email Blocklist"
|
||||||
@@ -642,8 +687,14 @@ msgstr "Email Blocklist"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Indirizzo email"
|
msgstr "Indirizzo email"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "L'indirizzo email che vuoi bloccare. Per bloccare i domini, puoi usare la sintassi di globbing, per esempio '*@example.com' blocca tutti gli indirizzi da example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"L'indirizzo email che vuoi bloccare. Per bloccare i domini, puoi usare la "
|
||||||
|
"sintassi di globbing, per esempio '*@example.com' blocca tutti gli indirizzi "
|
||||||
|
"da example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Nota"
|
msgstr "Nota"
|
||||||
@@ -651,14 +702,22 @@ msgstr "Nota"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Notifica l'utente?"
|
msgstr "Notifica l'utente?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Opzionale, mostra un messaggio all'utente quando tenta di creare un conto con quell'indirizzo"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Opzionale, mostra un messaggio all'utente quando tenta di creare un conto "
|
||||||
|
"con quell'indirizzo"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Notifica di blocklist"
|
msgstr "Notifica di blocklist"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Il messaggio da mostrare quando l'utente tenta di creare un profilo con questo indirizzo email"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Il messaggio da mostrare quando l'utente tenta di creare un profilo con "
|
||||||
|
"questo indirizzo email"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Aggiungi indirizzo messo in blocklist"
|
msgstr "Aggiungi indirizzo messo in blocklist"
|
||||||
@@ -729,8 +788,12 @@ msgstr "Sottotitolo"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Contenuto"
|
msgstr "Contenuto"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Puoi caricare media nella tua galleria, e poi copiare il loro codice Markdown nei tuoi articoli per inserirli."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Puoi caricare media nella tua galleria, e poi copiare il loro codice "
|
||||||
|
"Markdown nei tuoi articoli per inserirli."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Carica media"
|
msgstr "Carica media"
|
||||||
@@ -787,8 +850,12 @@ msgstr "Non voglio più boostare questo"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Boost"
|
msgstr "Boost"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Accedi{1}, o {2}usa il tuo account del Fediverso{3} per interagire con questo articolo"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Accedi{1}, o {2}usa il tuo account del Fediverso{3} per interagire con "
|
||||||
|
"questo articolo"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Commenti"
|
msgstr "Commenti"
|
||||||
@@ -806,7 +873,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "Sei sicuro?"
|
msgstr "Sei sicuro?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Questo articolo è ancora una bozza. Solo voi e gli altri autori la potete vedere."
|
msgstr ""
|
||||||
|
"Questo articolo è ancora una bozza. Solo voi e gli altri autori la potete "
|
||||||
|
"vedere."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Solo tu e gli altri autori potete modificare questo articolo."
|
msgstr "Solo tu e gli altri autori potete modificare questo articolo."
|
||||||
@@ -844,8 +913,12 @@ msgstr "Aggiorna password"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Controlla la tua casella di posta in arrivo!"
|
msgstr "Controlla la tua casella di posta in arrivo!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Ti abbiamo inviato una mail all'indirizzo che ci hai fornito, con il collegamento per reimpostare la tua password."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Ti abbiamo inviato una mail all'indirizzo che ci hai fornito, con il "
|
||||||
|
"collegamento per reimpostare la tua password."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Invia collegamento per reimpostare la password"
|
msgstr "Invia collegamento per reimpostare la password"
|
||||||
@@ -853,8 +926,12 @@ msgstr "Invia collegamento per reimpostare la password"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Questo token è scaduto"
|
msgstr "Questo token è scaduto"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Sei pregato di riavviare il processo cliccando <a href=\"/password-reset\">qui</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Sei pregato di riavviare il processo cliccando <a href=\"/password-reset"
|
||||||
|
"\">qui</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Nuovo Blog"
|
msgstr "Nuovo Blog"
|
||||||
@@ -868,8 +945,11 @@ msgstr "Crea blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Modifica \"{}\""
|
msgstr "Modifica \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Puoi caricare immagini nella tua galleria, ed utilizzarle come icone del blog, o copertine."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Puoi caricare immagini nella tua galleria, ed utilizzarle come icone del "
|
||||||
|
"blog, o copertine."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Carica immagini"
|
msgstr "Carica immagini"
|
||||||
@@ -887,7 +967,8 @@ msgid "Update blog"
|
|||||||
msgstr "Aggiorna blog"
|
msgstr "Aggiorna blog"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Fai molta attenzione, qualsiasi scelta fatta qui non può essere annullata."
|
msgstr ""
|
||||||
|
"Fai molta attenzione, qualsiasi scelta fatta qui non può essere annullata."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "Sei sicuro di voler eliminare permanentemente questo blog?"
|
msgstr "Sei sicuro di voler eliminare permanentemente questo blog?"
|
||||||
@@ -928,10 +1009,16 @@ msgid "Plume is a decentralized blogging engine."
|
|||||||
msgstr "Plume è un motore di blog decentralizzato."
|
msgstr "Plume è un motore di blog decentralizzato."
|
||||||
|
|
||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Gli autori possono gestire blog multipli, ognuno come fosse un sito web differente."
|
msgstr ""
|
||||||
|
"Gli autori possono gestire blog multipli, ognuno come fosse un sito web "
|
||||||
|
"differente."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Gli articoli sono anche visibili su altre istanze Plume, e puoi interagire con loro direttamente da altre piattaforme come Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Gli articoli sono anche visibili su altre istanze Plume, e puoi interagire "
|
||||||
|
"con loro direttamente da altre piattaforme come Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Leggi le regole dettagliate"
|
msgstr "Leggi le regole dettagliate"
|
||||||
@@ -1010,4 +1097,3 @@ msgstr "Pubblicato sotto questa licenza"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licenza dell'articolo"
|
msgstr "Licenza dell'articolo"
|
||||||
|
|
||||||
|
|||||||
+110
-37
@@ -214,12 +214,19 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "投稿を削除しました。"
|
msgstr "投稿を削除しました。"
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "削除しようとしている投稿は存在しないようです。すでに削除していませんか?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"削除しようとしている投稿は存在しないようです。すでに削除していませんか?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "お使いのアカウントに関する十分な情報を取得できませんでした。ご自身のユーザー名が正しいことを確認してください。"
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"お使いのアカウントに関する十分な情報を取得できませんでした。ご自身のユーザー"
|
||||||
|
"名が正しいことを確認してください。"
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +289,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "登録はこのインスタンス内に限定されています。"
|
msgstr "登録はこのインスタンス内に限定されています。"
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr "アカウントを作成しました。使用前に、ログインする必要があります。"
|
msgstr "アカウントを作成しました。使用前に、ログインする必要があります。"
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,8 +450,12 @@ msgstr "パスワード"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "パスワードの確認"
|
msgstr "パスワードの確認"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "申し訳ありませんが、このインスタンスでの登録は限定されています。ですが、他のインスタンスを見つけることはできます。"
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"申し訳ありませんが、このインスタンスでの登録は限定されています。ですが、他の"
|
||||||
|
"インスタンスを見つけることはできます。"
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0} がフォロー中のユーザー"
|
msgstr "{0} がフォロー中のユーザー"
|
||||||
@@ -454,7 +467,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "ブログ"
|
msgstr "ブログ"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "ブログはまだありません。ご自身のブログを作成するか、他の人のブログに参加できるか確認しましょう。"
|
msgstr ""
|
||||||
|
"ブログはまだありません。ご自身のブログを作成するか、他の人のブログに参加でき"
|
||||||
|
"るか確認しましょう。"
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "新しいブログを開始"
|
msgstr "新しいブログを開始"
|
||||||
@@ -471,7 +486,8 @@ msgstr "アカウントを編集"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "プロフィール"
|
msgstr "プロフィール"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr "アバターを変更するには、ギャラリーにアップロードして選択してください。"
|
msgstr "アバターを変更するには、ギャラリーにアップロードして選択してください。"
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -538,13 +554,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "サーバー側で何らかの問題が発生しました。"
|
msgstr "サーバー側で何らかの問題が発生しました。"
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "申し訳ありません。これがバグだと思われる場合は、問題を報告してください。"
|
msgstr ""
|
||||||
|
"申し訳ありません。これがバグだと思われる場合は、問題を報告してください。"
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "無効な CSRF トークンです"
|
msgstr "無効な CSRF トークンです"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "CSRF トークンに問題が発生しました。お使いのブラウザーで Cookie が有効になっていることを確認して、このページを再読み込みしてみてください。このエラーメッセージが表示され続ける場合は、問題を報告してください。"
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"CSRF トークンに問題が発生しました。お使いのブラウザーで Cookie が有効になって"
|
||||||
|
"いることを確認して、このページを再読み込みしてみてください。このエラーメッ"
|
||||||
|
"セージが表示され続ける場合は、問題を報告してください。"
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "許可されていません。"
|
msgstr "許可されていません。"
|
||||||
@@ -627,14 +650,31 @@ msgstr "投稿のデフォルトのライセンス"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "設定を保存"
|
msgstr "設定を保存"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "閲覧者としてこのサイトをご覧になっている場合、ご自身のデータは一切収集されません。"
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"閲覧者としてこのサイトをご覧になっている場合、ご自身のデータは一切収集されま"
|
||||||
|
"せん。"
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "登録ユーザーの場合、ログインしたり記事やコメントを投稿したりできるようにするため、ご自身のユーザー名(本名である必要はありません)、利用可能なメールアドレス、パスワードを指定する必要があります。投稿したコンテンツは、削除しない限り保存されます。"
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"登録ユーザーの場合、ログインしたり記事やコメントを投稿したりできるようにする"
|
||||||
|
"ため、ご自身のユーザー名(本名である必要はありません)、利用可能なメールアド"
|
||||||
|
"レス、パスワードを指定する必要があります。投稿したコンテンツは、削除しない限"
|
||||||
|
"り保存されます。"
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "ログインの際に、2 個の Cookie を保存します。1 つはセッションを開いた状態にするため、もう 1 つは誰かがあなたになりすますのを防ぐために使われます。この他には、一切の Cookie を保存しません。"
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"ログインの際に、2 個の Cookie を保存します。1 つはセッションを開いた状態にす"
|
||||||
|
"るため、もう 1 つは誰かがあなたになりすますのを防ぐために使われます。この他に"
|
||||||
|
"は、一切の Cookie を保存しません。"
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "ブロックするメール"
|
msgstr "ブロックするメール"
|
||||||
@@ -642,8 +682,13 @@ msgstr "ブロックするメール"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "メールアドレス"
|
msgstr "メールアドレス"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "ブロックするメールアドレス。*記法を使ってドメインをブロックすることができます。例えば '*@example.com' はexample.com の全てのアドレスをブロックします。"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"ブロックするメールアドレス。*記法を使ってドメインをブロックすることができま"
|
||||||
|
"す。例えば '*@example.com' はexample.com の全てのアドレスをブロックします。"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "メモ"
|
msgstr "メモ"
|
||||||
@@ -651,14 +696,21 @@ msgstr "メモ"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "ユーザーに知らせるか?"
|
msgstr "ユーザーに知らせるか?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "省略可。このアドレスでアカウントを作ろうとした時にユーザーにメッセージを表示します"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"省略可。このアドレスでアカウントを作ろうとした時にユーザーにメッセージを表示"
|
||||||
|
"します"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "ブロックリストの通知"
|
msgstr "ブロックリストの通知"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "ユーザーがこのメールアドレスでアカウントを作ろうとした時に表示するメッセージ"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"ユーザーがこのメールアドレスでアカウントを作ろうとした時に表示するメッセージ"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "ブロックするアドレスを追加"
|
msgstr "ブロックするアドレスを追加"
|
||||||
@@ -729,8 +781,12 @@ msgstr "サブタイトル"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "コンテンツ"
|
msgstr "コンテンツ"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "メディアをギャラリーにアップロードして、その Markdown コードをコピーして投稿に挿入できます。"
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"メディアをギャラリーにアップロードして、その Markdown コードをコピーして投稿"
|
||||||
|
"に挿入できます。"
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "メディアをアップロード"
|
msgstr "メディアをアップロード"
|
||||||
@@ -785,8 +841,12 @@ msgstr "このブーストを取り消します"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "ブースト"
|
msgstr "ブースト"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "この記事と関わるには{0}ログイン{1}するか {2}Fediverse アカウントを使用{3}してください"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"この記事と関わるには{0}ログイン{1}するか {2}Fediverse アカウントを使用{3}して"
|
||||||
|
"ください"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "コメント"
|
msgstr "コメント"
|
||||||
@@ -842,8 +902,12 @@ msgstr "パスワードを更新"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "受信トレイを確認してください!"
|
msgstr "受信トレイを確認してください!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "指定された宛先に、パスワードをリセットするためのリンクを記載したメールを送信しました。"
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"指定された宛先に、パスワードをリセットするためのリンクを記載したメールを送信"
|
||||||
|
"しました。"
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "パスワードリセットリンクを送信"
|
msgstr "パスワードリセットリンクを送信"
|
||||||
@@ -851,8 +915,12 @@ msgstr "パスワードリセットリンクを送信"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "このトークンは有効期限切れです"
|
msgstr "このトークンは有効期限切れです"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "<a href=\"/password-reset\">こちら</a>をクリックして、手順をやり直してください。"
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"<a href=\"/password-reset\">こちら</a>をクリックして、手順をやり直してくださ"
|
||||||
|
"い。"
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "新しいブログ"
|
msgstr "新しいブログ"
|
||||||
@@ -866,8 +934,10 @@ msgstr "ブログを作成"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "\"{}\" を編集"
|
msgstr "\"{}\" を編集"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "ギャラリーにアップロードした画像を、ブログアイコンやバナーに使用できます。"
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"ギャラリーにアップロードした画像を、ブログアイコンやバナーに使用できます。"
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "画像をアップロード"
|
msgstr "画像をアップロード"
|
||||||
@@ -927,8 +997,12 @@ msgstr "Plume は分散型ブログエンジンです。"
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "作成者は、それぞれ独自のウェブサイトとして複数のブログを管理できます。"
|
msgstr "作成者は、それぞれ独自のウェブサイトとして複数のブログを管理できます。"
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "投稿は他の Plume インスタンスからも閲覧可能であり、Mastdon のように他のプラットフォームから直接記事にアクセスできます。"
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"投稿は他の Plume インスタンスからも閲覧可能であり、Mastdon のように他のプラッ"
|
||||||
|
"トフォームから直接記事にアクセスできます。"
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "詳細な規則を読む"
|
msgstr "詳細な規則を読む"
|
||||||
@@ -1007,4 +1081,3 @@ msgstr "適用されているライセンス"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "投稿のライセンス"
|
msgstr "投稿のライセンス"
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -785,7 +814,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -842,7 +873,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -851,7 +884,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -866,7 +901,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -927,7 +963,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1007,4 +1045,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+121
-39
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Je artikel is verwijderd."
|
msgstr "Je artikel is verwijderd."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Het lijkt erop dat het artikel dat je probeerde te verwijderen niet bestaat. Misschien is het al verdwenen?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Het lijkt erop dat het artikel dat je probeerde te verwijderen niet bestaat. "
|
||||||
|
"Misschien is het al verdwenen?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Kon niet genoeg informatie over je account opvragen. Controleer of je gebruikersnaam juist is."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Kon niet genoeg informatie over je account opvragen. Controleer of je "
|
||||||
|
"gebruikersnaam juist is."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Registraties zijn gesloten op deze server."
|
msgstr "Registraties zijn gesloten op deze server."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Je account is aangemaakt. Nu hoe je alleen maar in te loggen, om het te kunnen gebruiken."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Je account is aangemaakt. Nu hoe je alleen maar in te loggen, om het te "
|
||||||
|
"kunnen gebruiken."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Media uploaden"
|
msgstr "Media uploaden"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Wachtwoord"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Wachtwoordbevestiging"
|
msgstr "Wachtwoordbevestiging"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Excuses, maar registraties zijn gesloten voor deze server. Je kunt wel een andere vinden."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Excuses, maar registraties zijn gesloten voor deze server. Je kunt wel een "
|
||||||
|
"andere vinden."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0}'s abonnementen"
|
msgstr "{0}'s abonnementen"
|
||||||
@@ -454,7 +470,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Je blogs"
|
msgstr "Je blogs"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Je hebt nog geen blog. Maak een blog, of vraag om aan een blog mee te mogen doen."
|
msgstr ""
|
||||||
|
"Je hebt nog geen blog. Maak een blog, of vraag om aan een blog mee te mogen "
|
||||||
|
"doen."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Start een nieuwe blog"
|
msgstr "Start een nieuwe blog"
|
||||||
@@ -471,8 +489,11 @@ msgstr "Bewerk je account"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Je profiel"
|
msgstr "Je profiel"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Om je avatar te veranderen upload je die naar je galerij en selecteer je avatar daar."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Om je avatar te veranderen upload je die naar je galerij en selecteer je "
|
||||||
|
"avatar daar."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Upload een avatar"
|
msgstr "Upload een avatar"
|
||||||
@@ -543,8 +564,14 @@ msgstr "Sorry. Als je denkt dat dit een bug is, rapporteer het dan."
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Ongeldig CSRF token"
|
msgstr "Ongeldig CSRF token"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Er is iets mis met het CSRF-token. Zorg ervoor dat cookies ingeschakeld zijn in je browser en probeer deze pagina opnieuw te laden. Als je dit foutbericht blijft zien, rapporteer het dan."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Er is iets mis met het CSRF-token. Zorg ervoor dat cookies ingeschakeld zijn "
|
||||||
|
"in je browser en probeer deze pagina opnieuw te laden. Als je dit "
|
||||||
|
"foutbericht blijft zien, rapporteer het dan."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Je bent niet geautoriseerd."
|
msgstr "Je bent niet geautoriseerd."
|
||||||
@@ -627,14 +654,31 @@ msgstr "Standaard artikellicentie"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Deze instellingen opslaan"
|
msgstr "Deze instellingen opslaan"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Als je deze site als bezoeker bekijkt, worden er geen gegevens over jou verzameld."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Als je deze site als bezoeker bekijkt, worden er geen gegevens over jou "
|
||||||
|
"verzameld."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Als geregistreerde gebruiker moet je je gebruikersnaam invoeren (dat hoeft niet je echte naam te zijn), je bestaande e-mailadres en een wachtwoord om in te kunnen loggen, artikelen en commentaar te schrijven. De inhoud die je opgeeft wordt opgeslagen totdat je die verwijdert."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Als geregistreerde gebruiker moet je je gebruikersnaam invoeren (dat hoeft "
|
||||||
|
"niet je echte naam te zijn), je bestaande e-mailadres en een wachtwoord om "
|
||||||
|
"in te kunnen loggen, artikelen en commentaar te schrijven. De inhoud die je "
|
||||||
|
"opgeeft wordt opgeslagen totdat je die verwijdert."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Als je inlogt, slaan we twee cookies op, de eerste om je sessie open te houden, de tweede om andere mensen te verhinderen om namens jou iets te doen. We slaan geen andere cookies op."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Als je inlogt, slaan we twee cookies op, de eerste om je sessie open te "
|
||||||
|
"houden, de tweede om andere mensen te verhinderen om namens jou iets te "
|
||||||
|
"doen. We slaan geen andere cookies op."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Geblokkeerde e-mailadressen"
|
msgstr "Geblokkeerde e-mailadressen"
|
||||||
@@ -642,8 +686,14 @@ msgstr "Geblokkeerde e-mailadressen"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "E-mailadres"
|
msgstr "E-mailadres"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "Het e-mailadres dat je wilt blokkeren. Om hele domeinen te blokkeren, kunt je de globale syntax gebruiken, bijvoorbeeld '*@example.com' blokkeert alle adressen van example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"Het e-mailadres dat je wilt blokkeren. Om hele domeinen te blokkeren, kunt "
|
||||||
|
"je de globale syntax gebruiken, bijvoorbeeld '*@example.com' blokkeert alle "
|
||||||
|
"adressen van example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Opmerking"
|
msgstr "Opmerking"
|
||||||
@@ -651,14 +701,22 @@ msgstr "Opmerking"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "De gebruiker informeren?"
|
msgstr "De gebruiker informeren?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Optioneel. Toont een bericht aan gebruikers wanneer ze een account met dat adres proberen aan te maken"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Optioneel. Toont een bericht aan gebruikers wanneer ze een account met dat "
|
||||||
|
"adres proberen aan te maken"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Blokkeringsmelding"
|
msgstr "Blokkeringsmelding"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Het bericht dat wordt getoond als iemand een account met dit e-mailadres probeert aan te maken"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Het bericht dat wordt getoond als iemand een account met dit e-mailadres "
|
||||||
|
"probeert aan te maken"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Te blokkeren adres toevoegen"
|
msgstr "Te blokkeren adres toevoegen"
|
||||||
@@ -729,8 +787,12 @@ msgstr "Ondertitel"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Inhoud"
|
msgstr "Inhoud"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Je kunt media uploaden naar je galerij en vervolgens de Markdown code in je artikelen kopiëren om ze in te voegen."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Je kunt media uploaden naar je galerij en vervolgens de Markdown code in je "
|
||||||
|
"artikelen kopiëren om ze in te voegen."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Media uploaden"
|
msgstr "Media uploaden"
|
||||||
@@ -787,8 +849,12 @@ msgstr "Ik wil dit niet meer boosten"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Boosten"
|
msgstr "Boosten"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Log in{1}, of {2}gebruik je Fediverse account{3} om over dit artikel te communiceren"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Log in{1}, of {2}gebruik je Fediverse account{3} om over dit artikel te "
|
||||||
|
"communiceren"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Reacties"
|
msgstr "Reacties"
|
||||||
@@ -806,7 +872,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "Weet je het zeker?"
|
msgstr "Weet je het zeker?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Dit artikel is nog een concept. Alleen jij en andere auteurs kunnen het bekijken."
|
msgstr ""
|
||||||
|
"Dit artikel is nog een concept. Alleen jij en andere auteurs kunnen het "
|
||||||
|
"bekijken."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Alleen jij en andere auteurs kunnen dit artikel bewerken."
|
msgstr "Alleen jij en andere auteurs kunnen dit artikel bewerken."
|
||||||
@@ -844,8 +912,12 @@ msgstr "Wachtwoord bijwerken"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Ga naar je inbox!"
|
msgstr "Ga naar je inbox!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "We hebben een e-mail gestuurd naar het adres dat je hebt opgegeven, met een link om je wachtwoord te resetten."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"We hebben een e-mail gestuurd naar het adres dat je hebt opgegeven, met een "
|
||||||
|
"link om je wachtwoord te resetten."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Wachtwoordresetlink versturen"
|
msgstr "Wachtwoordresetlink versturen"
|
||||||
@@ -853,8 +925,12 @@ msgstr "Wachtwoordresetlink versturen"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Dit token is verlopen"
|
msgstr "Dit token is verlopen"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Start het proces opnieuw door <a href=\"/password-reset\">hier</a> te klikken."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Start het proces opnieuw door <a href=\"/password-reset\">hier</a> te "
|
||||||
|
"klikken."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Nieuwe blog"
|
msgstr "Nieuwe blog"
|
||||||
@@ -868,8 +944,11 @@ msgstr "Creëer blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "\"{}\" bewerken"
|
msgstr "\"{}\" bewerken"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Je kunt afbeeldingen uploaden naar je galerij om ze als blogpictogrammen of banners te gebruiken."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Je kunt afbeeldingen uploaden naar je galerij om ze als blogpictogrammen of "
|
||||||
|
"banners te gebruiken."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Afbeeldingen opladen"
|
msgstr "Afbeeldingen opladen"
|
||||||
@@ -930,8 +1009,12 @@ msgstr "Plume is een gedecentraliseerde blogging-engine."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Auteurs kunnen meerdere blogs beheren, elk als een eigen website."
|
msgstr "Auteurs kunnen meerdere blogs beheren, elk als een eigen website."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Artikelen zijn ook zichtbaar op andere Plume-servers en je kunt ze direct vanuit andere platforms zoals Mastodon gebruiken."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Artikelen zijn ook zichtbaar op andere Plume-servers en je kunt ze direct "
|
||||||
|
"vanuit andere platforms zoals Mastodon gebruiken."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Lees de gedetailleerde instructies"
|
msgstr "Lees de gedetailleerde instructies"
|
||||||
@@ -1010,4 +1093,3 @@ msgstr "Gepubliceerd onder deze licentie"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Artikel licentie"
|
msgstr "Artikel licentie"
|
||||||
|
|
||||||
|
|||||||
+96
-32
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Artikkelen er slettet."
|
msgstr "Artikkelen er slettet."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Det ser ut som arikkelen du prøvde allerede er slettet; Kanskje den allerede er fjernet?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Det ser ut som arikkelen du prøvde allerede er slettet; Kanskje den allerede "
|
||||||
|
"er fjernet?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Klarte ikke å hente informasjon om kontoen din. Vennligst sjekk at brukernavnet er korrekt."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Klarte ikke å hente informasjon om kontoen din. Vennligst sjekk at "
|
||||||
|
"brukernavnet er korrekt."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +290,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Registrering er lukket på denne instansen."
|
msgstr "Registrering er lukket på denne instansen."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr "Kontoen din er opprettet. Du må logge inn for å bruke den."
|
msgstr "Kontoen din er opprettet. Du må logge inn for å bruke den."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,8 +451,12 @@ msgstr "Passord"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Beklager, nyregistreringer er lukket på denne instansen. Du kan istedet finne en annen instans."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Beklager, nyregistreringer er lukket på denne instansen. Du kan istedet "
|
||||||
|
"finne en annen instans."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -471,8 +485,10 @@ msgstr "Endre kontoen din"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Din profil"
|
msgstr "Din profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "For å endre avataren din må du legge den til galleriet og velge den der."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"For å endre avataren din må du legge den til galleriet og velge den der."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Last opp en avatar"
|
msgstr "Last opp en avatar"
|
||||||
@@ -538,13 +554,21 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Noe brakk hos oss."
|
msgstr "Noe brakk hos oss."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Beklager! Hvis du tror at dette er en programfeil, setter vi pris på at du sier ifra."
|
msgstr ""
|
||||||
|
"Beklager! Hvis du tror at dette er en programfeil, setter vi pris på at du "
|
||||||
|
"sier ifra."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Ugyldig CSRF token"
|
msgstr "Ugyldig CSRF token"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Noe er galt med CSRF token. Påse at informasjonskapsler er aktivert i nettleseren, prøv så å hente nettsiden på nytt. Hvis du fortsatt ser denne feilen, setter vi pris på om du sier ifra."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Noe er galt med CSRF token. Påse at informasjonskapsler er aktivert i "
|
||||||
|
"nettleseren, prøv så å hente nettsiden på nytt. Hvis du fortsatt ser denne "
|
||||||
|
"feilen, setter vi pris på om du sier ifra."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Du har ikke tilgang."
|
msgstr "Du har ikke tilgang."
|
||||||
@@ -627,14 +651,30 @@ msgstr "Standardlisens for artikler"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Lagre innstillingene"
|
msgstr "Lagre innstillingene"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Hvis du besøker denne siden som gjest, lagres ingen informasjon om deg."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Hvis du besøker denne siden som gjest, lagres ingen informasjon om deg."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "For å registrere deg må du oppgi ett brukernavn (dette behøver ikke å samsvare med ditt ekte navn), en fungerende epost-adresse og ett passord. Dette gjør at du kan logge inn, skrive artikler og kommentarer. Innholdet du legger inn blir lagret inntil du sletter det."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"For å registrere deg må du oppgi ett brukernavn (dette behøver ikke å "
|
||||||
|
"samsvare med ditt ekte navn), en fungerende epost-adresse og ett passord. "
|
||||||
|
"Dette gjør at du kan logge inn, skrive artikler og kommentarer. Innholdet du "
|
||||||
|
"legger inn blir lagret inntil du sletter det."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Når du logger inn lagrer vi to informasjonskapsler. Den har informasjon om sesjonen din, den andre beskytter identiteten din. Vi lagrer ingen andre informasjonskapsler."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Når du logger inn lagrer vi to informasjonskapsler. Den har informasjon om "
|
||||||
|
"sesjonen din, den andre beskytter identiteten din. Vi lagrer ingen andre "
|
||||||
|
"informasjonskapsler."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -642,7 +682,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +694,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +776,12 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Innhold"
|
msgstr "Innhold"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Du kan laste opp medier til galleriet, og så lime inn Markdown syntaksen inn i artiklen for å bruke dem."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Du kan laste opp medier til galleriet, og så lime inn Markdown syntaksen inn "
|
||||||
|
"i artiklen for å bruke dem."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Last opp medie"
|
msgstr "Last opp medie"
|
||||||
@@ -787,8 +838,12 @@ msgstr "Jeg vil ikke fremheve dette lenger"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Fremhev"
|
msgstr "Fremhev"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Logg inn{1} eller {2}bruk din Fediverse konto{3} for å interaktere med denne artikkelen"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Logg inn{1} eller {2}bruk din Fediverse konto{3} for å interaktere med "
|
||||||
|
"denne artikkelen"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Kommentarer"
|
msgstr "Kommentarer"
|
||||||
@@ -806,7 +861,8 @@ msgid "Are you sure?"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Denne artikkelen er ett utkast. Bare du og andre forfattere kan se den."
|
msgstr ""
|
||||||
|
"Denne artikkelen er ett utkast. Bare du og andre forfattere kan se den."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Bare du og andre forfattere kan endre denne artikkelen."
|
msgstr "Bare du og andre forfattere kan endre denne artikkelen."
|
||||||
@@ -844,7 +900,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +911,9 @@ msgstr "Send lenke for tilbakestilling av passord"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,8 +928,11 @@ msgstr "Opprett blogg"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Rediger \"{}\""
|
msgstr "Rediger \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Du kan legge opp bilder til galleriet ditt for å bruke den som bloggikoner eller bannere."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Du kan legge opp bilder til galleriet ditt for å bruke den som bloggikoner "
|
||||||
|
"eller bannere."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Last opp bilder"
|
msgstr "Last opp bilder"
|
||||||
@@ -930,7 +993,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1075,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+127
-41
@@ -10,7 +10,9 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n"
|
||||||
|
"%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n"
|
||||||
|
"%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: pl\n"
|
"X-Crowdin-Language: pl\n"
|
||||||
@@ -214,12 +216,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Twój artykuł został usunięty."
|
msgstr "Twój artykuł został usunięty."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Wygląda na to, że artykuł który próbowałeś(-aś) usunąć nie istnieje. Może został usunięty wcześniej?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Wygląda na to, że artykuł który próbowałeś(-aś) usunąć nie istnieje. Może "
|
||||||
|
"został usunięty wcześniej?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Nie można uzyskać wystarczającej ilości informacji o Twoim koncie. Upewnij się, że nazwa użytkownika jest prawidłowa."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Nie można uzyskać wystarczającej ilości informacji o Twoim koncie. Upewnij "
|
||||||
|
"się, że nazwa użytkownika jest prawidłowa."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +292,12 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Rejestracje są zamknięte w tej instancji."
|
msgstr "Rejestracje są zamknięte w tej instancji."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Twoje konto zostało utworzone. Zanim będziesz mógł(-ogła) z niego korzystać, musisz się zalogować."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Twoje konto zostało utworzone. Zanim będziesz mógł(-ogła) z niego korzystać, "
|
||||||
|
"musisz się zalogować."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Wysyłanie zawartości multimedialnej"
|
msgstr "Wysyłanie zawartości multimedialnej"
|
||||||
@@ -292,7 +306,9 @@ msgid "Description"
|
|||||||
msgstr "Opis"
|
msgstr "Opis"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Przydatny dla osób z problemami ze wzrokiem oraz do umieszczenia informacji o licencji"
|
msgstr ""
|
||||||
|
"Przydatny dla osób z problemami ze wzrokiem oraz do umieszczenia informacji "
|
||||||
|
"o licencji"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Ostrzeżenie o zawartości"
|
msgstr "Ostrzeżenie o zawartości"
|
||||||
@@ -441,8 +457,12 @@ msgstr "Hasło"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Potwierdzenie hasła"
|
msgstr "Potwierdzenie hasła"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Przepraszamy, rejestracja jest zamknięta na tej instancji. Spróbuj znaleźć inną."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Przepraszamy, rejestracja jest zamknięta na tej instancji. Spróbuj znaleźć "
|
||||||
|
"inną."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Subskrypcje {0}"
|
msgstr "Subskrypcje {0}"
|
||||||
@@ -454,7 +474,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Twoje blogi"
|
msgstr "Twoje blogi"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Nie posiadasz żadnego bloga. Utwórz własny, lub poproś o dołączanie do istniejącego."
|
msgstr ""
|
||||||
|
"Nie posiadasz żadnego bloga. Utwórz własny, lub poproś o dołączanie do "
|
||||||
|
"istniejącego."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Utwórz nowy blog"
|
msgstr "Utwórz nowy blog"
|
||||||
@@ -471,8 +493,11 @@ msgstr "Edytuj swoje konto"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Twój profil"
|
msgstr "Twój profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Aby zmienić swój awatar, prześlij go do Twojej galerii, a następnie wybierz go stamtąd."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Aby zmienić swój awatar, prześlij go do Twojej galerii, a następnie wybierz "
|
||||||
|
"go stamtąd."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Wczytaj awatara"
|
msgstr "Wczytaj awatara"
|
||||||
@@ -538,13 +563,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Coś poszło nie tak."
|
msgstr "Coś poszło nie tak."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Przepraszamy. Jeżeli uważasz że wystąpił błąd, prosimy o zgłoszenie go."
|
msgstr ""
|
||||||
|
"Przepraszamy. Jeżeli uważasz że wystąpił błąd, prosimy o zgłoszenie go."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Nieprawidłowy token CSRF"
|
msgstr "Nieprawidłowy token CSRF"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Coś poszło nie tak z tokenem CSRF. Upewnij się, że w przeglądarce są włączone pliki cookies i spróbuj odświeżyć stronę. Jeżeli wciąż widzisz tę wiadomość, zgłoś to."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Coś poszło nie tak z tokenem CSRF. Upewnij się, że w przeglądarce są "
|
||||||
|
"włączone pliki cookies i spróbuj odświeżyć stronę. Jeżeli wciąż widzisz tę "
|
||||||
|
"wiadomość, zgłoś to."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Nie jesteś zalogowany."
|
msgstr "Nie jesteś zalogowany."
|
||||||
@@ -627,14 +659,31 @@ msgstr "Domyślna licencja artykułów"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Zapisz te ustawienia"
|
msgstr "Zapisz te ustawienia"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Jeśli przeglądasz tę witrynę jako odwiedzający, nie zbierasz żadnych danych o Tobie."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Jeśli przeglądasz tę witrynę jako odwiedzający, nie zbierasz żadnych danych "
|
||||||
|
"o Tobie."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Jako zarejestrowany użytkownik, musisz podać swoją nazwę użytkownika (nie musi to być Twoje imię i nazwisko), działający adres e-mail i hasło, aby móc zalogować się, pisać artykuły i komentować. Dodane treści są przechowywane do czasu, gdy je usuniesz."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Jako zarejestrowany użytkownik, musisz podać swoją nazwę użytkownika (nie "
|
||||||
|
"musi to być Twoje imię i nazwisko), działający adres e-mail i hasło, aby móc "
|
||||||
|
"zalogować się, pisać artykuły i komentować. Dodane treści są przechowywane "
|
||||||
|
"do czasu, gdy je usuniesz."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Po zalogowaniu się, przechowujemy dwa ciasteczka – jedno, aby utrzymać aktywną sesję i drugie, aby uniemożliwić innym podszywanie się pod Ciebie. Nie przechowujemy innych plików cookie."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Po zalogowaniu się, przechowujemy dwa ciasteczka – jedno, aby utrzymać "
|
||||||
|
"aktywną sesję i drugie, aby uniemożliwić innym podszywanie się pod Ciebie. "
|
||||||
|
"Nie przechowujemy innych plików cookie."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Zablokowane adresy e-mail"
|
msgstr "Zablokowane adresy e-mail"
|
||||||
@@ -642,8 +691,14 @@ msgstr "Zablokowane adresy e-mail"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Adresy e-mail"
|
msgstr "Adresy e-mail"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
msgstr "Adres e-mail, który chcesz zablokować. Aby zablokować domeny, możesz użyć globbing syntax, na przykład '*@example.com' blokuje wszystkie adresy z example.com"
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
|
msgstr ""
|
||||||
|
"Adres e-mail, który chcesz zablokować. Aby zablokować domeny, możesz użyć "
|
||||||
|
"globbing syntax, na przykład '*@example.com' blokuje wszystkie adresy z "
|
||||||
|
"example.com"
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
msgstr "Notatka"
|
msgstr "Notatka"
|
||||||
@@ -651,14 +706,22 @@ msgstr "Notatka"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Powiadomić użytkownika?"
|
msgstr "Powiadomić użytkownika?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
msgstr "Opcjonalnie, pokazuje wiadomość użytkownikowi gdy próbuje utworzyć konto o tym adresie"
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
|
msgstr ""
|
||||||
|
"Opcjonalnie, pokazuje wiadomość użytkownikowi gdy próbuje utworzyć konto o "
|
||||||
|
"tym adresie"
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr "Zablokuj powiadomienie"
|
msgstr "Zablokuj powiadomienie"
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
msgstr "Wiadomość do wyświetlenia, gdy użytkownik próbuje utworzyć konto z tym adresem e-mail"
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
|
msgstr ""
|
||||||
|
"Wiadomość do wyświetlenia, gdy użytkownik próbuje utworzyć konto z tym "
|
||||||
|
"adresem e-mail"
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
msgstr "Dodaj zablokowany adres"
|
msgstr "Dodaj zablokowany adres"
|
||||||
@@ -729,8 +792,12 @@ msgstr "Podtytuł"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Zawartość"
|
msgstr "Zawartość"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Możesz przesłać multimedia do swojej galerii, i następnie skopiuj ich kod Markdown do artykułów, aby je wstawić."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Możesz przesłać multimedia do swojej galerii, i następnie skopiuj ich kod "
|
||||||
|
"Markdown do artykułów, aby je wstawić."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Przesłać media"
|
msgstr "Przesłać media"
|
||||||
@@ -791,8 +858,12 @@ msgstr "Nie chcę tego podbijać"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Podbij"
|
msgstr "Podbij"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Zaloguj się{1} lub {2}użyj konta w Fediwersum{3}, aby wejść w interakcje z tym artykułem"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Zaloguj się{1} lub {2}użyj konta w Fediwersum{3}, aby wejść w interakcje "
|
||||||
|
"z tym artykułem"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Komentarze"
|
msgstr "Komentarze"
|
||||||
@@ -848,8 +919,12 @@ msgstr "Zaktualizuj hasło"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Sprawdź do swoją skrzynki odbiorczej!"
|
msgstr "Sprawdź do swoją skrzynki odbiorczej!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Wysłaliśmy maila na adres, który nam podałeś, z linkiem do zresetowania hasła."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Wysłaliśmy maila na adres, który nam podałeś, z linkiem do zresetowania "
|
||||||
|
"hasła."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Wyślij e-mail resetujący hasło"
|
msgstr "Wyślij e-mail resetujący hasło"
|
||||||
@@ -857,8 +932,12 @@ msgstr "Wyślij e-mail resetujący hasło"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Ten token utracił własność"
|
msgstr "Ten token utracił własność"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
msgstr "Rozpocznij ten proces ponownie klikając <a href=\"/password-reset\">tutaj</a>."
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
|
msgstr ""
|
||||||
|
"Rozpocznij ten proces ponownie klikając <a href=\"/password-reset\">tutaj</"
|
||||||
|
"a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
msgstr "Nowy blog"
|
msgstr "Nowy blog"
|
||||||
@@ -872,8 +951,11 @@ msgstr "Utwórz blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Edytuj \"{}\""
|
msgstr "Edytuj \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Możesz przesłać zdjęcia do swojej galerii, aby używać ich jako ikon, lub banery blogów."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Możesz przesłać zdjęcia do swojej galerii, aby używać ich jako ikon, lub "
|
||||||
|
"banery blogów."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Przesyłać zdjęcia"
|
msgstr "Przesyłać zdjęcia"
|
||||||
@@ -936,8 +1018,13 @@ msgstr "Plume jest zdecentralizowanym silnikiem blogowym."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Autorzy mogą zarządzać różne blogi, każdy jako unikalny stronie."
|
msgstr "Autorzy mogą zarządzać różne blogi, każdy jako unikalny stronie."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Artykuły są również widoczne w innych instancjach Plume i możesz też wchodzić bezpośrednio interakcje z nimi z innych platform, takich jak Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Artykuły są również widoczne w innych instancjach Plume i możesz też "
|
||||||
|
"wchodzić bezpośrednio interakcje z nimi z innych platform, takich jak "
|
||||||
|
"Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Przeczytaj szczegółowe zasady"
|
msgstr "Przeczytaj szczegółowe zasady"
|
||||||
@@ -1016,4 +1103,3 @@ msgstr "Opublikowany na tej licencji"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licencja artykułu"
|
msgstr "Licencja artykułu"
|
||||||
|
|
||||||
|
|||||||
+47
-47
@@ -72,75 +72,75 @@ msgstr ""
|
|||||||
msgid "Your blog was successfully created!"
|
msgid "Your blog was successfully created!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:160
|
# src/routes/blogs.rs:159
|
||||||
msgid "Your blog was deleted."
|
msgid "Your blog was deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:168
|
# src/routes/blogs.rs:167
|
||||||
msgid "You are not allowed to delete this blog."
|
msgid "You are not allowed to delete this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:219
|
# src/routes/blogs.rs:218
|
||||||
msgid "You are not allowed to edit this blog."
|
msgid "You are not allowed to edit this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:275
|
# src/routes/blogs.rs:274
|
||||||
msgid "You can't use this media as a blog icon."
|
msgid "You can't use this media as a blog icon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:293
|
# src/routes/blogs.rs:292
|
||||||
msgid "You can't use this media as a blog banner."
|
msgid "You can't use this media as a blog banner."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/blogs.rs:327
|
# src/routes/blogs.rs:326
|
||||||
msgid "Your blog information have been updated."
|
msgid "Your blog information have been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/comments.rs:97
|
# src/routes/comments.rs:99
|
||||||
msgid "Your comment has been posted."
|
msgid "Your comment has been posted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/comments.rs:172
|
# src/routes/comments.rs:178
|
||||||
msgid "Your comment has been deleted."
|
msgid "Your comment has been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:120
|
# src/routes/instance.rs:118
|
||||||
msgid "Instance settings have been saved."
|
msgid "Instance settings have been saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:152
|
# src/routes/instance.rs:150
|
||||||
msgid "{} has been unblocked."
|
msgid "{} has been unblocked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:154
|
# src/routes/instance.rs:152
|
||||||
msgid "{} has been blocked."
|
msgid "{} has been blocked."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:203
|
# src/routes/instance.rs:201
|
||||||
msgid "Blocks deleted"
|
msgid "Blocks deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:218
|
# src/routes/instance.rs:216
|
||||||
msgid "Email already blocked"
|
msgid "Email already blocked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:223
|
# src/routes/instance.rs:221
|
||||||
msgid "Email Blocked"
|
msgid "Email Blocked"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:314
|
# src/routes/instance.rs:312
|
||||||
msgid "You can't change your own rights."
|
msgid "You can't change your own rights."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:325
|
# src/routes/instance.rs:323
|
||||||
msgid "You are not allowed to take this action."
|
msgid "You are not allowed to take this action."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/instance.rs:362
|
# src/routes/instance.rs:359
|
||||||
msgid "Done."
|
msgid "Done."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/likes.rs:53
|
# src/routes/likes.rs:58
|
||||||
msgid "To like a post, you need to be logged in"
|
msgid "To like a post, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -164,119 +164,119 @@ msgstr ""
|
|||||||
msgid "To see your notifications, you need to be logged in"
|
msgid "To see your notifications, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:54
|
# src/routes/posts.rs:55
|
||||||
msgid "This post isn't published yet."
|
msgid "This post isn't published yet."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:125
|
# src/routes/posts.rs:126
|
||||||
msgid "To write a new post, you need to be logged in"
|
msgid "To write a new post, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:142
|
# src/routes/posts.rs:143
|
||||||
msgid "You are not an author of this blog."
|
msgid "You are not an author of this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:149
|
# src/routes/posts.rs:150
|
||||||
msgid "New post"
|
msgid "New post"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:194
|
# src/routes/posts.rs:195
|
||||||
msgid "Edit {0}"
|
msgid "Edit {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:263
|
# src/routes/posts.rs:264
|
||||||
msgid "You are not allowed to publish on this blog."
|
msgid "You are not allowed to publish on this blog."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:355
|
# src/routes/posts.rs:363
|
||||||
msgid "Your article has been updated."
|
msgid "Your article has been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:542
|
# src/routes/posts.rs:553
|
||||||
msgid "Your article has been saved."
|
msgid "Your article has been saved."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:549
|
# src/routes/posts.rs:560
|
||||||
msgid "New article"
|
msgid "New article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:582
|
# src/routes/posts.rs:597
|
||||||
msgid "You are not allowed to delete this article."
|
msgid "You are not allowed to delete this article."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:607
|
# src/routes/posts.rs:622
|
||||||
msgid "Your article has been deleted."
|
msgid "Your article has been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:627
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:667
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:58
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/session.rs:87
|
# src/routes/session.rs:88
|
||||||
msgid "You are now connected."
|
msgid "You are now connected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/session.rs:108
|
# src/routes/session.rs:109
|
||||||
msgid "You are now logged off."
|
msgid "You are now logged off."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/session.rs:153
|
# src/routes/session.rs:154
|
||||||
msgid "Password reset"
|
msgid "Password reset"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/session.rs:154
|
# src/routes/session.rs:155
|
||||||
msgid "Here is the link to reset your password: {0}"
|
msgid "Here is the link to reset your password: {0}"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/session.rs:216
|
# src/routes/session.rs:215
|
||||||
msgid "Your password was successfully reset."
|
msgid "Your password was successfully reset."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:141
|
# src/routes/user.rs:142
|
||||||
msgid "To access your dashboard, you need to be logged in"
|
msgid "To access your dashboard, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:163
|
# src/routes/user.rs:164
|
||||||
msgid "You are no longer following {}."
|
msgid "You are no longer following {}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:180
|
# src/routes/user.rs:181
|
||||||
msgid "You are now following {}."
|
msgid "You are now following {}."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:260
|
# src/routes/user.rs:261
|
||||||
msgid "To subscribe to someone, you need to be logged in"
|
msgid "To subscribe to someone, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:364
|
# src/routes/user.rs:365
|
||||||
msgid "To edit your profile, you need to be logged in"
|
msgid "To edit your profile, you need to be logged in"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:409
|
# src/routes/user.rs:411
|
||||||
msgid "Your profile has been updated."
|
msgid "Your profile has been updated."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:436
|
# src/routes/user.rs:438
|
||||||
msgid "Your account has been deleted."
|
msgid "Your account has been deleted."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:442
|
# src/routes/user.rs:444
|
||||||
msgid "You can't delete someone else's account."
|
msgid "You can't delete someone else's account."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:526
|
# src/routes/user.rs:528
|
||||||
msgid "Registrations are closed on this instance."
|
msgid "Registrations are closed on this instance."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:551
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+104
-35
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Seu artigo foi excluído."
|
msgstr "Seu artigo foi excluído."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Parece que o artigo que você tentou excluir não existe. Talvez ele já tenha sido excluído?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Parece que o artigo que você tentou excluir não existe. Talvez ele já tenha "
|
||||||
|
"sido excluído?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Não foi possível obter informações sobre sua conta. Por favor, certifique-se de que seu nome de usuário completo está certo."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Não foi possível obter informações sobre sua conta. Por favor, certifique-se "
|
||||||
|
"de que seu nome de usuário completo está certo."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,7 +290,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Os registros estão fechados nesta instância."
|
msgstr "Os registros estão fechados nesta instância."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr "Sua conta foi criada. Agora você só precisa entrar para poder usá-la."
|
msgstr "Sua conta foi criada. Agora você só precisa entrar para poder usá-la."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -292,7 +302,8 @@ msgid "Description"
|
|||||||
msgstr "Descrição"
|
msgstr "Descrição"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Útil para pessoas com deficiência visual e para informações de licenciamento"
|
msgstr ""
|
||||||
|
"Útil para pessoas com deficiência visual e para informações de licenciamento"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Alerta de conteúdo"
|
msgstr "Alerta de conteúdo"
|
||||||
@@ -441,8 +452,12 @@ msgstr "Senha"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Confirmação de senha"
|
msgstr "Confirmação de senha"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Desculpe, mas os registros estão fechados nesta instância. Você pode, no entanto, procurar outra."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Desculpe, mas os registros estão fechados nesta instância. Você pode, no "
|
||||||
|
"entanto, procurar outra."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Inscrições de {0}"
|
msgstr "Inscrições de {0}"
|
||||||
@@ -471,7 +486,8 @@ msgstr "Editar sua conta"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Seu Perfil"
|
msgstr "Seu Perfil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr "Para mudar sua imagem de perfil, selecione uma nova na galeria."
|
msgstr "Para mudar sua imagem de perfil, selecione uma nova na galeria."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -502,13 +518,16 @@ msgid "Danger zone"
|
|||||||
msgstr "Zona de risco"
|
msgstr "Zona de risco"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr "Tenha muito cuidado, qualquer ação tomada aqui não poderá ser desfeita."
|
msgstr ""
|
||||||
|
"Tenha muito cuidado, qualquer ação tomada aqui não poderá ser desfeita."
|
||||||
|
|
||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Excluir sua conta"
|
msgstr "Excluir sua conta"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Desculpe, mas como administrador(a), você não pode sair da sua própria instância."
|
msgstr ""
|
||||||
|
"Desculpe, mas como administrador(a), você não pode sair da sua própria "
|
||||||
|
"instância."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Artigos recentes"
|
msgstr "Artigos recentes"
|
||||||
@@ -543,8 +562,14 @@ msgstr "Desculpe por isso. Se você acha que é um bug, por favor, reporte-o."
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Token CSRF inválido"
|
msgstr "Token CSRF inválido"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Algo está errado com seu token CSRF. Certifique-se de que os cookies estão habilitados no seu navegador e tente atualizar esta página. Se você continuar vendo esta mensagem de erro, por favor reporte-a."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Algo está errado com seu token CSRF. Certifique-se de que os cookies estão "
|
||||||
|
"habilitados no seu navegador e tente atualizar esta página. Se você "
|
||||||
|
"continuar vendo esta mensagem de erro, por favor reporte-a."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Você não tem permissão."
|
msgstr "Você não tem permissão."
|
||||||
@@ -627,14 +652,31 @@ msgstr "Licença padrão do artigo"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Salvar estas configurações"
|
msgstr "Salvar estas configurações"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Se você está navegando neste site como um visitante, nenhum dado sobre você é coletado."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Se você está navegando neste site como um visitante, nenhum dado sobre você "
|
||||||
|
"é coletado."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Como usuário registrado, você deve fornecer seu nome de usuário (que não precisa ser seu nome real), seu endereço de e-mail funcional e uma senha, para poder entrar, escrever artigos e comentários. O conteúdo que você enviar é armazenado até que você o exclua."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Como usuário registrado, você deve fornecer seu nome de usuário (que não "
|
||||||
|
"precisa ser seu nome real), seu endereço de e-mail funcional e uma senha, "
|
||||||
|
"para poder entrar, escrever artigos e comentários. O conteúdo que você "
|
||||||
|
"enviar é armazenado até que você o exclua."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Quando você entra, armazenamos dois cookies, um para manter a sua sessão aberta e o outro para impedir outras pessoas de agirem em seu nome. Não armazenamos nenhum outro cookies."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Quando você entra, armazenamos dois cookies, um para manter a sua sessão "
|
||||||
|
"aberta e o outro para impedir outras pessoas de agirem em seu nome. Não "
|
||||||
|
"armazenamos nenhum outro cookies."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -642,7 +684,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +696,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +778,12 @@ msgstr "Subtítulo"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Conteúdo"
|
msgstr "Conteúdo"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Você pode enviar mídia da sua galeria e inserí-la no artigo usando o código Markdown."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Você pode enviar mídia da sua galeria e inserí-la no artigo usando o código "
|
||||||
|
"Markdown."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Enviar mídia"
|
msgstr "Enviar mídia"
|
||||||
@@ -787,8 +840,12 @@ msgstr "Não quero mais compartilhar isso"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Compartilhar"
|
msgstr "Compartilhar"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Entrar{1}, ou {2}usar sua conta do Fediverso{3} para interagir com este artigo"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Entrar{1}, ou {2}usar sua conta do Fediverso{3} para interagir com este "
|
||||||
|
"artigo"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Comentários"
|
msgstr "Comentários"
|
||||||
@@ -806,7 +863,8 @@ msgid "Are you sure?"
|
|||||||
msgstr "Você tem certeza?"
|
msgstr "Você tem certeza?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Este artigo ainda é um rascunho. Apenas você e outros autores podem vê-lo."
|
msgstr ""
|
||||||
|
"Este artigo ainda é um rascunho. Apenas você e outros autores podem vê-lo."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Apenas você e outros autores podem editar este artigo."
|
msgstr "Apenas você e outros autores podem editar este artigo."
|
||||||
@@ -844,7 +902,9 @@ msgstr "Atualizar senha"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Verifique sua caixa de entrada!"
|
msgstr "Verifique sua caixa de entrada!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr "Enviamos para você um e-mail com um link para redefinir sua senha."
|
msgstr "Enviamos para você um e-mail com um link para redefinir sua senha."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +913,9 @@ msgstr "Enviar link para redefinir senha"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,8 +930,11 @@ msgstr "Criar blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Editar \"{}\""
|
msgstr "Editar \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Você pode enviar imagens da sua galeria, para usá-las como ícones ou capas do blog."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Você pode enviar imagens da sua galeria, para usá-las como ícones ou capas "
|
||||||
|
"do blog."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Enviar imagens"
|
msgstr "Enviar imagens"
|
||||||
@@ -887,7 +952,8 @@ msgid "Update blog"
|
|||||||
msgstr "Atualizar blog"
|
msgstr "Atualizar blog"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Tenha muito cuidado, qualquer ação tomada aqui não poderá ser desfeita."
|
msgstr ""
|
||||||
|
"Tenha muito cuidado, qualquer ação tomada aqui não poderá ser desfeita."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -930,8 +996,12 @@ msgstr "Plume é um motor de blogs descentralizado."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Autores podem gerenciar vários blogs, cada um como seu próprio site."
|
msgstr "Autores podem gerenciar vários blogs, cada um como seu próprio site."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Os artigos também são visíveis em outras instâncias Plume, e você pode interagir com elas diretamente de outras plataformas como o Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Os artigos também são visíveis em outras instâncias Plume, e você pode "
|
||||||
|
"interagir com elas diretamente de outras plataformas como o Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Leia as regras detalhadas"
|
msgstr "Leia as regras detalhadas"
|
||||||
@@ -1010,4 +1080,3 @@ msgstr "Publicado sob esta licença"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Licença do artigo"
|
msgstr "Licença do artigo"
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100>0 && n%100<20)) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : (n==0 || (n%100>0 && n"
|
||||||
|
"%100<20)) ? 1 : 2);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: ro\n"
|
"X-Crowdin-Language: ro\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +448,9 @@ msgstr "Parolă"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +480,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -789,7 +819,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Boost"
|
msgstr "Boost"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -846,7 +878,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -855,7 +889,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -870,7 +906,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -933,7 +970,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1013,4 +1052,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+66
-22
@@ -10,7 +10,9 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 "
|
||||||
|
"&& n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 "
|
||||||
|
"&& n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: ru\n"
|
"X-Crowdin-Language: ru\n"
|
||||||
@@ -214,11 +216,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +288,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +449,9 @@ msgstr "Пароль"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +481,8 @@ msgstr "Редактировать ваш аккаунт"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -538,13 +549,21 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Произошла ошибка на вашей стороне."
|
msgstr "Произошла ошибка на вашей стороне."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Приносим извинения. Если вы считаете что это ошибка, пожалуйста сообщите о ней."
|
msgstr ""
|
||||||
|
"Приносим извинения. Если вы считаете что это ошибка, пожалуйста сообщите о "
|
||||||
|
"ней."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Что-то не так с вашим CSRF-токеном. Убедитесь что в вашем браузере включены cookies и попробуйте перезагрузить страницу. Если вы продолжите видеть это сообщение об ошибке, сообщите об этом."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Что-то не так с вашим CSRF-токеном. Убедитесь что в вашем браузере включены "
|
||||||
|
"cookies и попробуйте перезагрузить страницу. Если вы продолжите видеть это "
|
||||||
|
"сообщение об ошибке, сообщите об этом."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Вы не авторизованы."
|
msgstr "Вы не авторизованы."
|
||||||
@@ -627,13 +646,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +669,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +681,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +763,9 @@ msgstr "Подзаголовок"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Содержимое"
|
msgstr "Содержимое"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -791,7 +827,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Продвинуть"
|
msgstr "Продвинуть"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -848,7 +886,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -857,7 +897,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -872,7 +914,8 @@ msgstr "Создать блог"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -936,7 +979,9 @@ msgstr "Plume это децентрализованный движок для б
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1016,4 +1061,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr "ᱵᱞᱚᱜ ᱛᱮᱭᱟᱨ ᱢᱮ"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "\"{}\" ᱥᱟᱯᱰᱟᱣ"
|
msgstr "\"{}\" ᱥᱟᱯᱰᱟᱣ"
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr "මුර පදය"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "විද්යුත් තැපැල් ලිපිනය"
|
msgstr "විද්යුත් තැපැල් ලිපිනය"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr "සටහන"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+117
-39
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Tvoj článok bol vymazaný."
|
msgstr "Tvoj článok bol vymazaný."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Vyzerá to tak, že článok, ktorý si sa pokúšal/a vymazať neexistuje. Možno je už preč?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Vyzerá to tak, že článok, ktorý si sa pokúšal/a vymazať neexistuje. Možno je "
|
||||||
|
"už preč?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Nebolo možné zistiť postačujúce množstvo informácií o tvojom účte. Prosím over si, že celá tvoja prezývka je zadaná správne."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Nebolo možné zistiť postačujúce množstvo informácií o tvojom účte. Prosím "
|
||||||
|
"over si, že celá tvoja prezývka je zadaná správne."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,11 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Registrácie na tejto instancii sú uzatvorené."
|
msgstr "Registrácie na tejto instancii sú uzatvorené."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Tvoj účet bol vytvorený. K jeho užívaniu sa teraz musíš už len prihlásiť."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Tvoj účet bol vytvorený. K jeho užívaniu sa teraz musíš už len prihlásiť."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Nahrávanie mediálnych súborov"
|
msgstr "Nahrávanie mediálnych súborov"
|
||||||
@@ -292,7 +303,8 @@ msgid "Description"
|
|||||||
msgstr "Popis"
|
msgstr "Popis"
|
||||||
|
|
||||||
msgid "Useful for visually impaired people, as well as licensing information"
|
msgid "Useful for visually impaired people, as well as licensing information"
|
||||||
msgstr "Užitočné pre zrakovo postihnutých ľudí, ako aj pre informácie o licencovaní"
|
msgstr ""
|
||||||
|
"Užitočné pre zrakovo postihnutých ľudí, ako aj pre informácie o licencovaní"
|
||||||
|
|
||||||
msgid "Content warning"
|
msgid "Content warning"
|
||||||
msgstr "Varovanie o obsahu"
|
msgstr "Varovanie o obsahu"
|
||||||
@@ -441,8 +453,12 @@ msgstr "Heslo"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Potvrdenie hesla"
|
msgstr "Potvrdenie hesla"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Ospravedlňujeme sa, ale na tejto konkrétnej instancii sú registrácie zatvorené. Môžeš si však nájsť inú."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Ospravedlňujeme sa, ale na tejto konkrétnej instancii sú registrácie "
|
||||||
|
"zatvorené. Môžeš si však nájsť inú."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "Odoberané užívateľom {0}"
|
msgstr "Odoberané užívateľom {0}"
|
||||||
@@ -454,7 +470,9 @@ msgid "Your Blogs"
|
|||||||
msgstr "Tvoje blogy"
|
msgstr "Tvoje blogy"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Ešte nemáš žiaden blog. Vytvor si svoj vlastný, alebo požiadaj v niektorom o členstvo."
|
msgstr ""
|
||||||
|
"Ešte nemáš žiaden blog. Vytvor si svoj vlastný, alebo požiadaj v niektorom o "
|
||||||
|
"členstvo."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Začni nový blog"
|
msgstr "Začni nový blog"
|
||||||
@@ -471,8 +489,10 @@ msgstr "Uprav svoj účet"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Tvoj profil"
|
msgstr "Tvoj profil"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Pre zmenu tvojho avataru ho nahraj do svojej galérie a potom ho odtiaľ zvoľ."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Pre zmenu tvojho avataru ho nahraj do svojej galérie a potom ho odtiaľ zvoľ."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Nahraj avatar"
|
msgstr "Nahraj avatar"
|
||||||
@@ -502,13 +522,16 @@ msgid "Danger zone"
|
|||||||
msgstr "Riziková zóna"
|
msgstr "Riziková zóna"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be cancelled."
|
msgid "Be very careful, any action taken here can't be cancelled."
|
||||||
msgstr "Buď veľmi opatrný/á, akýkoľvek úkon vykonaný v tomto priestore nieje možné vziať späť."
|
msgstr ""
|
||||||
|
"Buď veľmi opatrný/á, akýkoľvek úkon vykonaný v tomto priestore nieje možné "
|
||||||
|
"vziať späť."
|
||||||
|
|
||||||
msgid "Delete your account"
|
msgid "Delete your account"
|
||||||
msgstr "Vymaž svoj účet"
|
msgstr "Vymaž svoj účet"
|
||||||
|
|
||||||
msgid "Sorry, but as an admin, you can't leave your own instance."
|
msgid "Sorry, but as an admin, you can't leave your own instance."
|
||||||
msgstr "Prepáč, ale ako jej správca, ty nemôžeš opustiť svoju vlastnú instanciu."
|
msgstr ""
|
||||||
|
"Prepáč, ale ako jej správca, ty nemôžeš opustiť svoju vlastnú instanciu."
|
||||||
|
|
||||||
msgid "Latest articles"
|
msgid "Latest articles"
|
||||||
msgstr "Najnovšie články"
|
msgstr "Najnovšie články"
|
||||||
@@ -543,8 +566,14 @@ msgstr "Prepáč ohľadom toho. Ak si myslíš, že ide o chybu, prosím nahlás
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Neplatný CSRF token"
|
msgstr "Neplatný CSRF token"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "Niečo nieje v poriadku s tvojím CSRF tokenom. Uisti sa, že máš vo svojom prehliadači povolené cookies, potom skús načítať stránku znovu. Ak budeš aj naďalej vidieť túto chybovú správu, prosím nahlás ju."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"Niečo nieje v poriadku s tvojím CSRF tokenom. Uisti sa, že máš vo svojom "
|
||||||
|
"prehliadači povolené cookies, potom skús načítať stránku znovu. Ak budeš aj "
|
||||||
|
"naďalej vidieť túto chybovú správu, prosím nahlás ju."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Nemáš oprávnenie."
|
msgstr "Nemáš oprávnenie."
|
||||||
@@ -627,14 +656,31 @@ msgstr "Predvolená licencia článkov"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Ulož tieto nastavenia"
|
msgstr "Ulož tieto nastavenia"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Pokiaľ si túto stránku prezeráš ako návštevník, niesú o tebe zaznamenávané žiadne dáta."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Pokiaľ si túto stránku prezeráš ako návštevník, niesú o tebe zaznamenávané "
|
||||||
|
"žiadne dáta."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Ako registrovaný užívateľ musíš poskytnúť svoje užívateľské meno (čo zároveň nemusí byť tvoje skutočné meno), tvoju fungujúcu emailovú adresu a helso, aby sa ti bolo možné prihlásiť, písať články a komentovať. Obsah, ktorý zverejníš je uložený len pokiaľ ho nevymažeš."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Ako registrovaný užívateľ musíš poskytnúť svoje užívateľské meno (čo zároveň "
|
||||||
|
"nemusí byť tvoje skutočné meno), tvoju fungujúcu emailovú adresu a helso, "
|
||||||
|
"aby sa ti bolo možné prihlásiť, písať články a komentovať. Obsah, ktorý "
|
||||||
|
"zverejníš je uložený len pokiaľ ho nevymažeš."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Keď sa prihlásiš, ukladáme dve cookies, jedno aby tvoja sezóna mohla ostať otvorená, druhé je na zabránenie iným ľudom, aby konali za teba. Žiadne iné cookies neukladáme."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Keď sa prihlásiš, ukladáme dve cookies, jedno aby tvoja sezóna mohla ostať "
|
||||||
|
"otvorená, druhé je na zabránenie iným ľudom, aby konali za teba. Žiadne iné "
|
||||||
|
"cookies neukladáme."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr "Blokované emaily"
|
msgstr "Blokované emaily"
|
||||||
@@ -642,7 +688,10 @@ msgstr "Blokované emaily"
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "Emailová adresa"
|
msgstr "Emailová adresa"
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +700,17 @@ msgstr "Poznámka"
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr "Oboznámiť používateľa?"
|
msgstr "Oboznámiť používateľa?"
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +782,12 @@ msgstr "Podnadpis"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "Obsah"
|
msgstr "Obsah"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Do svojej galérie môžeš nahrávať multimédiá, a potom skopírovať ich Markdown syntaxiu do tvojích článkov, aby si ich vložil/a."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Do svojej galérie môžeš nahrávať multimédiá, a potom skopírovať ich Markdown "
|
||||||
|
"syntaxiu do tvojích článkov, aby si ich vložil/a."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Nahraj multimédiá"
|
msgstr "Nahraj multimédiá"
|
||||||
@@ -791,8 +848,12 @@ msgstr "Už to viac nechcem vyzdvihovať"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Vyzdvihni"
|
msgstr "Vyzdvihni"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Prihlás sa{1}, alebo {2}použi svoj účet v rámci Fediversa{3} pre narábanie s týmto článkom"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Prihlás sa{1}, alebo {2}použi svoj účet v rámci Fediversa{3} pre "
|
||||||
|
"narábanie s týmto článkom"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Komentáre"
|
msgstr "Komentáre"
|
||||||
@@ -810,7 +871,9 @@ msgid "Are you sure?"
|
|||||||
msgstr "Ste si istý/á?"
|
msgstr "Ste si istý/á?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Tento článok je ešte len konceptom. Vidieť ho môžeš iba ty, a ostatní jeho autori."
|
msgstr ""
|
||||||
|
"Tento článok je ešte len konceptom. Vidieť ho môžeš iba ty, a ostatní jeho "
|
||||||
|
"autori."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Iba ty, a ostatní autori môžu upravovať tento článok."
|
msgstr "Iba ty, a ostatní autori môžu upravovať tento článok."
|
||||||
@@ -848,8 +911,12 @@ msgstr "Aktualizovať heslo"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Pozri si svoju Doručenú poštu!"
|
msgstr "Pozri si svoju Doručenú poštu!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Email s odkazom na obnovenie hesla bol odoslaný na adresu, ktorú si nám dal/a."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Email s odkazom na obnovenie hesla bol odoslaný na adresu, ktorú si nám dal/"
|
||||||
|
"a."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Pošli odkaz na obnovu hesla"
|
msgstr "Pošli odkaz na obnovu hesla"
|
||||||
@@ -857,7 +924,9 @@ msgstr "Pošli odkaz na obnovu hesla"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr "Toto token oprávnenie vypršalo"
|
msgstr "Toto token oprávnenie vypršalo"
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr "Prosím začni odznovu, kliknutím <a href=\"/password-reset\">sem</a>."
|
msgstr "Prosím začni odznovu, kliknutím <a href=\"/password-reset\">sem</a>."
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -872,8 +941,11 @@ msgstr "Vytvor blog"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Uprav \"{}\""
|
msgstr "Uprav \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Do svojej galérie môžeš nahrávať obrázky, ktoré sa potom dajú použiť aj ako ikonky, či záhlavie pre blogy."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Do svojej galérie môžeš nahrávať obrázky, ktoré sa potom dajú použiť aj ako "
|
||||||
|
"ikonky, či záhlavie pre blogy."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Nahraj obrázky"
|
msgstr "Nahraj obrázky"
|
||||||
@@ -891,7 +963,9 @@ msgid "Update blog"
|
|||||||
msgstr "Aktualizuj blog"
|
msgstr "Aktualizuj blog"
|
||||||
|
|
||||||
msgid "Be very careful, any action taken here can't be reversed."
|
msgid "Be very careful, any action taken here can't be reversed."
|
||||||
msgstr "Buď veľmi opatrný/á, akýkoľvek úkon vykonaný v tomto priestore nieje možné vziať späť."
|
msgstr ""
|
||||||
|
"Buď veľmi opatrný/á, akýkoľvek úkon vykonaný v tomto priestore nieje možné "
|
||||||
|
"vziať späť."
|
||||||
|
|
||||||
msgid "Are you sure that you want to permanently delete this blog?"
|
msgid "Are you sure that you want to permanently delete this blog?"
|
||||||
msgstr "Si si istý/á, že chceš natrvalo zmazať tento blog?"
|
msgstr "Si si istý/á, že chceš natrvalo zmazať tento blog?"
|
||||||
@@ -936,8 +1010,13 @@ msgstr "Plume je decentralizovaná blogovacia platforma."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Autori môžu spravovať viacero blogov, každý ako osobitnú stránku."
|
msgstr "Autori môžu spravovať viacero blogov, každý ako osobitnú stránku."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Články sú tiež viditeľné na iných Plume instanciách a môžeš s nimi interaktovať priamo aj z iných federovaných platforiem, ako napríklad Mastodon."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Články sú tiež viditeľné na iných Plume instanciách a môžeš s nimi "
|
||||||
|
"interaktovať priamo aj z iných federovaných platforiem, ako napríklad "
|
||||||
|
"Mastodon."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Prečítaj si podrobné pravidlá"
|
msgstr "Prečítaj si podrobné pravidlá"
|
||||||
@@ -1016,4 +1095,3 @@ msgstr "Uverejnené pod touto licenciou"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Článok je pod licenciou"
|
msgstr "Článok je pod licenciou"
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n%100==4 ? 3 : 0);\n"
|
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 1 : n%100==2 ? 2 : n%100==3 || n"
|
||||||
|
"%100==4 ? 3 : 0);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: sl\n"
|
"X-Crowdin-Language: sl\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +448,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +480,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -791,7 +821,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -848,7 +880,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -857,7 +891,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -872,7 +908,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -936,7 +973,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1016,4 +1055,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+58
-20
@@ -10,7 +10,8 @@ msgstr ""
|
|||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n"
|
||||||
|
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
|
||||||
"X-Crowdin-Project: plume\n"
|
"X-Crowdin-Project: plume\n"
|
||||||
"X-Crowdin-Project-ID: 352097\n"
|
"X-Crowdin-Project-ID: 352097\n"
|
||||||
"X-Crowdin-Language: sr-CS\n"
|
"X-Crowdin-Language: sr-CS\n"
|
||||||
@@ -214,11 +215,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +287,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +448,9 @@ msgstr ""
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +480,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +553,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +640,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +663,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +675,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +757,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -789,7 +819,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -846,7 +878,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -855,7 +889,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -870,7 +906,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -933,7 +970,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1013,4 +1052,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+56
-19
@@ -214,11 +214,15 @@ msgid "Your article has been deleted."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
@@ -282,7 +286,9 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
@@ -441,7 +447,9 @@ msgstr "Lösenord"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
@@ -471,7 +479,8 @@ msgstr ""
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
@@ -543,7 +552,10 @@ msgstr ""
|
|||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
@@ -627,13 +639,21 @@ msgstr ""
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
@@ -642,7 +662,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +674,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,7 +756,9 @@ msgstr ""
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
@@ -787,7 +816,9 @@ msgstr ""
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
@@ -844,7 +875,9 @@ msgstr ""
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
@@ -853,7 +886,9 @@ msgstr ""
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,7 +903,8 @@ msgstr ""
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Redigera \"{}\""
|
msgstr "Redigera \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
@@ -930,7 +966,9 @@ msgstr ""
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
@@ -1010,4 +1048,3 @@ msgstr ""
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
+104
-36
@@ -214,12 +214,20 @@ msgid "Your article has been deleted."
|
|||||||
msgstr "Makalen silindi."
|
msgstr "Makalen silindi."
|
||||||
|
|
||||||
# src/routes/posts.rs:612
|
# src/routes/posts.rs:612
|
||||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
msgid ""
|
||||||
msgstr "Görünüşe göre silmek istediğin makale mevcut değil. Belki de zaten silinmiştir?"
|
"It looks like the article you tried to delete doesn't exist. Maybe it is "
|
||||||
|
"already gone?"
|
||||||
|
msgstr ""
|
||||||
|
"Görünüşe göre silmek istediğin makale mevcut değil. Belki de zaten "
|
||||||
|
"silinmiştir?"
|
||||||
|
|
||||||
# src/routes/posts.rs:652
|
# src/routes/posts.rs:652
|
||||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
msgid ""
|
||||||
msgstr "Hesabın hakkında yeterli bilgi edinemedik. Lütfen kullanıcı adını doğru yazdığından emin ol."
|
"Couldn't obtain enough information about your account. Please make sure your "
|
||||||
|
"username is correct."
|
||||||
|
msgstr ""
|
||||||
|
"Hesabın hakkında yeterli bilgi edinemedik. Lütfen kullanıcı adını doğru "
|
||||||
|
"yazdığından emin ol."
|
||||||
|
|
||||||
# src/routes/reshares.rs:54
|
# src/routes/reshares.rs:54
|
||||||
msgid "To reshare a post, you need to be logged in"
|
msgid "To reshare a post, you need to be logged in"
|
||||||
@@ -282,8 +290,11 @@ msgid "Registrations are closed on this instance."
|
|||||||
msgstr "Bu örnekte kayıtlar kapalıdır."
|
msgstr "Bu örnekte kayıtlar kapalıdır."
|
||||||
|
|
||||||
# src/routes/user.rs:549
|
# src/routes/user.rs:549
|
||||||
msgid "Your account has been created. Now you just need to log in, before you can use it."
|
msgid ""
|
||||||
msgstr "Hesabınız oluşturuldu. Şimdi kullanabilmeniz için giriş yapmanız yeterlidir."
|
"Your account has been created. Now you just need to log in, before you can "
|
||||||
|
"use it."
|
||||||
|
msgstr ""
|
||||||
|
"Hesabınız oluşturuldu. Şimdi kullanabilmeniz için giriş yapmanız yeterlidir."
|
||||||
|
|
||||||
msgid "Media upload"
|
msgid "Media upload"
|
||||||
msgstr "Medya karşıya yükleme"
|
msgstr "Medya karşıya yükleme"
|
||||||
@@ -441,8 +452,12 @@ msgstr "Parola"
|
|||||||
msgid "Password confirmation"
|
msgid "Password confirmation"
|
||||||
msgstr "Parola doğrulama"
|
msgstr "Parola doğrulama"
|
||||||
|
|
||||||
msgid "Apologies, but registrations are closed on this particular instance. You can, however, find a different one."
|
msgid ""
|
||||||
msgstr "Özür dileriz, ancak bu örnek kayıt olmaya kapalıdır. Ama farklı bir tane bulabilirsiniz."
|
"Apologies, but registrations are closed on this particular instance. You "
|
||||||
|
"can, however, find a different one."
|
||||||
|
msgstr ""
|
||||||
|
"Özür dileriz, ancak bu örnek kayıt olmaya kapalıdır. Ama farklı bir tane "
|
||||||
|
"bulabilirsiniz."
|
||||||
|
|
||||||
msgid "{0}'s subscriptions"
|
msgid "{0}'s subscriptions"
|
||||||
msgstr "{0}'in abonelikleri"
|
msgstr "{0}'in abonelikleri"
|
||||||
@@ -454,7 +469,8 @@ msgid "Your Blogs"
|
|||||||
msgstr "Günlüklerin"
|
msgstr "Günlüklerin"
|
||||||
|
|
||||||
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
msgid "You don't have any blog yet. Create your own, or ask to join one."
|
||||||
msgstr "Henüz hiç günlüğün yok :( Bir tane yarat veya birine katılmak için izin al."
|
msgstr ""
|
||||||
|
"Henüz hiç günlüğün yok :( Bir tane yarat veya birine katılmak için izin al."
|
||||||
|
|
||||||
msgid "Start a new blog"
|
msgid "Start a new blog"
|
||||||
msgstr "Yeni bir günlük başlat"
|
msgstr "Yeni bir günlük başlat"
|
||||||
@@ -471,8 +487,10 @@ msgstr "Hesabınızı düzenleyin"
|
|||||||
msgid "Your Profile"
|
msgid "Your Profile"
|
||||||
msgstr "Profiliniz"
|
msgstr "Profiliniz"
|
||||||
|
|
||||||
msgid "To change your avatar, upload it to your gallery and then select from there."
|
msgid ""
|
||||||
msgstr "Avatarınızı değiştirmek için galerinize yükleyin ve ardından oradan seçin."
|
"To change your avatar, upload it to your gallery and then select from there."
|
||||||
|
msgstr ""
|
||||||
|
"Avatarınızı değiştirmek için galerinize yükleyin ve ardından oradan seçin."
|
||||||
|
|
||||||
msgid "Upload an avatar"
|
msgid "Upload an avatar"
|
||||||
msgstr "Bir avatar yükle"
|
msgstr "Bir avatar yükle"
|
||||||
@@ -538,13 +556,20 @@ msgid "Something broke on our side."
|
|||||||
msgstr "Bizim tarafımızda bir şeyler bozuldu."
|
msgstr "Bizim tarafımızda bir şeyler bozuldu."
|
||||||
|
|
||||||
msgid "Sorry about that. If you think this is a bug, please report it."
|
msgid "Sorry about that. If you think this is a bug, please report it."
|
||||||
msgstr "Bunun için üzgünüz. Bunun bir hata olduğunu düşünüyorsanız, lütfen bildirin."
|
msgstr ""
|
||||||
|
"Bunun için üzgünüz. Bunun bir hata olduğunu düşünüyorsanız, lütfen bildirin."
|
||||||
|
|
||||||
msgid "Invalid CSRF token"
|
msgid "Invalid CSRF token"
|
||||||
msgstr "Geçersiz CSRF belirteci"
|
msgstr "Geçersiz CSRF belirteci"
|
||||||
|
|
||||||
msgid "Something is wrong with your CSRF token. Make sure cookies are enabled in you browser, and try reloading this page. If you continue to see this error message, please report it."
|
msgid ""
|
||||||
msgstr "CSRF belirtecinizle ilgili bir sorun var. Tarayıcınızda çerezlerin etkinleştirildiğinden emin olun ve bu sayfayı yeniden yüklemeyi deneyin. Bu hata mesajını görmeye devam ederseniz, lütfen bildirin."
|
"Something is wrong with your CSRF token. Make sure cookies are enabled in "
|
||||||
|
"you browser, and try reloading this page. If you continue to see this error "
|
||||||
|
"message, please report it."
|
||||||
|
msgstr ""
|
||||||
|
"CSRF belirtecinizle ilgili bir sorun var. Tarayıcınızda çerezlerin "
|
||||||
|
"etkinleştirildiğinden emin olun ve bu sayfayı yeniden yüklemeyi deneyin. Bu "
|
||||||
|
"hata mesajını görmeye devam ederseniz, lütfen bildirin."
|
||||||
|
|
||||||
msgid "You are not authorized."
|
msgid "You are not authorized."
|
||||||
msgstr "Yetkiniz yok."
|
msgstr "Yetkiniz yok."
|
||||||
@@ -627,14 +652,30 @@ msgstr "Varsayılan makale lisansı"
|
|||||||
msgid "Save these settings"
|
msgid "Save these settings"
|
||||||
msgstr "Bu ayarları kaydet"
|
msgstr "Bu ayarları kaydet"
|
||||||
|
|
||||||
msgid "If you are browsing this site as a visitor, no data about you is collected."
|
msgid ""
|
||||||
msgstr "Bu siteye ziyaretçi olarak göz atıyorsanız, hakkınızda veri toplanmamaktadır."
|
"If you are browsing this site as a visitor, no data about you is collected."
|
||||||
|
msgstr ""
|
||||||
|
"Bu siteye ziyaretçi olarak göz atıyorsanız, hakkınızda veri toplanmamaktadır."
|
||||||
|
|
||||||
msgid "As a registered user, you have to provide your username (which does not have to be your real name), your functional email address and a password, in order to be able to log in, write articles and comment. The content you submit is stored until you delete it."
|
msgid ""
|
||||||
msgstr "Kayıtlı bir kullanıcı olarak, giriş yapmak, makale yazmak ve yorum yapmak için bir kullanıcı adına (ki bu kullanıcı adının senin gerçek adın olması gerekmiyor), kullanabildiğin bir e-posta adresine ve bir şifreye ihtiyacın var. Girdiğin bilgiler sen hesabını silene dek depolanır."
|
"As a registered user, you have to provide your username (which does not have "
|
||||||
|
"to be your real name), your functional email address and a password, in "
|
||||||
|
"order to be able to log in, write articles and comment. The content you "
|
||||||
|
"submit is stored until you delete it."
|
||||||
|
msgstr ""
|
||||||
|
"Kayıtlı bir kullanıcı olarak, giriş yapmak, makale yazmak ve yorum yapmak "
|
||||||
|
"için bir kullanıcı adına (ki bu kullanıcı adının senin gerçek adın olması "
|
||||||
|
"gerekmiyor), kullanabildiğin bir e-posta adresine ve bir şifreye ihtiyacın "
|
||||||
|
"var. Girdiğin bilgiler sen hesabını silene dek depolanır."
|
||||||
|
|
||||||
msgid "When you log in, we store two cookies, one to keep your session open, the second to prevent other people to act on your behalf. We don't store any other cookies."
|
msgid ""
|
||||||
msgstr "Giriş yaptığınızda; biri oturumunuzu açık tutmak için, ikincisi başkalarının sizin adınıza hareket etmesini önlemek için iki çerez saklamaktayız. Başka çerez saklamıyoruz."
|
"When you log in, we store two cookies, one to keep your session open, the "
|
||||||
|
"second to prevent other people to act on your behalf. We don't store any "
|
||||||
|
"other cookies."
|
||||||
|
msgstr ""
|
||||||
|
"Giriş yaptığınızda; biri oturumunuzu açık tutmak için, ikincisi başkalarının "
|
||||||
|
"sizin adınıza hareket etmesini önlemek için iki çerez saklamaktayız. Başka "
|
||||||
|
"çerez saklamıyoruz."
|
||||||
|
|
||||||
msgid "Blocklisted Emails"
|
msgid "Blocklisted Emails"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -642,7 +683,10 @@ msgstr ""
|
|||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The email address you wish to block. In order to block domains, you can use globbing syntax, for example '*@example.com' blocks all addresses from example.com"
|
msgid ""
|
||||||
|
"The email address you wish to block. In order to block domains, you can use "
|
||||||
|
"globbing syntax, for example '*@example.com' blocks all addresses from "
|
||||||
|
"example.com"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Note"
|
msgid "Note"
|
||||||
@@ -651,13 +695,17 @@ msgstr ""
|
|||||||
msgid "Notify the user?"
|
msgid "Notify the user?"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Optional, shows a message to the user when they attempt to create an account with that address"
|
msgid ""
|
||||||
|
"Optional, shows a message to the user when they attempt to create an account "
|
||||||
|
"with that address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Blocklisting notification"
|
msgid "Blocklisting notification"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "The message to be shown when the user attempts to create an account with this email address"
|
msgid ""
|
||||||
|
"The message to be shown when the user attempts to create an account with "
|
||||||
|
"this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Add blocklisted address"
|
msgid "Add blocklisted address"
|
||||||
@@ -729,8 +777,12 @@ msgstr "Altyazı"
|
|||||||
msgid "Content"
|
msgid "Content"
|
||||||
msgstr "İçerik"
|
msgstr "İçerik"
|
||||||
|
|
||||||
msgid "You can upload media to your gallery, and then copy their Markdown code into your articles to insert them."
|
msgid ""
|
||||||
msgstr "Galerine bir resim ekleyebilir, daha sonra makalene eklemek için resmin Markdown kodunu kopyalayabilirsin."
|
"You can upload media to your gallery, and then copy their Markdown code into "
|
||||||
|
"your articles to insert them."
|
||||||
|
msgstr ""
|
||||||
|
"Galerine bir resim ekleyebilir, daha sonra makalene eklemek için resmin "
|
||||||
|
"Markdown kodunu kopyalayabilirsin."
|
||||||
|
|
||||||
msgid "Upload media"
|
msgid "Upload media"
|
||||||
msgstr "Medyayı karşıya yükle"
|
msgstr "Medyayı karşıya yükle"
|
||||||
@@ -787,8 +839,12 @@ msgstr "Bunu artık desteklemek istemiyorum"
|
|||||||
msgid "Boost"
|
msgid "Boost"
|
||||||
msgstr "Destekle"
|
msgstr "Destekle"
|
||||||
|
|
||||||
msgid "{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this article"
|
msgid ""
|
||||||
msgstr "{0}Giriş yaparak{1}, ya da {2}Fediverse hesabını kullanarak{3} bu makaleyle iletişime geç"
|
"{0}Log in{1}, or {2}use your Fediverse account{3} to interact with this "
|
||||||
|
"article"
|
||||||
|
msgstr ""
|
||||||
|
"{0}Giriş yaparak{1}, ya da {2}Fediverse hesabını kullanarak{3} bu makaleyle "
|
||||||
|
"iletişime geç"
|
||||||
|
|
||||||
msgid "Comments"
|
msgid "Comments"
|
||||||
msgstr "Yorumlar"
|
msgstr "Yorumlar"
|
||||||
@@ -806,7 +862,8 @@ msgid "Are you sure?"
|
|||||||
msgstr "Emin misiniz?"
|
msgstr "Emin misiniz?"
|
||||||
|
|
||||||
msgid "This article is still a draft. Only you and other authors can see it."
|
msgid "This article is still a draft. Only you and other authors can see it."
|
||||||
msgstr "Bu makale hâlâ bir taslak. Yalnızca sen ve diğer yazarlar bunu görebilir."
|
msgstr ""
|
||||||
|
"Bu makale hâlâ bir taslak. Yalnızca sen ve diğer yazarlar bunu görebilir."
|
||||||
|
|
||||||
msgid "Only you and other authors can edit this article."
|
msgid "Only you and other authors can edit this article."
|
||||||
msgstr "Sadece sen ve diğer yazarlar bu makaleyi düzenleyebilir."
|
msgstr "Sadece sen ve diğer yazarlar bu makaleyi düzenleyebilir."
|
||||||
@@ -844,8 +901,11 @@ msgstr "Parolayı güncelle"
|
|||||||
msgid "Check your inbox!"
|
msgid "Check your inbox!"
|
||||||
msgstr "Gelen kutunuzu kontrol edin!"
|
msgstr "Gelen kutunuzu kontrol edin!"
|
||||||
|
|
||||||
msgid "We sent a mail to the address you gave us, with a link to reset your password."
|
msgid ""
|
||||||
msgstr "Bize verdiğiniz adrese, parola sıfırlama linki içeren bir e-posta gönderdik."
|
"We sent a mail to the address you gave us, with a link to reset your "
|
||||||
|
"password."
|
||||||
|
msgstr ""
|
||||||
|
"Bize verdiğiniz adrese, parola sıfırlama linki içeren bir e-posta gönderdik."
|
||||||
|
|
||||||
msgid "Send password reset link"
|
msgid "Send password reset link"
|
||||||
msgstr "Parola sıfırlama linki gönder"
|
msgstr "Parola sıfırlama linki gönder"
|
||||||
@@ -853,7 +913,9 @@ msgstr "Parola sıfırlama linki gönder"
|
|||||||
msgid "This token has expired"
|
msgid "This token has expired"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Please start the process again by clicking <a href=\"/password-reset\">here</a>."
|
msgid ""
|
||||||
|
"Please start the process again by clicking <a href=\"/password-reset\">here</"
|
||||||
|
"a>."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "New Blog"
|
msgid "New Blog"
|
||||||
@@ -868,8 +930,11 @@ msgstr "Günlük oluştur"
|
|||||||
msgid "Edit \"{}\""
|
msgid "Edit \"{}\""
|
||||||
msgstr "Düzenle: \"{}\""
|
msgstr "Düzenle: \"{}\""
|
||||||
|
|
||||||
msgid "You can upload images to your gallery, to use them as blog icons, or banners."
|
msgid ""
|
||||||
msgstr "Günlük simgeleri veya manşeti olarak kullanmak için resimleri galerinize yükleyebilirsiniz."
|
"You can upload images to your gallery, to use them as blog icons, or banners."
|
||||||
|
msgstr ""
|
||||||
|
"Günlük simgeleri veya manşeti olarak kullanmak için resimleri galerinize "
|
||||||
|
"yükleyebilirsiniz."
|
||||||
|
|
||||||
msgid "Upload images"
|
msgid "Upload images"
|
||||||
msgstr "Resimleri karşıya yükle"
|
msgstr "Resimleri karşıya yükle"
|
||||||
@@ -930,8 +995,12 @@ msgstr "Plume merkezi olmayan bir internet günlüğü yazma motorudur."
|
|||||||
msgid "Authors can manage multiple blogs, each as its own website."
|
msgid "Authors can manage multiple blogs, each as its own website."
|
||||||
msgstr "Yazarlar her biri farklı sitedeki birden çok günlüğü yönetebilirler."
|
msgstr "Yazarlar her biri farklı sitedeki birden çok günlüğü yönetebilirler."
|
||||||
|
|
||||||
msgid "Articles are also visible on other Plume instances, and you can interact with them directly from other platforms like Mastodon."
|
msgid ""
|
||||||
msgstr "Makaleler ayrıca diğer Plume oluşumlarında da görünür. Mastodon gibi platformlardan yazılarla doğrudan etkileşime geçebilirsin."
|
"Articles are also visible on other Plume instances, and you can interact "
|
||||||
|
"with them directly from other platforms like Mastodon."
|
||||||
|
msgstr ""
|
||||||
|
"Makaleler ayrıca diğer Plume oluşumlarında da görünür. Mastodon gibi "
|
||||||
|
"platformlardan yazılarla doğrudan etkileşime geçebilirsin."
|
||||||
|
|
||||||
msgid "Read the detailed rules"
|
msgid "Read the detailed rules"
|
||||||
msgstr "Detaylı kuralları oku"
|
msgstr "Detaylı kuralları oku"
|
||||||
@@ -1010,4 +1079,3 @@ msgstr "Bu lisans altında yayınlanan"
|
|||||||
|
|
||||||
msgid "Article license"
|
msgid "Article license"
|
||||||
msgstr "Makale lisansı"
|
msgstr "Makale lisansı"
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user