mirror of
https://git.joinplu.me/Plume/Plume.git
synced 2024-11-14 07:51:01 +00:00
Merge pull request 'Search Actor' (#870) from search-actor into main
Reviewed-on: https://git.joinplu.me/Plume/Plume/pulls/870
This commit is contained in:
commit
46fc030df4
23 changed files with 674 additions and 223 deletions
|
@ -143,6 +143,7 @@ jobs:
|
|||
cache: <<#parameters.postgres>>postgres<</ parameters.postgres>><<^parameters.postgres>>sqlite<</parameters.postgres>>
|
||||
- run_with_coverage:
|
||||
cmd: |
|
||||
cargo run -p plume-cli --no-default-features --features=${FEATURES} -- migration run
|
||||
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
|
||||
$cmd $i && break
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
- Allow `dir` attributes for LtoR text in RtoL document (#860)
|
||||
- More translation languages (#862)
|
||||
- Proxy support (#829)
|
||||
- Riker a actor system library (#870)
|
||||
|
||||
### Changed
|
||||
|
||||
|
@ -16,6 +17,7 @@
|
|||
- 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
|
||||
|
||||
|
|
289
Cargo.lock
generated
289
Cargo.lock
generated
|
@ -9,7 +9,7 @@ dependencies = [
|
|||
"activitystreams-derive",
|
||||
"activitystreams-traits",
|
||||
"activitystreams-types",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -32,7 +32,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "670ef03168e704b0cae242e7a5d8b40506772b339687e01a3496fc4afe2e8542"
|
||||
dependencies = [
|
||||
"failure",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -46,7 +46,7 @@ dependencies = [
|
|||
"activitystreams-traits",
|
||||
"chrono",
|
||||
"mime 0.3.16",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -126,6 +126,9 @@ name = "ahash"
|
|||
version = "0.3.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8fd72866655d1904d6b0997d0b07ba561047d070fbe29de039031c641b61217"
|
||||
dependencies = [
|
||||
"const-random",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
|
@ -168,6 +171,12 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "arc-swap"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dabe5a181f83789739c194cbe5a897dde195078fac08568d09221fd6137a7ba8"
|
||||
|
||||
[[package]]
|
||||
name = "array_tool"
|
||||
version = "1.0.3"
|
||||
|
@ -344,7 +353,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "f30d3a39baa26f9651f17b375061f3233dde33424a8b72b0dbe93a68a0bc896d"
|
||||
dependencies = [
|
||||
"byteorder 1.3.4",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -516,8 +525,8 @@ checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
|
|||
dependencies = [
|
||||
"libc",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"num-traits 0.2.14",
|
||||
"serde 1.0.118",
|
||||
"time",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
@ -555,6 +564,44 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "config"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "19b076e143e1d9538dde65da30f8481c2a6c44040edb8e02b9bf1351edb92ce3"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"nom 5.1.2",
|
||||
"rust-ini",
|
||||
"serde 1.0.118",
|
||||
"serde-hjson",
|
||||
"serde_json",
|
||||
"toml 0.5.8",
|
||||
"yaml-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f590d95d011aa80b063ffe3253422ed5aa462af4e9867d43ce8337562bac77c4"
|
||||
dependencies = [
|
||||
"const-random-macro",
|
||||
"proc-macro-hack 0.5.19",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const-random-macro"
|
||||
version = "0.1.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "615f6e27d000a2bffbc7f2f6a8669179378fa27ee4d0a509e985dfc0a7defb40"
|
||||
dependencies = [
|
||||
"getrandom 0.2.1",
|
||||
"lazy_static",
|
||||
"proc-macro-hack 0.5.19",
|
||||
"tiny-keccak",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "const_fn"
|
||||
version = "0.4.4"
|
||||
|
@ -607,7 +654,7 @@ dependencies = [
|
|||
"idna 0.1.5",
|
||||
"log 0.4.11",
|
||||
"publicsuffix",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"time",
|
||||
"try_from",
|
||||
|
@ -789,6 +836,17 @@ version = "0.1.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ef8ae57c4978a2acd8b869ce6b9ca1dfe817bff704c220209fdef2c0b75a01b9"
|
||||
|
||||
[[package]]
|
||||
name = "dashmap"
|
||||
version = "3.11.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0f260e2fc850179ef410018660006951c1b55b79e8087e87111a2c388994b9b5"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"cfg-if 0.1.10",
|
||||
"num_cpus",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "data-encoding"
|
||||
version = "2.1.2"
|
||||
|
@ -1370,6 +1428,17 @@ dependencies = [
|
|||
"wasi 0.9.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4060f4657be78b8e766215b02b18a2e862d83745545de804638e2b545e81aee6"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gettext"
|
||||
version = "0.3.0"
|
||||
|
@ -1943,7 +2012,7 @@ dependencies = [
|
|||
"log 0.4.11",
|
||||
"native-tls",
|
||||
"nom 4.2.3",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -2010,7 +2079,7 @@ dependencies = [
|
|||
"lindera-dictionary",
|
||||
"lindera-ipadic",
|
||||
"lindera-ipadic-builder",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -2023,7 +2092,7 @@ dependencies = [
|
|||
"bincode",
|
||||
"byteorder 1.3.4",
|
||||
"encoding",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"yada",
|
||||
]
|
||||
|
||||
|
@ -2091,9 +2160,13 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "linked-hash-map"
|
||||
version = "0.5.3"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8dd5a6d5999d9907cda8ed67bbd137d3af8085216c2ac62de5be860bd41f304a"
|
||||
checksum = "6d262045c5b87c0861b3f004610afd0e2c851e2908d08b6c870cbb9d5f494ecd"
|
||||
dependencies = [
|
||||
"serde 0.8.23",
|
||||
"serde_test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
|
@ -2152,7 +2225,7 @@ dependencies = [
|
|||
"log 0.4.11",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"string_cache",
|
||||
|
@ -2504,7 +2577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
|
||||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2515,7 +2588,16 @@ checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef"
|
|||
dependencies = [
|
||||
"autocfg 1.0.1",
|
||||
"num-integer",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-traits"
|
||||
version = "0.1.43"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
|
||||
dependencies = [
|
||||
"num-traits 0.2.14",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2826,7 +2908,7 @@ dependencies = [
|
|||
"chrono",
|
||||
"indexmap",
|
||||
"line-wrap",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"xml-rs",
|
||||
]
|
||||
|
||||
|
@ -2854,6 +2936,7 @@ dependencies = [
|
|||
"plume-api",
|
||||
"plume-common",
|
||||
"plume-models",
|
||||
"riker",
|
||||
"rocket",
|
||||
"rocket_contrib",
|
||||
"rocket_csrf",
|
||||
|
@ -2862,7 +2945,7 @@ dependencies = [
|
|||
"rsass",
|
||||
"ructe",
|
||||
"scheduled-thread-pool",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"shrinkwraprs 0.2.3",
|
||||
"tracing",
|
||||
|
@ -2876,7 +2959,7 @@ dependencies = [
|
|||
name = "plume-api"
|
||||
version = "0.6.1-dev"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
|
@ -2909,7 +2992,7 @@ dependencies = [
|
|||
"regex-syntax 0.6.21",
|
||||
"reqwest 0.9.24",
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"shrinkwraprs 0.3.0",
|
||||
|
@ -2926,7 +3009,7 @@ dependencies = [
|
|||
"gettext-macros",
|
||||
"gettext-utils",
|
||||
"lazy_static",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"stdweb",
|
||||
"stdweb-internal-runtime",
|
||||
|
@ -2961,15 +3044,17 @@ dependencies = [
|
|||
"ldap3",
|
||||
"lindera-tantivy",
|
||||
"migrations_internals",
|
||||
"once_cell",
|
||||
"openssl",
|
||||
"plume-api",
|
||||
"plume-common",
|
||||
"plume-macro",
|
||||
"reqwest 0.9.24",
|
||||
"riker",
|
||||
"rocket",
|
||||
"rocket_i18n",
|
||||
"scheduled-thread-pool",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"shrinkwraprs 0.2.3",
|
||||
|
@ -3220,7 +3305,7 @@ version = "0.7.3"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.1.15",
|
||||
"libc",
|
||||
"rand_chacha 0.2.2",
|
||||
"rand_core 0.5.1",
|
||||
|
@ -3268,7 +3353,7 @@ version = "0.5.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
|
||||
dependencies = [
|
||||
"getrandom",
|
||||
"getrandom 0.1.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3445,7 +3530,7 @@ dependencies = [
|
|||
"mime 0.3.16",
|
||||
"mime_guess 2.0.3",
|
||||
"native-tls",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"serde_urlencoded 0.5.5",
|
||||
"socks",
|
||||
|
@ -3484,7 +3569,7 @@ dependencies = [
|
|||
"native-tls",
|
||||
"percent-encoding 2.1.0",
|
||||
"pin-project-lite 0.2.0",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_urlencoded 0.7.0",
|
||||
"tokio 0.2.24",
|
||||
"tokio-tls",
|
||||
|
@ -3495,6 +3580,38 @@ dependencies = [
|
|||
"winreg 0.7.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "riker"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abff93ece5a5d3d7f2c54dfba7550657a644c9dc0a871c7ddf8c31381971c41b"
|
||||
dependencies = [
|
||||
"chrono",
|
||||
"config",
|
||||
"dashmap",
|
||||
"futures 0.3.8",
|
||||
"num_cpus",
|
||||
"pin-utils",
|
||||
"rand 0.7.3",
|
||||
"regex",
|
||||
"riker-macros",
|
||||
"slog",
|
||||
"slog-scope",
|
||||
"slog-stdlog",
|
||||
"uuid 0.8.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "riker-macros"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d2a8e8f71c9e7980a596c39c7e3537ea8563054526e15712a610ac97a02dba15"
|
||||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ring"
|
||||
version = "0.13.5"
|
||||
|
@ -3523,7 +3640,7 @@ dependencies = [
|
|||
"rocket_http",
|
||||
"state",
|
||||
"time",
|
||||
"toml",
|
||||
"toml 0.4.10",
|
||||
"version_check 0.9.2",
|
||||
"yansi",
|
||||
]
|
||||
|
@ -3552,7 +3669,7 @@ dependencies = [
|
|||
"log 0.4.11",
|
||||
"notify",
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
]
|
||||
|
||||
|
@ -3564,7 +3681,7 @@ dependencies = [
|
|||
"data-encoding",
|
||||
"ring",
|
||||
"rocket",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"time",
|
||||
]
|
||||
|
||||
|
@ -3623,7 +3740,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"nom 4.2.3",
|
||||
"num-rational",
|
||||
"num-traits",
|
||||
"num-traits 0.2.14",
|
||||
"rand 0.6.5",
|
||||
]
|
||||
|
||||
|
@ -3640,13 +3757,19 @@ dependencies = [
|
|||
"nom 5.1.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-ini"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3e52c148ef37f8c375d49d5a73aa70713125b7f19095948a923f80afdeb22ec2"
|
||||
|
||||
[[package]]
|
||||
name = "rust-stemmers"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e46a2036019fdb888131db7a4c847a1063a7493f971ed94ea82c67eada63ca54"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
|
@ -3749,6 +3872,12 @@ version = "0.7.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9dad3f759919b92c3068c696c15c3d17238234498bbdcc80f2c469606f948ac8"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.118"
|
||||
|
@ -3758,6 +3887,19 @@ dependencies = [
|
|||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde-hjson"
|
||||
version = "0.9.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6a3a4e0ea8a88553209f6cc6cfe8724ecad22e1acf372793c27d995290fe74f8"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"linked-hash-map",
|
||||
"num-traits 0.1.43",
|
||||
"regex",
|
||||
"serde 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.118"
|
||||
|
@ -3777,7 +3919,16 @@ checksum = "4fceb2595057b6891a4ee808f70054bd2d12f0e97f1cbb78689b59f676df325a"
|
|||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_test"
|
||||
version = "0.8.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "110b3dbdf8607ec493c22d5d947753282f3bae73c0f56d322af1e8c78e4c23d5"
|
||||
dependencies = [
|
||||
"serde 0.8.23",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3788,7 +3939,7 @@ checksum = "642dd69105886af2efd227f75a520ec9b44a820d65bc133a9131f7d229fd165a"
|
|||
dependencies = [
|
||||
"dtoa",
|
||||
"itoa",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"url 1.7.2",
|
||||
]
|
||||
|
||||
|
@ -3801,7 +3952,7 @@ dependencies = [
|
|||
"form_urlencoded",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3878,6 +4029,34 @@ version = "0.4.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
|
||||
[[package]]
|
||||
name = "slog"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8347046d4ebd943127157b94d63abb990fcf729dc4e9978927fdf4ac3c998d06"
|
||||
|
||||
[[package]]
|
||||
name = "slog-scope"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7c44c89dd8b0ae4537d1ae318353eaf7840b4869c536e31c41e963d1ea523ee6"
|
||||
dependencies = [
|
||||
"arc-swap",
|
||||
"lazy_static",
|
||||
"slog",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "slog-stdlog"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8228ab7302adbf4fcb37e66f3cda78003feb521e7fd9e3847ec117a7784d0f5a"
|
||||
dependencies = [
|
||||
"log 0.4.11",
|
||||
"slog",
|
||||
"slog-scope",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "0.6.13"
|
||||
|
@ -3948,7 +4127,7 @@ checksum = "a68c0ce28cf7400ed022e18da3c4591e14e1df02c70e93573cc59921b3923aeb"
|
|||
dependencies = [
|
||||
"discard",
|
||||
"rustc_version",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"stdweb-derive",
|
||||
"stdweb-internal-macros",
|
||||
|
@ -3964,7 +4143,7 @@ checksum = "0e21ebd9179de08f2300a65454268a17ea3de204627458588c84319c4def3930"
|
|||
dependencies = [
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"syn 0.15.44",
|
||||
]
|
||||
|
@ -3978,7 +4157,7 @@ dependencies = [
|
|||
"base-x",
|
||||
"proc-macro2 0.4.30",
|
||||
"quote 0.6.13",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha1",
|
||||
|
@ -4010,7 +4189,7 @@ dependencies = [
|
|||
"new_debug_unreachable",
|
||||
"phf_shared",
|
||||
"precomputed-hash",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"string_cache_codegen",
|
||||
"string_cache_shared",
|
||||
]
|
||||
|
@ -4154,7 +4333,7 @@ dependencies = [
|
|||
"onig",
|
||||
"plist",
|
||||
"regex-syntax 0.6.21",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"walkdir",
|
||||
|
@ -4194,7 +4373,7 @@ dependencies = [
|
|||
"rayon",
|
||||
"regex",
|
||||
"rust-stemmers",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"smallvec 1.5.1",
|
||||
"snap",
|
||||
|
@ -4322,6 +4501,15 @@ dependencies = [
|
|||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tiny-keccak"
|
||||
version = "2.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
|
||||
dependencies = [
|
||||
"crunchy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec"
|
||||
version = "1.1.0"
|
||||
|
@ -4605,7 +4793,16 @@ version = "0.4.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "758664fc71a3a69038656bee8b6be6477d2a6c315a6b81f7081f591bffa4111f"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.5.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
|
||||
dependencies = [
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4674,7 +4871,7 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
|
@ -4689,7 +4886,7 @@ dependencies = [
|
|||
"lazy_static",
|
||||
"matchers",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"sharded-slab",
|
||||
"smallvec 1.5.1",
|
||||
|
@ -4875,7 +5072,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "9fde2f6a4bea1d6e007c4ad38c6839fa71cbb63b6dbf5b595aa38dc9b1093c11"
|
||||
dependencies = [
|
||||
"rand 0.7.3",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -4887,7 +5084,7 @@ dependencies = [
|
|||
"idna 0.1.5",
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"url 1.7.2",
|
||||
|
@ -4989,7 +5186,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3cd364751395ca0f68cafb17666eee36b63077fb5ecd972bbcd74c90c4bf736e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_json",
|
||||
"wasm-bindgen-macro",
|
||||
]
|
||||
|
@ -5067,7 +5264,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "ec24b1b0700d4b466d280228ed0f62274eedeaa80206820f071fdc8ed787b664"
|
||||
dependencies = [
|
||||
"reqwest 0.9.24",
|
||||
"serde",
|
||||
"serde 1.0.118",
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ validator_derive = "0.8"
|
|||
webfinger = "0.4.1"
|
||||
tracing = "0.1.22"
|
||||
tracing-subscriber = "0.2.15"
|
||||
riker = "0.4.2"
|
||||
|
||||
[[bin]]
|
||||
name = "plume"
|
||||
|
|
|
@ -33,6 +33,8 @@ diesel-derive-newtype = "0.1.2"
|
|||
glob = "0.3.0"
|
||||
lindera-tantivy = { version = "0.7.1", optional = true }
|
||||
tracing = "0.1.22"
|
||||
riker = "0.4.2"
|
||||
once_cell = "1.5.2"
|
||||
|
||||
[dependencies.chrono]
|
||||
features = ["serde"]
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use crate::{
|
||||
ap_url, instance::*, medias::Media, posts::Post, safe_string::SafeString, schema::blogs,
|
||||
search::Searcher, users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||
users::User, Connection, Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||
};
|
||||
use activitypub::{
|
||||
actor::Group,
|
||||
|
@ -317,9 +317,9 @@ impl Blog {
|
|||
.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)? {
|
||||
post.delete(conn, searcher)?;
|
||||
post.delete(conn)?;
|
||||
}
|
||||
diesel::delete(self)
|
||||
.execute(conn)
|
||||
|
@ -497,10 +497,8 @@ pub(crate) mod tests {
|
|||
use super::*;
|
||||
use crate::{
|
||||
blog_authors::*,
|
||||
config::CONFIG,
|
||||
instance::tests as instance_tests,
|
||||
medias::NewMedia,
|
||||
search::tests::get_searcher,
|
||||
tests::{db, rockets},
|
||||
users::tests as usersTests,
|
||||
Connection as Conn,
|
||||
|
@ -767,9 +765,7 @@ pub(crate) mod tests {
|
|||
conn.test_transaction::<_, (), _>(|| {
|
||||
let (_, blogs) = fill_database(conn);
|
||||
|
||||
blogs[0]
|
||||
.delete(conn, &get_searcher(&CONFIG.search_tokenizers))
|
||||
.unwrap();
|
||||
blogs[0].delete(conn).unwrap();
|
||||
assert!(Blog::get(conn, blogs[0].id).is_err());
|
||||
Ok(())
|
||||
})
|
||||
|
@ -779,7 +775,6 @@ pub(crate) mod tests {
|
|||
fn delete_via_user() {
|
||||
let conn = &db();
|
||||
conn.test_transaction::<_, (), _>(|| {
|
||||
let searcher = get_searcher(&CONFIG.search_tokenizers);
|
||||
let (user, _) = fill_database(conn);
|
||||
|
||||
let b1 = Blog::insert(
|
||||
|
@ -836,10 +831,10 @@ pub(crate) mod tests {
|
|||
)
|
||||
.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[1].id).is_err());
|
||||
user[1].delete(conn, &searcher).unwrap();
|
||||
user[1].delete(conn).unwrap();
|
||||
assert!(Blog::get(conn, blog[0].id).is_err());
|
||||
Ok(())
|
||||
})
|
||||
|
@ -886,7 +881,7 @@ pub(crate) mod tests {
|
|||
let _: Blog = blogs[0].save_changes(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();
|
||||
|
||||
assert_eq!(blog.actor_id, blogs[0].actor_id);
|
||||
|
|
|
@ -97,7 +97,6 @@ pub(crate) mod tests {
|
|||
source: String::new(),
|
||||
cover_id: None,
|
||||
},
|
||||
&rockets.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -17,7 +17,10 @@ extern crate serde_json;
|
|||
#[macro_use]
|
||||
extern crate tantivy;
|
||||
|
||||
use once_cell::sync::Lazy;
|
||||
use plume_common::activity_pub::inbox::InboxError;
|
||||
use posts::PostEvent;
|
||||
use riker::actors::{channel, ActorSystem, ChannelRef, SystemBuilder};
|
||||
|
||||
#[cfg(not(any(feature = "sqlite", feature = "postgres")))]
|
||||
compile_error!("Either feature \"sqlite\" or \"postgres\" must be enabled for this crate.");
|
||||
|
@ -30,6 +33,16 @@ pub type Connection = diesel::SqliteConnection;
|
|||
#[cfg(all(not(feature = "sqlite"), feature = "postgres"))]
|
||||
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 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
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use crate::{
|
||||
ap_url, blogs::Blog, instance::Instance, medias::Media, mentions::Mention, post_authors::*,
|
||||
safe_string::SafeString, schema::posts, search::Searcher, tags::*, timeline::*, users::User,
|
||||
Connection, Error, PlumeRocket, Result, CONFIG,
|
||||
safe_string::SafeString, schema::posts, tags::*, timeline::*, users::User, Connection, Error,
|
||||
PlumeRocket, PostEvent::*, Result, CONFIG, POST_CHAN,
|
||||
};
|
||||
use activitypub::{
|
||||
activity::{Create, Delete, Update},
|
||||
|
@ -19,11 +19,13 @@ use plume_common::{
|
|||
},
|
||||
utils::md_to_html,
|
||||
};
|
||||
use riker::actors::{Publish, Tell};
|
||||
use std::collections::HashSet;
|
||||
use std::sync::Arc;
|
||||
|
||||
pub type LicensedArticle = CustomObject<Licensed, Article>;
|
||||
|
||||
#[derive(Queryable, Identifiable, Clone, AsChangeset)]
|
||||
#[derive(Queryable, Identifiable, Clone, AsChangeset, Debug)]
|
||||
#[changeset_options(treat_none_as_null = "true")]
|
||||
pub struct Post {
|
||||
pub id: i32,
|
||||
|
@ -62,7 +64,7 @@ impl Post {
|
|||
find_by!(posts, find_by_ap_url, ap_url as &str);
|
||||
|
||||
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)
|
||||
.values(new)
|
||||
.execute(conn)?;
|
||||
|
@ -77,23 +79,29 @@ impl Post {
|
|||
let _: Post = post.save_changes(conn)?;
|
||||
}
|
||||
|
||||
searcher.add_document(conn, &post)?;
|
||||
if post.published {
|
||||
post.publish_published();
|
||||
}
|
||||
|
||||
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)?;
|
||||
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)
|
||||
}
|
||||
|
||||
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)? {
|
||||
m.delete(conn)?;
|
||||
}
|
||||
diesel::delete(self).execute(conn)?;
|
||||
searcher.delete_document(self);
|
||||
self.publish_deleted();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -545,6 +553,36 @@ impl Post {
|
|||
.set_to_link_vec(vec![Id::new(PUBLIC_VISIBILITY)])?;
|
||||
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 {
|
||||
|
@ -557,7 +595,6 @@ impl FromId<PlumeRocket> for Post {
|
|||
|
||||
fn from_activity(c: &PlumeRocket, article: LicensedArticle) -> Result<Self> {
|
||||
let conn = &*c.conn;
|
||||
let searcher = &c.searcher;
|
||||
let license = article.custom_props.license_string().unwrap_or_default();
|
||||
let article = article.object;
|
||||
|
||||
|
@ -605,7 +642,6 @@ impl FromId<PlumeRocket> for Post {
|
|||
source: article.ap_object_props.source_object::<Source>()?.content,
|
||||
cover_id: cover,
|
||||
},
|
||||
searcher,
|
||||
)?;
|
||||
|
||||
for author in authors {
|
||||
|
@ -670,7 +706,7 @@ impl AsObject<User, Delete, &PlumeRocket> for Post {
|
|||
.into_iter()
|
||||
.any(|a| actor.id == a.id);
|
||||
if can_delete {
|
||||
self.delete(&c.conn, &c.searcher).map(|_| ())
|
||||
self.delete(&c.conn).map(|_| ())
|
||||
} else {
|
||||
Err(Error::Unauthorized)
|
||||
}
|
||||
|
@ -727,7 +763,6 @@ impl AsObject<User, Update, &PlumeRocket> for PostUpdate {
|
|||
|
||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
||||
let conn = &*c.conn;
|
||||
let searcher = &c.searcher;
|
||||
let mut post = Post::from_id(c, &self.ap_url, None, CONFIG.proxy()).map_err(|(_, e)| e)?;
|
||||
|
||||
if !post.is_author(conn, actor.id)? {
|
||||
|
@ -789,7 +824,7 @@ impl AsObject<User, Update, &PlumeRocket> for PostUpdate {
|
|||
post.update_hashtags(conn, hashtags)?;
|
||||
}
|
||||
|
||||
post.update(conn, searcher)?;
|
||||
post.update(conn)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
@ -800,6 +835,25 @@ 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)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -831,7 +885,6 @@ mod tests {
|
|||
source: "Hello".into(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
PostAuthor::insert(
|
||||
|
@ -843,7 +896,7 @@ mod tests {
|
|||
)
|
||||
.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() {
|
||||
InboxResult::Post(p) => {
|
||||
|
|
207
plume-models/src/search/actor.rs
Normal file
207
plume-models/src/search/actor.rs
Normal file
|
@ -0,0 +1,207 @@
|
|||
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::diesel::RunQueryDsl;
|
||||
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
|
||||
);
|
||||
// TODO: Make sure records are deleted even when assertion failed
|
||||
post.delete(&conn).unwrap();
|
||||
blog.delete(&conn).unwrap();
|
||||
user.delete(&conn).unwrap();
|
||||
diesel::delete(&instance).execute(&conn).unwrap();
|
||||
}
|
||||
|
||||
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: true,
|
||||
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 mut user = NewUser::default();
|
||||
user.instance_id = instance.id;
|
||||
user.username = random_hex().to_string();
|
||||
user.ap_url = random_hex().to_string();
|
||||
user.inbox_url = random_hex().to_string();
|
||||
user.outbox_url = random_hex().to_string();
|
||||
user.followers_endpoint = random_hex().to_string();
|
||||
let user = User::insert(conn, user).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 searcher;
|
||||
mod tokenizer;
|
||||
|
@ -7,12 +8,7 @@ pub use self::tokenizer::TokenizerKind;
|
|||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod tests {
|
||||
use super::{Query, Searcher, TokenizerKind};
|
||||
use diesel::Connection;
|
||||
use plume_common::utils::random_hex;
|
||||
use std::env::temp_dir;
|
||||
use std::str::FromStr;
|
||||
|
||||
use super::{Query, Searcher};
|
||||
use crate::{
|
||||
blogs::tests::fill_database,
|
||||
config::SearchTokenizerConfig,
|
||||
|
@ -22,6 +18,10 @@ pub(crate) mod tests {
|
|||
tests::db,
|
||||
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 {
|
||||
let dir = temp_dir().join(&format!("plume-test-{}", random_hex()));
|
||||
|
@ -144,7 +144,6 @@ pub(crate) mod tests {
|
|||
source: "".to_owned(),
|
||||
cover_id: None,
|
||||
},
|
||||
&searcher,
|
||||
)
|
||||
.unwrap();
|
||||
PostAuthor::insert(
|
||||
|
@ -155,7 +154,7 @@ pub(crate) mod tests {
|
|||
},
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
searcher.add_document(&conn, &post).unwrap();
|
||||
searcher.commit();
|
||||
assert_eq!(
|
||||
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();
|
||||
post.title = newtitle.clone();
|
||||
post.update(conn, &searcher).unwrap();
|
||||
post.update(conn).unwrap();
|
||||
searcher.update_document(conn, &post).unwrap();
|
||||
searcher.commit();
|
||||
assert_eq!(
|
||||
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))
|
||||
.is_empty());
|
||||
|
||||
post.delete(conn, &searcher).unwrap();
|
||||
searcher.delete_document(&post);
|
||||
searcher.commit();
|
||||
assert!(searcher
|
||||
.search_document(conn, Query::from_str(&newtitle).unwrap(), (0, 1))
|
||||
|
@ -213,7 +213,6 @@ pub(crate) mod tests {
|
|||
source: "".to_owned(),
|
||||
cover_id: None,
|
||||
},
|
||||
&searcher,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
use crate::{
|
||||
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 itertools::Itertools;
|
||||
use std::fs;
|
||||
use std::{cmp, fs::create_dir_all, io, path::Path, sync::Mutex};
|
||||
use tantivy::{
|
||||
collector::TopDocs, directory::MmapDirectory, schema::*, Index, IndexReader, IndexWriter,
|
||||
ReloadPolicy, TantivyError, Term,
|
||||
};
|
||||
use tracing::warn;
|
||||
use whatlang::{detect as detect_lang, Lang};
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -67,6 +69,58 @@ impl Searcher {
|
|||
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> {
|
||||
let schema = Self::schema();
|
||||
|
||||
|
|
|
@ -408,7 +408,6 @@ mod tests {
|
|||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(gnu_tl.matches(r, &gnu_post, Kind::Original).unwrap());
|
||||
|
@ -428,7 +427,6 @@ mod tests {
|
|||
source: "so is Microsoft".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!gnu_tl.matches(r, &non_free_post, Kind::Original).unwrap());
|
||||
|
@ -481,7 +479,6 @@ mod tests {
|
|||
subtitle: "".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(my_tl.matches(r, &post, Kind::Original).unwrap()); // matches because of "blog in fav_blogs" (and there is no cover)
|
||||
|
@ -503,7 +500,6 @@ mod tests {
|
|||
subtitle: "".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
assert!(!my_tl.matches(r, &post, Kind::Like(&users[1])).unwrap());
|
||||
|
@ -549,7 +545,6 @@ mod tests {
|
|||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -568,7 +563,6 @@ mod tests {
|
|||
source: "so is Microsoft".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
@ -608,7 +602,6 @@ mod tests {
|
|||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
gnu_post
|
||||
|
@ -745,7 +738,6 @@ mod tests {
|
|||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
gnu_post.update_tags(conn, vec![Tag::build_activity("free".to_owned()).unwrap()]).unwrap();
|
||||
|
@ -779,7 +771,6 @@ mod tests {
|
|||
source: "you must say GNU/Linux, not Linux!!!".to_string(),
|
||||
cover_id: None,
|
||||
},
|
||||
&r.searcher,
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use crate::{
|
||||
ap_url, blocklisted_emails::BlocklistedEmail, blogs::Blog, db_conn::DbConn, follows::Follow,
|
||||
instance::*, medias::Media, notifications::Notification, post_authors::PostAuthor, posts::Post,
|
||||
safe_string::SafeString, schema::users, search::Searcher, timeline::Timeline, Connection,
|
||||
Error, PlumeRocket, Result, CONFIG, ITEMS_PER_PAGE,
|
||||
safe_string::SafeString, schema::users, timeline::Timeline, Connection, Error, PlumeRocket,
|
||||
Result, CONFIG, ITEMS_PER_PAGE,
|
||||
};
|
||||
use activitypub::{
|
||||
activity::Delete,
|
||||
|
@ -129,14 +129,14 @@ impl User {
|
|||
.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;
|
||||
|
||||
for blog in Blog::find_for_author(conn, self)?
|
||||
.iter()
|
||||
.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
|
||||
let all_their_posts_ids: Vec<i32> = post_authors::table
|
||||
|
@ -156,7 +156,7 @@ impl User {
|
|||
.unwrap_or(&0)
|
||||
> &0;
|
||||
if !has_other_authors {
|
||||
Post::get(conn, post_id)?.delete(conn, searcher)?;
|
||||
Post::get(conn, post_id)?.delete(conn)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1037,7 +1037,7 @@ impl AsObject<User, Delete, &PlumeRocket> for User {
|
|||
|
||||
fn activity(self, c: &PlumeRocket, actor: User, _id: &str) -> Result<()> {
|
||||
if self.id == actor.id {
|
||||
self.delete(&c.conn, &c.searcher).map(|_| ())
|
||||
self.delete(&c.conn).map(|_| ())
|
||||
} else {
|
||||
Err(Error::Unauthorized)
|
||||
}
|
||||
|
@ -1130,9 +1130,7 @@ impl NewUser {
|
|||
pub(crate) mod tests {
|
||||
use super::*;
|
||||
use crate::{
|
||||
config::CONFIG,
|
||||
instance::{tests as instance_tests, Instance},
|
||||
search::tests::get_searcher,
|
||||
tests::{db, rockets},
|
||||
Connection as Conn,
|
||||
};
|
||||
|
@ -1227,9 +1225,7 @@ pub(crate) mod tests {
|
|||
let inserted = fill_database(conn);
|
||||
|
||||
assert!(User::get(conn, inserted[0].id).is_ok());
|
||||
inserted[0]
|
||||
.delete(conn, &get_searcher(&CONFIG.search_tokenizers))
|
||||
.unwrap();
|
||||
inserted[0].delete(conn).unwrap();
|
||||
assert!(User::get(conn, inserted[0].id).is_err());
|
||||
Ok(())
|
||||
});
|
||||
|
@ -1319,7 +1315,7 @@ pub(crate) mod tests {
|
|||
let users = fill_database(conn);
|
||||
|
||||
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();
|
||||
|
||||
assert_eq!(user.username, users[0].username);
|
||||
|
|
|
@ -10,12 +10,17 @@ msgstr ""
|
|||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\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-Crowdin-Project: plume\n"
|
||||
"X-Crowdin-Language: cy\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
|
||||
msgid "Open the rich text editor"
|
||||
msgstr ""
|
||||
|
@ -24,8 +29,8 @@ msgstr ""
|
|||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:147
|
||||
msgid "Subtitle or summary"
|
||||
# plume-front/src/editor.rs:319
|
||||
msgid "Subtitle, or summary"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:154
|
||||
|
@ -55,4 +60,3 @@ msgstr ""
|
|||
# plume-front/src/editor.rs:259
|
||||
msgid "Publish"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -12,46 +12,46 @@ msgstr ""
|
|||
"Content-Transfer-Encoding: 8bit\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 {}?"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:282
|
||||
# plume-front/src/editor.rs:281
|
||||
msgid "Open the rich text editor"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:315
|
||||
# plume-front/src/editor.rs:314
|
||||
msgid "Title"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:319
|
||||
# plume-front/src/editor.rs:318
|
||||
msgid "Subtitle, or summary"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:326
|
||||
# plume-front/src/editor.rs:325
|
||||
msgid "Write your article here. Markdown is supported."
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:337
|
||||
# plume-front/src/editor.rs:336
|
||||
msgid "Around {} characters left"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:414
|
||||
# plume-front/src/editor.rs:413
|
||||
msgid "Tags"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:415
|
||||
# plume-front/src/editor.rs:414
|
||||
msgid "License"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:418
|
||||
# plume-front/src/editor.rs:417
|
||||
msgid "Cover"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:438
|
||||
# plume-front/src/editor.rs:437
|
||||
msgid "This is a draft"
|
||||
msgstr ""
|
||||
|
||||
# plume-front/src/editor.rs:445
|
||||
# plume-front/src/editor.rs:444
|
||||
msgid "Publish"
|
||||
msgstr ""
|
||||
|
|
|
@ -72,27 +72,27 @@ msgstr ""
|
|||
msgid "Your blog was successfully created!"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:160
|
||||
# src/routes/blogs.rs:159
|
||||
msgid "Your blog was deleted."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:168
|
||||
# src/routes/blogs.rs:167
|
||||
msgid "You are not allowed to delete this blog."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:219
|
||||
# src/routes/blogs.rs:218
|
||||
msgid "You are not allowed to edit this blog."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:275
|
||||
# src/routes/blogs.rs:274
|
||||
msgid "You can't use this media as a blog icon."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:293
|
||||
# src/routes/blogs.rs:292
|
||||
msgid "You can't use this media as a blog banner."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/blogs.rs:327
|
||||
# src/routes/blogs.rs:326
|
||||
msgid "Your blog information have been updated."
|
||||
msgstr ""
|
||||
|
||||
|
@ -104,39 +104,39 @@ msgstr ""
|
|||
msgid "Your comment has been deleted."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:119
|
||||
# src/routes/instance.rs:118
|
||||
msgid "Instance settings have been saved."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:151
|
||||
# src/routes/instance.rs:150
|
||||
msgid "{} has been unblocked."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:153
|
||||
# src/routes/instance.rs:152
|
||||
msgid "{} has been blocked."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:202
|
||||
# src/routes/instance.rs:201
|
||||
msgid "Blocks deleted"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:217
|
||||
# src/routes/instance.rs:216
|
||||
msgid "Email already blocked"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:222
|
||||
# src/routes/instance.rs:221
|
||||
msgid "Email Blocked"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:313
|
||||
# src/routes/instance.rs:312
|
||||
msgid "You can't change your own rights."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:324
|
||||
# src/routes/instance.rs:323
|
||||
msgid "You are not allowed to take this action."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/instance.rs:361
|
||||
# src/routes/instance.rs:359
|
||||
msgid "Done."
|
||||
msgstr ""
|
||||
|
||||
|
@ -188,31 +188,31 @@ msgstr ""
|
|||
msgid "You are not allowed to publish on this blog."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:364
|
||||
# src/routes/posts.rs:363
|
||||
msgid "Your article has been updated."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:555
|
||||
# src/routes/posts.rs:553
|
||||
msgid "Your article has been saved."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:562
|
||||
# src/routes/posts.rs:560
|
||||
msgid "New article"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:599
|
||||
# src/routes/posts.rs:597
|
||||
msgid "You are not allowed to delete this article."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:624
|
||||
# src/routes/posts.rs:622
|
||||
msgid "Your article has been deleted."
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:629
|
||||
# src/routes/posts.rs:627
|
||||
msgid "It looks like the article you tried to delete doesn't exist. Maybe it is already gone?"
|
||||
msgstr ""
|
||||
|
||||
# src/routes/posts.rs:669
|
||||
# src/routes/posts.rs:667
|
||||
msgid "Couldn't obtain enough information about your account. Please make sure your username is correct."
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -105,7 +105,6 @@ pub fn create(
|
|||
rockets: PlumeRocket,
|
||||
) -> Api<PostData> {
|
||||
let conn = &*rockets.conn;
|
||||
let search = &rockets.searcher;
|
||||
let worker = &rockets.worker;
|
||||
|
||||
let author = User::get(conn, auth.0.user_id)?;
|
||||
|
@ -155,7 +154,6 @@ pub fn create(
|
|||
source: payload.source.clone(),
|
||||
cover_id: payload.cover_id,
|
||||
},
|
||||
search,
|
||||
)?;
|
||||
|
||||
PostAuthor::insert(
|
||||
|
@ -232,7 +230,7 @@ pub fn delete(auth: Authorization<Write, Post>, rockets: PlumeRocket, id: i32) -
|
|||
let author = User::get(&*rockets.conn, auth.0.user_id)?;
|
||||
if let Ok(post) = Post::get(&*rockets.conn, id) {
|
||||
if post.is_author(&*rockets.conn, author.id).unwrap_or(false) {
|
||||
post.delete(&*rockets.conn, &rockets.searcher)?;
|
||||
post.delete(&*rockets.conn)?;
|
||||
}
|
||||
}
|
||||
Ok(Json(()))
|
||||
|
|
65
src/main.rs
65
src/main.rs
|
@ -10,20 +10,17 @@ extern crate serde_json;
|
|||
#[macro_use]
|
||||
extern crate validator_derive;
|
||||
|
||||
use chrono::Utc;
|
||||
use clap::App;
|
||||
use diesel::r2d2::ConnectionManager;
|
||||
use plume_models::{
|
||||
db_conn::{DbPool, PragmaForeignKey},
|
||||
instance::Instance,
|
||||
migrations::IMPORTED_MIGRATIONS,
|
||||
search::{Searcher as UnmanagedSearcher, SearcherError},
|
||||
Connection, Error, CONFIG,
|
||||
search::{actor::SearchActor, Searcher as UnmanagedSearcher},
|
||||
Connection, CONFIG,
|
||||
};
|
||||
use rocket_csrf::CsrfFairingBuilder;
|
||||
use scheduled_thread_pool::ScheduledThreadPool;
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
use std::process::exit;
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
|
@ -103,59 +100,11 @@ Then try to restart Plume.
|
|||
}
|
||||
let workpool = ScheduledThreadPool::with_name("worker {}", num_cpus::get());
|
||||
// we want a fast exit here, so
|
||||
let mut open_searcher =
|
||||
UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||
if let Err(Error::Search(SearcherError::InvalidIndexDataError)) = open_searcher {
|
||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_tokenizers).is_err() {
|
||||
let current_path = Path::new(&CONFIG.search_index);
|
||||
let backup_path = format!("{}.{}", ¤t_path.display(), Utc::now().timestamp());
|
||||
let backup_path = Path::new(&backup_path);
|
||||
fs::rename(current_path, backup_path)
|
||||
.expect("main: error on backing up search index directory for recreating");
|
||||
if UnmanagedSearcher::create(&CONFIG.search_index, &CONFIG.search_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 = UnmanagedSearcher::open(&CONFIG.search_index, &CONFIG.search_tokenizers);
|
||||
}
|
||||
#[allow(clippy::match_wild_err_arm)]
|
||||
let searcher = match open_searcher {
|
||||
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(),
|
||||
},
|
||||
Err(_) => panic!("Unexpected error while opening search index"),
|
||||
Ok(s) => Arc::new(s),
|
||||
};
|
||||
|
||||
let searcher = Arc::new(UnmanagedSearcher::open_or_recreate(
|
||||
&CONFIG.search_index,
|
||||
&CONFIG.search_tokenizers,
|
||||
));
|
||||
SearchActor::init(searcher.clone(), dbpool.clone());
|
||||
let commiter = searcher.clone();
|
||||
workpool.execute_with_fixed_delay(
|
||||
Duration::from_secs(5),
|
||||
|
|
|
@ -153,8 +153,7 @@ pub fn delete(name: String, rockets: PlumeRocket) -> RespondOrRedirect {
|
|||
.and_then(|u| u.is_author_in(&*conn, &blog).ok())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
blog.delete(&conn, &rockets.searcher)
|
||||
.expect("blog::expect: deletion error");
|
||||
blog.delete(&conn).expect("blog::expect: deletion error");
|
||||
Flash::success(
|
||||
Redirect::to(uri!(super::instance::index)),
|
||||
i18n!(rockets.intl.catalog, "Your blog was deleted."),
|
||||
|
|
|
@ -21,7 +21,6 @@ use plume_models::{
|
|||
instance::*,
|
||||
posts::Post,
|
||||
safe_string::SafeString,
|
||||
search::Searcher,
|
||||
timeline::Timeline,
|
||||
users::{Role, User},
|
||||
Connection, Error, PlumeRocket, CONFIG,
|
||||
|
@ -331,7 +330,6 @@ pub fn edit_users(
|
|||
}
|
||||
|
||||
let conn = &rockets.conn;
|
||||
let searcher = &*rockets.searcher;
|
||||
let worker = &*rockets.worker;
|
||||
match form.action {
|
||||
UserActions::Admin => {
|
||||
|
@ -351,7 +349,7 @@ pub fn edit_users(
|
|||
}
|
||||
UserActions::Ban => {
|
||||
for u in form.ids.clone() {
|
||||
ban(u, conn, searcher, worker)?;
|
||||
ban(u, conn, worker)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -362,14 +360,9 @@ pub fn edit_users(
|
|||
))
|
||||
}
|
||||
|
||||
fn ban(
|
||||
id: i32,
|
||||
conn: &Connection,
|
||||
searcher: &Searcher,
|
||||
worker: &ScheduledThreadPool,
|
||||
) -> Result<(), ErrorPage> {
|
||||
fn ban(id: i32, conn: &Connection, worker: &ScheduledThreadPool) -> Result<(), ErrorPage> {
|
||||
let u = User::get(&*conn, id)?;
|
||||
u.delete(&*conn, searcher)?;
|
||||
u.delete(&*conn)?;
|
||||
if Instance::get_local()
|
||||
.map(|i| u.instance_id == i.id)
|
||||
.unwrap_or(false)
|
||||
|
|
|
@ -298,8 +298,7 @@ pub fn update(
|
|||
post.source = form.content.clone();
|
||||
post.license = form.license.clone();
|
||||
post.cover_id = form.cover;
|
||||
post.update(&*conn, &rockets.searcher)
|
||||
.expect("post::update: update error");
|
||||
post.update(&*conn).expect("post::update: update error");
|
||||
|
||||
if post.published {
|
||||
post.update_mentions(
|
||||
|
@ -481,7 +480,6 @@ pub fn create(
|
|||
source: form.content.clone(),
|
||||
cover_id: form.cover,
|
||||
},
|
||||
&rockets.searcher,
|
||||
)
|
||||
.expect("post::create: post save error");
|
||||
|
||||
|
|
|
@ -421,7 +421,7 @@ pub fn delete(
|
|||
) -> Result<Flash<Redirect>, ErrorPage> {
|
||||
let account = User::find_by_fqn(&rockets, &name)?;
|
||||
if user.id == account.id {
|
||||
account.delete(&*rockets.conn, &rockets.searcher)?;
|
||||
account.delete(&*rockets.conn)?;
|
||||
|
||||
let target = User::one_by_instance(&*rockets.conn)?;
|
||||
let delete_act = account.delete_activity(&*rockets.conn)?;
|
||||
|
|
Loading…
Reference in a new issue