mirror of https://github.com/LemmyNet/lemmy.git
Compare commits
41 Commits
dcc93f3d60
...
076262317b
Author | SHA1 | Date |
---|---|---|
Dull Bananas | 076262317b | |
Dull Bananas | 689d2efb48 | |
Dull Bananas | 06de0c5205 | |
Dessalines | d09854a722 | |
Dessalines | c8d155102a | |
dullbananas | 36e6f7ec78 | |
Dessalines | 6d8d23130d | |
Dessalines | 9cf6da1b9e | |
Dessalines | 59f274e531 | |
Dessalines | fa143f72eb | |
Dessalines | 63a824a2ed | |
renovate[bot] | b9dc7612a8 | |
renovate[bot] | 393f65db8d | |
Dessalines | bfefdfd15d | |
renovate[bot] | 41d1b054fe | |
dullbananas | 42a6d8ab0f | |
renovate[bot] | f080400826 | |
renovate[bot] | c55636b0d0 | |
renovate[bot] | 32b7ee76e3 | |
Dessalines | 5cc798a146 | |
renovate[bot] | 4974dbb1dd | |
renovate[bot] | d7a453dd68 | |
renovate[bot] | 393b221be0 | |
renovate[bot] | 966d949f73 | |
renovate[bot] | b245bf48c0 | |
renovate[bot] | b569c7df17 | |
renovate[bot] | 0f6bd94407 | |
renovate[bot] | 5cf1593c9f | |
renovate[bot] | 04400ceac3 | |
renovate[bot] | dede17bf24 | |
renovate[bot] | b0e2a14d04 | |
renovate[bot] | 027017b0a8 | |
renovate[bot] | b27b38b9a9 | |
renovate[bot] | a7771ff385 | |
renovate[bot] | 27e7aa1e04 | |
dullbananas | 6497ec519e | |
Dessalines | 65620913fc | |
Nutomic | a3c8761bed | |
dullbananas | 99160228ae | |
Dessalines | fc6f46c1ac | |
dullbananas | 046375171e |
|
@ -192,7 +192,6 @@ dependencies = [
|
||||||
"bytestring",
|
"bytestring",
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"regex",
|
|
||||||
"regex-lite",
|
"regex-lite",
|
||||||
"serde",
|
"serde",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -267,9 +266,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-web"
|
name = "actix-web"
|
||||||
version = "4.6.0"
|
version = "4.7.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b1cf67dadb19d7c95e5a299e2dda24193b89d5d4f33a3b9800888ede9e19aa32"
|
checksum = "5d6316df3fa569627c98b12557a8b6ff0674e5be4bb9b5e4ae2550ddb4964ed6"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-codec",
|
"actix-codec",
|
||||||
"actix-http",
|
"actix-http",
|
||||||
|
@ -308,9 +307,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-web-codegen"
|
name = "actix-web-codegen"
|
||||||
version = "4.2.2"
|
version = "4.3.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eb1f50ebbb30eca122b188319a4398b3f7bb4a8cdf50ecfb73bfc6a3c3ce54f5"
|
checksum = "f591380e2e68490b5dfaf1dd1aa0ebe78d84ba7067078512b4ea6e4492d622b8"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-router",
|
"actix-router",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
|
@ -320,13 +319,13 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "actix-web-httpauth"
|
name = "actix-web-httpauth"
|
||||||
version = "0.8.1"
|
version = "0.8.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1d613edf08a42ccc6864c941d30fe14e1b676a77d16f1dbadc1174d065a0a775"
|
checksum = "456348ed9dcd72a13a1f4a660449fafdecee9ac8205552e286809eb5b0b29bd3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-utils",
|
"actix-utils",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"base64 0.21.7",
|
"base64 0.22.1",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"log",
|
"log",
|
||||||
|
@ -978,9 +977,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.5.6"
|
version = "4.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9689a29b593160de5bc4aacab7b5d54fb52231de70122626c178e6a368994c7"
|
checksum = "5db83dced34638ad474f39f250d7fea9598bdd239eaced1bdf45d597da0f433f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap_builder",
|
"clap_builder",
|
||||||
"clap_derive",
|
"clap_derive",
|
||||||
|
@ -988,9 +987,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap_builder"
|
name = "clap_builder"
|
||||||
version = "4.5.6"
|
version = "4.5.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2e5387378c84f6faa26890ebf9f0a92989f8873d4d380467bcd0d8d8620424df"
|
checksum = "f7e204572485eb3fbf28f871612191521df159bc3e15a9f5064c66dba3a8c05f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anstream",
|
"anstream",
|
||||||
"anstyle",
|
"anstyle",
|
||||||
|
@ -1121,13 +1120,26 @@ dependencies = [
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console-api"
|
||||||
|
version = "0.7.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a257c22cd7e487dd4a13d413beabc512c5052f0bc048db0da6a84c3d8a6142fd"
|
||||||
|
dependencies = [
|
||||||
|
"futures-core",
|
||||||
|
"prost 0.12.6",
|
||||||
|
"prost-types",
|
||||||
|
"tonic 0.11.0",
|
||||||
|
"tracing-core",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "console-subscriber"
|
name = "console-subscriber"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e"
|
checksum = "7481d4c57092cd1c19dd541b92bdce883de840df30aa5d03fd48a3935c01842e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console-api",
|
"console-api 0.6.0",
|
||||||
"crossbeam-channel",
|
"crossbeam-channel",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
"futures-task",
|
"futures-task",
|
||||||
|
@ -1145,6 +1157,31 @@ dependencies = [
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "console-subscriber"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "31c4cc54bae66f7d9188996404abdf7fdfa23034ef8e43478c8810828abad758"
|
||||||
|
dependencies = [
|
||||||
|
"console-api 0.7.0",
|
||||||
|
"crossbeam-channel",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"futures-task",
|
||||||
|
"hdrhistogram",
|
||||||
|
"humantime",
|
||||||
|
"prost 0.12.6",
|
||||||
|
"prost-types",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"thread_local",
|
||||||
|
"tokio",
|
||||||
|
"tokio-stream",
|
||||||
|
"tonic 0.11.0",
|
||||||
|
"tracing",
|
||||||
|
"tracing-core",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "const-oid"
|
name = "const-oid"
|
||||||
version = "0.9.6"
|
version = "0.9.6"
|
||||||
|
@ -1620,6 +1657,17 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "displaydoc"
|
||||||
|
version = "0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "doku"
|
name = "doku"
|
||||||
version = "0.21.1"
|
version = "0.21.1"
|
||||||
|
@ -2493,6 +2541,124 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_collections"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locid"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"litemap",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locid_transform"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_locid_transform_data",
|
||||||
|
"icu_provider",
|
||||||
|
"tinystr",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_locid_transform_data"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_normalizer_data",
|
||||||
|
"icu_properties",
|
||||||
|
"icu_provider",
|
||||||
|
"smallvec",
|
||||||
|
"utf16_iter",
|
||||||
|
"utf8_iter",
|
||||||
|
"write16",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_normalizer_data"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1f8ac670d7422d7f76b32e17a5db556510825b29ec9154f235977c9caba61036"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_collections",
|
||||||
|
"icu_locid_transform",
|
||||||
|
"icu_properties_data",
|
||||||
|
"icu_provider",
|
||||||
|
"tinystr",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_properties_data"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"icu_locid",
|
||||||
|
"icu_provider_macros",
|
||||||
|
"stable_deref_trait",
|
||||||
|
"tinystr",
|
||||||
|
"writeable",
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "icu_provider_macros"
|
||||||
|
version = "1.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ident_case"
|
name = "ident_case"
|
||||||
version = "1.0.1"
|
version = "1.0.1"
|
||||||
|
@ -2519,6 +2685,18 @@ dependencies = [
|
||||||
"unicode-normalization",
|
"unicode-normalization",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "idna"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4716a3a0933a1d01c2f72450e89596eb51dd34ef3c211ccd875acdf1f8fe47ed"
|
||||||
|
dependencies = [
|
||||||
|
"icu_normalizer",
|
||||||
|
"icu_properties",
|
||||||
|
"smallvec",
|
||||||
|
"utf8_iter",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "image"
|
name = "image"
|
||||||
version = "0.24.9"
|
version = "0.24.9"
|
||||||
|
@ -2702,7 +2880,7 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_api"
|
name = "lemmy_api"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -2731,7 +2909,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_api_common"
|
name = "lemmy_api_common"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -2769,7 +2947,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_api_crud"
|
name = "lemmy_api_crud"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"accept-language",
|
"accept-language",
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
|
@ -2792,7 +2970,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_apub"
|
name = "lemmy_apub"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -2830,7 +3008,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db_perf"
|
name = "lemmy_db_perf"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
@ -2845,7 +3023,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db_schema"
|
name = "lemmy_db_schema"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -2868,7 +3046,7 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pretty_assertions",
|
"pretty_assertions",
|
||||||
"regex",
|
"regex",
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_with",
|
"serde_with",
|
||||||
|
@ -2888,7 +3066,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db_views"
|
name = "lemmy_db_views"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"chrono",
|
"chrono",
|
||||||
|
@ -2910,7 +3088,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db_views_actor"
|
name = "lemmy_db_views_actor"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"diesel",
|
"diesel",
|
||||||
|
@ -2931,7 +3109,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_db_views_moderator"
|
name = "lemmy_db_views_moderator"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
|
@ -2943,7 +3121,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_federate"
|
name = "lemmy_federate"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -2968,7 +3146,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_routes"
|
name = "lemmy_routes"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -2993,7 +3171,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_server"
|
name = "lemmy_server"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"activitypub_federation",
|
"activitypub_federation",
|
||||||
"actix-cors",
|
"actix-cors",
|
||||||
|
@ -3002,7 +3180,7 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"clokwerk",
|
"clokwerk",
|
||||||
"console-subscriber",
|
"console-subscriber 0.3.0",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
@ -3036,7 +3214,7 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemmy_utils"
|
name = "lemmy_utils"
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"anyhow",
|
"anyhow",
|
||||||
|
@ -3144,6 +3322,12 @@ version = "0.4.14"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "litemap"
|
||||||
|
version = "0.7.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "643cb0b8d4fcc284004d5fd0d67ccf61dfffadb7f75e1e71bc420f4688a3a704"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "local-channel"
|
name = "local-channel"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -3321,9 +3505,9 @@ checksum = "6c8640c5d730cb13ebd907d8d04b52f55ac9a2eec55b440c8892f40d56c76c1d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metrics"
|
name = "metrics"
|
||||||
version = "0.22.3"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2be3cbd384d4e955b231c895ce10685e3d8260c5ccffae898c96c723b0772835"
|
checksum = "884adb57038347dfbaf2d5065887b6cf4312330dc8e94bc30a1a839bd79d3261"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"portable-atomic",
|
"portable-atomic",
|
||||||
|
@ -3331,9 +3515,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metrics-exporter-prometheus"
|
name = "metrics-exporter-prometheus"
|
||||||
version = "0.14.0"
|
version = "0.15.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d58e362dc7206e9456ddbcdbd53c71ba441020e62104703075a69151e38d85f"
|
checksum = "26eb45aff37b45cff885538e1dcbd6c2b462c04fe84ce0155ea469f325672c98"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"http-body-util",
|
"http-body-util",
|
||||||
|
@ -3351,9 +3535,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "metrics-util"
|
name = "metrics-util"
|
||||||
version = "0.16.3"
|
version = "0.17.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "8b07a5eb561b8cbc16be2d216faf7757f9baf3bfb94dbb0fae3df8387a5bb47f"
|
checksum = "4259040465c955f9f2f1a4a8a16dc46726169bca0f88e8fb2dbeced487c3e828"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crossbeam-epoch",
|
"crossbeam-epoch",
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
|
@ -3652,9 +3836,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry"
|
name = "opentelemetry"
|
||||||
version = "0.22.0"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "900d57987be3f2aeb70d385fff9b27fb74c5723cc9a52d904d4f9c807a0667bf"
|
checksum = "1b69a91d4893e713e06f724597ad630f1fa76057a5e1026c0ca67054a9032a76"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-sink",
|
"futures-sink",
|
||||||
|
@ -3662,7 +3846,6 @@ dependencies = [
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"urlencoding",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3685,17 +3868,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry-otlp"
|
name = "opentelemetry-otlp"
|
||||||
version = "0.15.0"
|
version = "0.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1a016b8d9495c639af2145ac22387dcb88e44118e45320d9238fbf4e7889abcb"
|
checksum = "a94c69209c05319cdf7460c6d4c055ed102be242a0a6245835d7bc42c6ec7f54"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"http 0.2.12",
|
"http 0.2.12",
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"opentelemetry-proto 0.5.0",
|
"opentelemetry-proto 0.6.0",
|
||||||
"opentelemetry-semantic-conventions",
|
"opentelemetry_sdk 0.23.0",
|
||||||
"opentelemetry_sdk 0.22.1",
|
|
||||||
"prost 0.12.6",
|
"prost 0.12.6",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
@ -3717,22 +3899,16 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry-proto"
|
name = "opentelemetry-proto"
|
||||||
version = "0.5.0"
|
version = "0.6.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "3a8fddc9b68f5b80dae9d6f510b88e02396f006ad48cac349411fbecc80caae4"
|
checksum = "984806e6cf27f2b49282e2a05e288f30594f3dbc74eb7a6e99422bc48ed78162"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"opentelemetry_sdk 0.22.1",
|
"opentelemetry_sdk 0.23.0",
|
||||||
"prost 0.12.6",
|
"prost 0.12.6",
|
||||||
"tonic 0.11.0",
|
"tonic 0.11.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "opentelemetry-semantic-conventions"
|
|
||||||
version = "0.14.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "f9ab5bd6c42fb9349dcf28af2ba9a0667f697f9bdcca045d39f2cec5543e2910"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry_api"
|
name = "opentelemetry_api"
|
||||||
version = "0.19.0"
|
version = "0.19.0"
|
||||||
|
@ -3773,18 +3949,18 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "opentelemetry_sdk"
|
name = "opentelemetry_sdk"
|
||||||
version = "0.22.1"
|
version = "0.23.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9e90c7113be649e31e9a0f8b5ee24ed7a16923b322c3c5ab6367469c049d6b7e"
|
checksum = "ae312d58eaa90a82d2e627fd86e075cf5230b3f11794e2ed74199ebbe572d4fd"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"crossbeam-channel",
|
|
||||||
"futures-channel",
|
"futures-channel",
|
||||||
"futures-executor",
|
"futures-executor",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"glob",
|
"glob",
|
||||||
|
"lazy_static",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"ordered-float",
|
"ordered-float",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"rand",
|
"rand",
|
||||||
|
@ -3983,9 +4159,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pict-rs"
|
name = "pict-rs"
|
||||||
version = "0.5.15"
|
version = "0.5.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f60cdba5d277139be805efb823d2c2a9801f508dd9e5f724225a75a4834b60b4"
|
checksum = "5bbee61836cce10f7cf733196b7c0701e7ea6d0b617da68a3e6e4311b6262c2b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-form-data",
|
"actix-form-data",
|
||||||
"actix-web",
|
"actix-web",
|
||||||
|
@ -3997,7 +4173,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"color-eyre",
|
"color-eyre",
|
||||||
"config",
|
"config",
|
||||||
"console-subscriber",
|
"console-subscriber 0.2.0",
|
||||||
"dashmap",
|
"dashmap",
|
||||||
"diesel",
|
"diesel",
|
||||||
"diesel-async",
|
"diesel-async",
|
||||||
|
@ -4008,15 +4184,15 @@ dependencies = [
|
||||||
"metrics",
|
"metrics",
|
||||||
"metrics-exporter-prometheus",
|
"metrics-exporter-prometheus",
|
||||||
"mime",
|
"mime",
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"opentelemetry-otlp 0.15.0",
|
"opentelemetry-otlp 0.16.0",
|
||||||
"opentelemetry_sdk 0.22.1",
|
"opentelemetry_sdk 0.23.0",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
"refinery",
|
"refinery",
|
||||||
"reqwest 0.12.4",
|
"reqwest 0.12.4",
|
||||||
"reqwest-middleware 0.3.1",
|
"reqwest-middleware 0.3.1",
|
||||||
"reqwest-tracing 0.5.0",
|
"reqwest-tracing 0.5.0",
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
"rustls-channel-resolver",
|
"rustls-channel-resolver",
|
||||||
"rustls-pemfile 2.1.2",
|
"rustls-pemfile 2.1.2",
|
||||||
"rusty-s3",
|
"rusty-s3",
|
||||||
|
@ -4039,7 +4215,7 @@ dependencies = [
|
||||||
"tracing-actix-web",
|
"tracing-actix-web",
|
||||||
"tracing-error",
|
"tracing-error",
|
||||||
"tracing-log 0.2.0",
|
"tracing-log 0.2.0",
|
||||||
"tracing-opentelemetry 0.23.0",
|
"tracing-opentelemetry 0.24.0",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
@ -4505,9 +4681,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "regex"
|
name = "regex"
|
||||||
version = "1.10.4"
|
version = "1.10.5"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c117dbdfde9c8308975b6a18d71f3f385c89461f7b3fb054288ecf2a2058ba4c"
|
checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aho-corasick",
|
"aho-corasick",
|
||||||
"memchr",
|
"memchr",
|
||||||
|
@ -4828,9 +5004,9 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustls"
|
name = "rustls"
|
||||||
version = "0.23.9"
|
version = "0.23.10"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a218f0f6d05669de4eabfb24f31ce802035c952429d037507b4a4a39f0e60c5b"
|
checksum = "05cff451f60db80f490f3c182b77c35260baace73209e9cdbbe526bfe3a4d402"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"log",
|
"log",
|
||||||
|
@ -4849,7 +5025,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "fede2a247359da6b4998f7723ec6468c2d6a577a5d8c17e54f21806426ad2290"
|
checksum = "fede2a247359da6b4998f7723ec6468c2d6a577a5d8c17e54f21806426ad2290"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"nanorand",
|
"nanorand",
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -5304,6 +5480,12 @@ dependencies = [
|
||||||
"der",
|
"der",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "stable_deref_trait"
|
||||||
|
version = "1.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "stacker"
|
name = "stacker"
|
||||||
version = "0.1.15"
|
version = "0.1.15"
|
||||||
|
@ -5441,6 +5623,17 @@ version = "0.1.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "synstructure"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "syntect"
|
name = "syntect"
|
||||||
version = "5.2.0"
|
version = "5.2.0"
|
||||||
|
@ -5598,6 +5791,16 @@ version = "2.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a"
|
checksum = "9ab95735ea2c8fd51154d01e39cf13912a78071c2d89abc49a7ef102a7dd725a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tinystr"
|
||||||
|
version = "0.7.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
|
||||||
|
dependencies = [
|
||||||
|
"displaydoc",
|
||||||
|
"zerovec",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tinyvec"
|
name = "tinyvec"
|
||||||
version = "1.6.0"
|
version = "1.6.0"
|
||||||
|
@ -5718,7 +5921,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c8e98c31c29b2666fb28720739e11476166be4ead1610a37dcd7414bb124413a"
|
checksum = "c8e98c31c29b2666fb28720739e11476166be4ead1610a37dcd7414bb124413a"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"aws-lc-rs",
|
"aws-lc-rs",
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-postgres",
|
"tokio-postgres",
|
||||||
"tokio-rustls 0.26.0",
|
"tokio-rustls 0.26.0",
|
||||||
|
@ -5732,7 +5935,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "04fb792ccd6bbcd4bba408eb8a292f70fc4a3589e5d793626f45190e6454b6ab"
|
checksum = "04fb792ccd6bbcd4bba408eb8a292f70fc4a3589e5d793626f45190e6454b6ab"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ring",
|
"ring",
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-postgres",
|
"tokio-postgres",
|
||||||
"tokio-rustls 0.26.0",
|
"tokio-rustls 0.26.0",
|
||||||
|
@ -5756,7 +5959,7 @@ version = "0.26.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
checksum = "0c7bc40d0e5a97695bb96e27995cd3a08538541b0a846f65bba7a359f36700d4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"rustls 0.23.9",
|
"rustls 0.23.10",
|
||||||
"rustls-pki-types",
|
"rustls-pki-types",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
@ -5998,10 +6201,10 @@ checksum = "4ee9e39a66d9b615644893ffc1704d2a89b5b315b7fd0228ad3182ca9a306b19"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
"mutually_exclusive_features",
|
"mutually_exclusive_features",
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"pin-project",
|
"pin-project",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-opentelemetry 0.23.0",
|
"tracing-opentelemetry 0.24.0",
|
||||||
"uuid",
|
"uuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -6097,14 +6300,14 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-opentelemetry"
|
name = "tracing-opentelemetry"
|
||||||
version = "0.23.0"
|
version = "0.24.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a9be14ba1bbe4ab79e9229f7f89fab8d120b865859f10527f31c033e599d2284"
|
checksum = "f68803492bf28ab40aeccaecc7021096bd256baf7ca77c3d425d89b35a7be4e4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"opentelemetry 0.22.0",
|
"opentelemetry 0.23.0",
|
||||||
"opentelemetry_sdk 0.22.1",
|
"opentelemetry_sdk 0.23.0",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
|
@ -6280,12 +6483,12 @@ checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "url"
|
name = "url"
|
||||||
version = "2.5.0"
|
version = "2.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "31e6302e3bb753d46e83516cae55ae196fc0c309407cf11ab35cc51a4c2a4633"
|
checksum = "f7c25da092f0a868cdf09e8674cd3b7ef3a7d92a24253e663a2fb85e2496de56"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"form_urlencoded",
|
"form_urlencoded",
|
||||||
"idna 0.5.0",
|
"idna 1.0.0",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
@ -6302,12 +6505,24 @@ version = "0.7.6"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf16_iter"
|
||||||
|
version = "1.0.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8-width"
|
name = "utf8-width"
|
||||||
version = "0.1.7"
|
version = "0.1.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
|
checksum = "86bd8d4e895da8537e5315b8254664e6b769c4ff3db18321b297a1e7004392e3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "utf8_iter"
|
||||||
|
version = "1.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf8parse"
|
name = "utf8parse"
|
||||||
version = "0.2.1"
|
version = "0.2.1"
|
||||||
|
@ -6760,6 +6975,18 @@ dependencies = [
|
||||||
"windows-sys 0.48.0",
|
"windows-sys 0.48.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "write16"
|
||||||
|
version = "1.0.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "writeable"
|
||||||
|
version = "0.5.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "x509-cert"
|
name = "x509-cert"
|
||||||
version = "0.2.5"
|
version = "0.2.5"
|
||||||
|
@ -6834,6 +7061,30 @@ version = "0.5.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c5b1314b079b0930c31e3af543d8ee1757b1951ae1e1565ec704403a7240ca5"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"stable_deref_trait",
|
||||||
|
"yoke-derive",
|
||||||
|
"zerofrom",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yoke-derive"
|
||||||
|
version = "0.7.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "28cc31741b18cb6f1d5ff12f5b7523e3d6eb0852bbbad19d73905511d9849b95"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zerocopy"
|
name = "zerocopy"
|
||||||
version = "0.7.34"
|
version = "0.7.34"
|
||||||
|
@ -6854,6 +7105,27 @@ dependencies = [
|
||||||
"syn 2.0.66",
|
"syn 2.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "91ec111ce797d0e0784a1116d0ddcdbea84322cd79e5d5ad173daeba4f93ab55"
|
||||||
|
dependencies = [
|
||||||
|
"zerofrom-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerofrom-derive"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0ea7b4a3637ea8669cedf0f1fd5c286a17f3de97b8dd5a70a6c167a1730e63a5"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
"synstructure",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zeroize"
|
name = "zeroize"
|
||||||
version = "1.8.1"
|
version = "1.8.1"
|
||||||
|
@ -6874,6 +7146,28 @@ dependencies = [
|
||||||
"syn 2.0.66",
|
"syn 2.0.66",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bb2cc8827d6c0994478a15c53f374f46fbd41bea663d809b14744bc42e6b109c"
|
||||||
|
dependencies = [
|
||||||
|
"yoke",
|
||||||
|
"zerofrom",
|
||||||
|
"zerovec-derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "zerovec-derive"
|
||||||
|
version = "0.10.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "97cf56601ee5052b4417d90c8755c6683473c926039908196cf35d99f893ebe7"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.66",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zstd"
|
name = "zstd"
|
||||||
version = "0.13.1"
|
version = "0.13.1"
|
||||||
|
|
26
Cargo.toml
26
Cargo.toml
|
@ -1,5 +1,5 @@
|
||||||
[workspace.package]
|
[workspace.package]
|
||||||
version = "0.19.4"
|
version = "0.19.5"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
description = "A link aggregator for the fediverse"
|
description = "A link aggregator for the fediverse"
|
||||||
license = "AGPL-3.0"
|
license = "AGPL-3.0"
|
||||||
|
@ -88,17 +88,17 @@ unused_self = "deny"
|
||||||
unwrap_used = "deny"
|
unwrap_used = "deny"
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
lemmy_api = { version = "=0.19.4", path = "./crates/api" }
|
lemmy_api = { version = "=0.19.5", path = "./crates/api" }
|
||||||
lemmy_api_crud = { version = "=0.19.4", path = "./crates/api_crud" }
|
lemmy_api_crud = { version = "=0.19.5", path = "./crates/api_crud" }
|
||||||
lemmy_apub = { version = "=0.19.4", path = "./crates/apub" }
|
lemmy_apub = { version = "=0.19.5", path = "./crates/apub" }
|
||||||
lemmy_utils = { version = "=0.19.4", path = "./crates/utils", default-features = false }
|
lemmy_utils = { version = "=0.19.5", path = "./crates/utils", default-features = false }
|
||||||
lemmy_db_schema = { version = "=0.19.4", path = "./crates/db_schema" }
|
lemmy_db_schema = { version = "=0.19.5", path = "./crates/db_schema" }
|
||||||
lemmy_api_common = { version = "=0.19.4", path = "./crates/api_common" }
|
lemmy_api_common = { version = "=0.19.5", path = "./crates/api_common" }
|
||||||
lemmy_routes = { version = "=0.19.4", path = "./crates/routes" }
|
lemmy_routes = { version = "=0.19.5", path = "./crates/routes" }
|
||||||
lemmy_db_views = { version = "=0.19.4", path = "./crates/db_views" }
|
lemmy_db_views = { version = "=0.19.5", path = "./crates/db_views" }
|
||||||
lemmy_db_views_actor = { version = "=0.19.4", path = "./crates/db_views_actor" }
|
lemmy_db_views_actor = { version = "=0.19.5", path = "./crates/db_views_actor" }
|
||||||
lemmy_db_views_moderator = { version = "=0.19.4", path = "./crates/db_views_moderator" }
|
lemmy_db_views_moderator = { version = "=0.19.5", path = "./crates/db_views_moderator" }
|
||||||
lemmy_federate = { version = "=0.19.4", path = "./crates/federate" }
|
lemmy_federate = { version = "=0.19.5", path = "./crates/federate" }
|
||||||
activitypub_federation = { version = "0.5.6", default-features = false, features = [
|
activitypub_federation = { version = "0.5.6", default-features = false, features = [
|
||||||
"actix-web",
|
"actix-web",
|
||||||
] }
|
] }
|
||||||
|
@ -197,7 +197,7 @@ clokwerk = { workspace = true }
|
||||||
serde_json = { workspace = true }
|
serde_json = { workspace = true }
|
||||||
tracing-opentelemetry = { workspace = true, optional = true }
|
tracing-opentelemetry = { workspace = true, optional = true }
|
||||||
opentelemetry = { workspace = true, optional = true }
|
opentelemetry = { workspace = true, optional = true }
|
||||||
console-subscriber = { version = "0.2.0", optional = true }
|
console-subscriber = { version = "0.3.0", optional = true }
|
||||||
opentelemetry-otlp = { version = "0.12.0", optional = true }
|
opentelemetry-otlp = { version = "0.12.0", optional = true }
|
||||||
pict-rs = { version = "0.5.15", optional = true }
|
pict-rs = { version = "0.5.15", optional = true }
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
|
|
@ -1,42 +0,0 @@
|
||||||
{
|
|
||||||
"root": true,
|
|
||||||
"env": {
|
|
||||||
"browser": true
|
|
||||||
},
|
|
||||||
"plugins": ["@typescript-eslint"],
|
|
||||||
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended"],
|
|
||||||
"parser": "@typescript-eslint/parser",
|
|
||||||
"parserOptions": {
|
|
||||||
"project": "./tsconfig.json",
|
|
||||||
"warnOnUnsupportedTypeScriptVersion": false
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
"@typescript-eslint/ban-ts-comment": 0,
|
|
||||||
"@typescript-eslint/no-explicit-any": 0,
|
|
||||||
"@typescript-eslint/explicit-module-boundary-types": 0,
|
|
||||||
"@typescript-eslint/no-var-requires": 0,
|
|
||||||
"arrow-body-style": 0,
|
|
||||||
"curly": 0,
|
|
||||||
"eol-last": 0,
|
|
||||||
"eqeqeq": 0,
|
|
||||||
"func-style": 0,
|
|
||||||
"import/no-duplicates": 0,
|
|
||||||
"max-statements": 0,
|
|
||||||
"max-params": 0,
|
|
||||||
"new-cap": 0,
|
|
||||||
"no-console": 0,
|
|
||||||
"no-duplicate-imports": 0,
|
|
||||||
"no-extra-parens": 0,
|
|
||||||
"no-return-assign": 0,
|
|
||||||
"no-throw-literal": 0,
|
|
||||||
"no-trailing-spaces": 0,
|
|
||||||
"no-unused-expressions": 0,
|
|
||||||
"no-useless-constructor": 0,
|
|
||||||
"no-useless-escape": 0,
|
|
||||||
"no-var": 0,
|
|
||||||
"prefer-const": 0,
|
|
||||||
"prefer-rest-params": 0,
|
|
||||||
"quote-props": 0,
|
|
||||||
"unicorn/filename-case": 0
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
import pluginJs from "@eslint/js";
|
||||||
|
import tseslint from "typescript-eslint";
|
||||||
|
|
||||||
|
export default [
|
||||||
|
pluginJs.configs.recommended,
|
||||||
|
...tseslint.configs.recommended,
|
||||||
|
{
|
||||||
|
languageOptions: {
|
||||||
|
parser: tseslint.parser,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// For some reason this has to be in its own block
|
||||||
|
{
|
||||||
|
ignores: [
|
||||||
|
"putTypesInIndex.js",
|
||||||
|
"dist/*",
|
||||||
|
"docs/*",
|
||||||
|
".yalc",
|
||||||
|
"jest.config.js",
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
files: ["src/**/*"],
|
||||||
|
rules: {
|
||||||
|
"@typescript-eslint/no-empty-interface": 0,
|
||||||
|
"@typescript-eslint/no-empty-function": 0,
|
||||||
|
"@typescript-eslint/ban-ts-comment": 0,
|
||||||
|
"@typescript-eslint/no-explicit-any": 0,
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": 0,
|
||||||
|
"@typescript-eslint/no-var-requires": 0,
|
||||||
|
"arrow-body-style": 0,
|
||||||
|
curly: 0,
|
||||||
|
"eol-last": 0,
|
||||||
|
eqeqeq: 0,
|
||||||
|
"func-style": 0,
|
||||||
|
"import/no-duplicates": 0,
|
||||||
|
"max-statements": 0,
|
||||||
|
"max-params": 0,
|
||||||
|
"new-cap": 0,
|
||||||
|
"no-console": 0,
|
||||||
|
"no-duplicate-imports": 0,
|
||||||
|
"no-extra-parens": 0,
|
||||||
|
"no-return-assign": 0,
|
||||||
|
"no-throw-literal": 0,
|
||||||
|
"no-trailing-spaces": 0,
|
||||||
|
"no-unused-expressions": 0,
|
||||||
|
"no-useless-constructor": 0,
|
||||||
|
"no-useless-escape": 0,
|
||||||
|
"no-var": 0,
|
||||||
|
"prefer-const": 0,
|
||||||
|
"prefer-rest-params": 0,
|
||||||
|
"quote-props": 0,
|
||||||
|
"unicorn/filename-case": 0,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
];
|
|
@ -6,9 +6,9 @@
|
||||||
"repository": "https://github.com/LemmyNet/lemmy",
|
"repository": "https://github.com/LemmyNet/lemmy",
|
||||||
"author": "Dessalines",
|
"author": "Dessalines",
|
||||||
"license": "AGPL-3.0",
|
"license": "AGPL-3.0",
|
||||||
"packageManager": "pnpm@9.1.4",
|
"packageManager": "pnpm@9.4.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint": "tsc --noEmit && eslint --report-unused-disable-directives --ext .js,.ts,.tsx src && prettier --check 'src/**/*.ts'",
|
"lint": "tsc --noEmit && eslint --report-unused-disable-directives && prettier --check 'src/**/*.ts'",
|
||||||
"fix": "prettier --write src && eslint --fix src",
|
"fix": "prettier --write src && eslint --fix src",
|
||||||
"api-test": "jest -i follow.spec.ts && jest -i image.spec.ts && jest -i user.spec.ts && jest -i private_message.spec.ts && jest -i community.spec.ts && jest -i post.spec.ts && jest -i comment.spec.ts ",
|
"api-test": "jest -i follow.spec.ts && jest -i image.spec.ts && jest -i user.spec.ts && jest -i private_message.spec.ts && jest -i community.spec.ts && jest -i post.spec.ts && jest -i comment.spec.ts ",
|
||||||
"api-test-follow": "jest -i follow.spec.ts",
|
"api-test-follow": "jest -i follow.spec.ts",
|
||||||
|
@ -25,12 +25,13 @@
|
||||||
"@typescript-eslint/eslint-plugin": "^7.5.0",
|
"@typescript-eslint/eslint-plugin": "^7.5.0",
|
||||||
"@typescript-eslint/parser": "^7.5.0",
|
"@typescript-eslint/parser": "^7.5.0",
|
||||||
"download-file-sync": "^1.0.4",
|
"download-file-sync": "^1.0.4",
|
||||||
"eslint": "^8.57.0",
|
"eslint": "^9.0.0",
|
||||||
"eslint-plugin-prettier": "^5.1.3",
|
"eslint-plugin-prettier": "^5.1.3",
|
||||||
"jest": "^29.5.0",
|
"jest": "^29.5.0",
|
||||||
"lemmy-js-client": "0.19.4",
|
"lemmy-js-client": "0.19.5-alpha.1",
|
||||||
"prettier": "^3.2.5",
|
"prettier": "^3.2.5",
|
||||||
"ts-jest": "^29.1.0",
|
"ts-jest": "^29.1.0",
|
||||||
"typescript": "^5.4.4"
|
"typescript": "^5.4.4",
|
||||||
|
"typescript-eslint": "^7.13.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,7 @@ export LEMMY_TEST_FAST_FEDERATION=1 # by default, the persistent federation queu
|
||||||
|
|
||||||
# pictrs setup
|
# pictrs setup
|
||||||
if [ ! -f "api_tests/pict-rs" ]; then
|
if [ ! -f "api_tests/pict-rs" ]; then
|
||||||
curl "https://git.asonix.dog/asonix/pict-rs/releases/download/v0.5.13/pict-rs-linux-amd64" -o api_tests/pict-rs
|
curl "https://git.asonix.dog/asonix/pict-rs/releases/download/v0.5.16/pict-rs-linux-amd64" -o api_tests/pict-rs
|
||||||
chmod +x api_tests/pict-rs
|
chmod +x api_tests/pict-rs
|
||||||
fi
|
fi
|
||||||
./api_tests/pict-rs \
|
./api_tests/pict-rs \
|
||||||
|
|
|
@ -160,6 +160,7 @@ test("Purge post, linked image removed", async () => {
|
||||||
upload.url,
|
upload.url,
|
||||||
);
|
);
|
||||||
expect(post.post_view.post.url).toBe(upload.url);
|
expect(post.post_view.post.url).toBe(upload.url);
|
||||||
|
expect(post.post_view.image_details).toBeDefined();
|
||||||
|
|
||||||
// purge post
|
// purge post
|
||||||
const purgeForm: PurgePost = {
|
const purgeForm: PurgePost = {
|
||||||
|
@ -184,6 +185,9 @@ test("Images in remote image post are proxied if setting enabled", async () => {
|
||||||
const post = postRes.post_view.post;
|
const post = postRes.post_view.post;
|
||||||
expect(post).toBeDefined();
|
expect(post).toBeDefined();
|
||||||
|
|
||||||
|
// Make sure it fetched the image details
|
||||||
|
expect(postRes.post_view.image_details).toBeDefined();
|
||||||
|
|
||||||
// remote image gets proxied after upload
|
// remote image gets proxied after upload
|
||||||
expect(
|
expect(
|
||||||
post.thumbnail_url?.startsWith(
|
post.thumbnail_url?.startsWith(
|
||||||
|
|
|
@ -502,7 +502,7 @@ test("Enforce site ban federation for local user", async () => {
|
||||||
}
|
}
|
||||||
let newAlphaUserJwt = await loginUser(alpha, alphaUserPerson.name);
|
let newAlphaUserJwt = await loginUser(alpha, alphaUserPerson.name);
|
||||||
alphaUserHttp.setHeaders({
|
alphaUserHttp.setHeaders({
|
||||||
Authorization: "Bearer " + newAlphaUserJwt.jwt ?? "",
|
Authorization: "Bearer " + newAlphaUserJwt.jwt,
|
||||||
});
|
});
|
||||||
// alpha makes new post in beta community, it federates
|
// alpha makes new post in beta community, it federates
|
||||||
let postRes2 = await createPost(alphaUserHttp, betaCommunity!.community.id);
|
let postRes2 = await createPost(alphaUserHttp, betaCommunity!.community.id);
|
||||||
|
|
|
@ -26,6 +26,7 @@ body = """
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
|
|
||||||
|
{%- if github -%}
|
||||||
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
{% if github.contributors | filter(attribute="is_first_time", value=true) | length != 0 %}
|
||||||
{% raw %}\n{% endraw -%}
|
{% raw %}\n{% endraw -%}
|
||||||
## New Contributors
|
## New Contributors
|
||||||
|
@ -36,6 +37,7 @@ body = """
|
||||||
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
[#{{ contributor.pr_number }}]({{ self::remote_url() }}/pull/{{ contributor.pr_number }}) \
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{%- endfor -%}
|
{%- endfor -%}
|
||||||
|
{%- endif -%}
|
||||||
|
|
||||||
{% if version %}
|
{% if version %}
|
||||||
{% if previous.version %}
|
{% if previous.version %}
|
||||||
|
@ -70,6 +72,7 @@ commit_preprocessors = [
|
||||||
# remove issue numbers from commits
|
# remove issue numbers from commits
|
||||||
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" },
|
{ pattern = '\((\w+\s)?#([0-9]+)\)', replace = "" },
|
||||||
]
|
]
|
||||||
|
commit_parsers = [{ field = "author.name", pattern = "renovate", skip = true }]
|
||||||
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
# protect breaking changes from being skipped due to matching a skipping commit_parser
|
||||||
protect_breaking_commits = false
|
protect_breaking_commits = false
|
||||||
# filter out the commits that are not matched by commit parsers
|
# filter out the commits that are not matched by commit parsers
|
||||||
|
|
|
@ -79,6 +79,8 @@ pub struct GetPosts {
|
||||||
pub liked_only: Option<bool>,
|
pub liked_only: Option<bool>,
|
||||||
pub disliked_only: Option<bool>,
|
pub disliked_only: Option<bool>,
|
||||||
pub show_hidden: Option<bool>,
|
pub show_hidden: Option<bool>,
|
||||||
|
/// If true, then show the read posts (even if your user setting is to hide them)
|
||||||
|
pub show_read: Option<bool>,
|
||||||
pub page_cursor: Option<PaginationCursor>,
|
pub page_cursor: Option<PaginationCursor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ use encoding_rs::{Encoding, UTF_8};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
newtypes::DbUrl,
|
newtypes::DbUrl,
|
||||||
source::{
|
source::{
|
||||||
images::{LocalImage, LocalImageForm},
|
images::{ImageDetailsForm, LocalImage, LocalImageForm},
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
post::{Post, PostUpdateForm},
|
post::{Post, PostUpdateForm},
|
||||||
},
|
},
|
||||||
|
@ -209,6 +209,19 @@ pub struct PictrsFileDetails {
|
||||||
pub created_at: DateTime<Utc>,
|
pub created_at: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl PictrsFileDetails {
|
||||||
|
/// Builds the image form. This should always use the thumbnail_url,
|
||||||
|
/// Because the post_view joins to it
|
||||||
|
pub fn build_image_details_form(&self, thumbnail_url: &Url) -> ImageDetailsForm {
|
||||||
|
ImageDetailsForm {
|
||||||
|
link: thumbnail_url.clone().into(),
|
||||||
|
width: self.width.into(),
|
||||||
|
height: self.height.into(),
|
||||||
|
content_type: self.content_type.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize, Debug)]
|
#[derive(Deserialize, Serialize, Debug)]
|
||||||
struct PictrsPurgeResponse {
|
struct PictrsPurgeResponse {
|
||||||
msg: String,
|
msg: String,
|
||||||
|
@ -316,11 +329,52 @@ async fn generate_pictrs_thumbnail(image_url: &Url, context: &LemmyContext) -> L
|
||||||
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
||||||
let thumbnail_url = image.thumbnail_url(&protocol_and_hostname)?;
|
let thumbnail_url = image.thumbnail_url(&protocol_and_hostname)?;
|
||||||
|
|
||||||
LocalImage::create(&mut context.pool(), &form).await?;
|
// Also store the details for the image
|
||||||
|
let details_form = image.details.build_image_details_form(&thumbnail_url);
|
||||||
|
LocalImage::create(&mut context.pool(), &form, &details_form).await?;
|
||||||
|
|
||||||
Ok(thumbnail_url)
|
Ok(thumbnail_url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Fetches the image details for pictrs proxied images
|
||||||
|
///
|
||||||
|
/// We don't need to check for image mode, as that's already been done
|
||||||
|
#[tracing::instrument(skip_all)]
|
||||||
|
pub async fn fetch_pictrs_proxied_image_details(
|
||||||
|
image_url: &Url,
|
||||||
|
context: &LemmyContext,
|
||||||
|
) -> LemmyResult<PictrsFileDetails> {
|
||||||
|
let pictrs_url = context.settings().pictrs_config()?.url;
|
||||||
|
let encoded_image_url = encode(image_url.as_str());
|
||||||
|
|
||||||
|
// Pictrs needs you to fetch the proxied image before you can fetch the details
|
||||||
|
let proxy_url = format!("{pictrs_url}image/original?proxy={encoded_image_url}");
|
||||||
|
|
||||||
|
let res = context
|
||||||
|
.client()
|
||||||
|
.get(&proxy_url)
|
||||||
|
.timeout(REQWEST_TIMEOUT)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.status();
|
||||||
|
if !res.is_success() {
|
||||||
|
Err(LemmyErrorType::NotAnImageType)?
|
||||||
|
}
|
||||||
|
|
||||||
|
let details_url = format!("{pictrs_url}image/details/original?proxy={encoded_image_url}");
|
||||||
|
|
||||||
|
let res = context
|
||||||
|
.client()
|
||||||
|
.get(&details_url)
|
||||||
|
.timeout(REQWEST_TIMEOUT)
|
||||||
|
.send()
|
||||||
|
.await?
|
||||||
|
.json()
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: get rid of this by reading content type from db
|
// TODO: get rid of this by reading content type from db
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> LemmyResult<()> {
|
async fn is_image_content_type(client: &ClientWithMiddleware, url: &Url) -> LemmyResult<()> {
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
context::LemmyContext,
|
context::LemmyContext,
|
||||||
request::{delete_image_from_pictrs, purge_image_from_pictrs},
|
request::{
|
||||||
|
delete_image_from_pictrs,
|
||||||
|
fetch_pictrs_proxied_image_details,
|
||||||
|
purge_image_from_pictrs,
|
||||||
|
},
|
||||||
site::{FederatedInstances, InstanceWithFederationState},
|
site::{FederatedInstances, InstanceWithFederationState},
|
||||||
};
|
};
|
||||||
use chrono::{DateTime, Days, Local, TimeZone, Utc};
|
use chrono::{DateTime, Days, Local, TimeZone, Utc};
|
||||||
|
@ -948,7 +952,18 @@ pub async fn process_markdown(
|
||||||
|
|
||||||
if context.settings().pictrs_config()?.image_mode() == PictrsImageMode::ProxyAllImages {
|
if context.settings().pictrs_config()?.image_mode() == PictrsImageMode::ProxyAllImages {
|
||||||
let (text, links) = markdown_rewrite_image_links(text);
|
let (text, links) = markdown_rewrite_image_links(text);
|
||||||
RemoteImage::create(&mut context.pool(), links).await?;
|
|
||||||
|
// Create images and image detail rows
|
||||||
|
for link in links {
|
||||||
|
// Insert image details for the remote image
|
||||||
|
let details_res = fetch_pictrs_proxied_image_details(&link, context).await;
|
||||||
|
if let Ok(details) = details_res {
|
||||||
|
let proxied =
|
||||||
|
build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
||||||
|
let details_form = details.build_image_details_form(&proxied);
|
||||||
|
RemoteImage::create(&mut context.pool(), &details_form).await?;
|
||||||
|
}
|
||||||
|
}
|
||||||
Ok(text)
|
Ok(text)
|
||||||
} else {
|
} else {
|
||||||
Ok(text)
|
Ok(text)
|
||||||
|
@ -983,8 +998,14 @@ async fn proxy_image_link_internal(
|
||||||
Ok(link.into())
|
Ok(link.into())
|
||||||
} else if image_mode == PictrsImageMode::ProxyAllImages {
|
} else if image_mode == PictrsImageMode::ProxyAllImages {
|
||||||
let proxied = build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
let proxied = build_proxied_image_url(&link, &context.settings().get_protocol_and_hostname())?;
|
||||||
|
// This should fail softly, since pictrs might not even be running
|
||||||
|
let details_res = fetch_pictrs_proxied_image_details(&link, context).await;
|
||||||
|
|
||||||
|
if let Ok(details) = details_res {
|
||||||
|
let details_form = details.build_image_details_form(&proxied);
|
||||||
|
RemoteImage::create(&mut context.pool(), &details_form).await?;
|
||||||
|
};
|
||||||
|
|
||||||
RemoteImage::create(&mut context.pool(), vec![link]).await?;
|
|
||||||
Ok(proxied.into())
|
Ok(proxied.into())
|
||||||
} else {
|
} else {
|
||||||
Ok(link.into())
|
Ok(link.into())
|
||||||
|
@ -1122,10 +1143,13 @@ mod tests {
|
||||||
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
"https://lemmy-alpha/api/v3/image_proxy?url=http%3A%2F%2Flemmy-beta%2Fimage.png",
|
||||||
proxied.as_str()
|
proxied.as_str()
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// This fails, because the details can't be fetched without pictrs running,
|
||||||
|
// And a remote image won't be inserted.
|
||||||
assert!(
|
assert!(
|
||||||
RemoteImage::validate(&mut context.pool(), remote_image.into())
|
RemoteImage::validate(&mut context.pool(), remote_image.into())
|
||||||
.await
|
.await
|
||||||
.is_ok()
|
.is_err()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -83,11 +83,13 @@ pub async fn get_post(
|
||||||
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
.ok_or(LemmyErrorType::CouldntFindCommunity)?;
|
||||||
|
|
||||||
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
let moderators = CommunityModeratorView::for_community(&mut context.pool(), community_id).await?;
|
||||||
|
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
|
||||||
|
|
||||||
// Fetch the cross_posts
|
// Fetch the cross_posts
|
||||||
let cross_posts = if let Some(url) = &post_view.post.url {
|
let cross_posts = if let Some(url) = &post_view.post.url {
|
||||||
let mut x_posts = PostQuery {
|
let mut x_posts = PostQuery {
|
||||||
url_search: Some(url.inner().as_str().into()),
|
url_search: Some(url.inner().as_str().into()),
|
||||||
|
local_user,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&local_site.site, &mut context.pool())
|
.list(&local_site.site, &mut context.pool())
|
||||||
|
|
|
@ -37,11 +37,11 @@ pub async fn list_comments(
|
||||||
};
|
};
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let max_depth = data.max_depth;
|
let max_depth = data.max_depth;
|
||||||
let saved_only = data.saved_only.unwrap_or_default();
|
let saved_only = data.saved_only;
|
||||||
|
|
||||||
let liked_only = data.liked_only.unwrap_or_default();
|
let liked_only = data.liked_only;
|
||||||
let disliked_only = data.disliked_only.unwrap_or_default();
|
let disliked_only = data.disliked_only;
|
||||||
if liked_only && disliked_only {
|
if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() {
|
||||||
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +70,8 @@ pub async fn list_comments(
|
||||||
|
|
||||||
let parent_path_cloned = parent_path.clone();
|
let parent_path_cloned = parent_path.clone();
|
||||||
let post_id = data.post_id;
|
let post_id = data.post_id;
|
||||||
|
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
||||||
|
|
||||||
let comments = CommentQuery {
|
let comments = CommentQuery {
|
||||||
listing_type,
|
listing_type,
|
||||||
sort,
|
sort,
|
||||||
|
@ -80,7 +82,7 @@ pub async fn list_comments(
|
||||||
community_id,
|
community_id,
|
||||||
parent_path: parent_path_cloned,
|
parent_path: parent_path_cloned,
|
||||||
post_id,
|
post_id,
|
||||||
local_user: local_user_view.as_ref(),
|
local_user,
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -40,26 +40,27 @@ pub async fn list_posts(
|
||||||
} else {
|
} else {
|
||||||
data.community_id
|
data.community_id
|
||||||
};
|
};
|
||||||
let saved_only = data.saved_only.unwrap_or_default();
|
let saved_only = data.saved_only;
|
||||||
let show_hidden = data.show_hidden.unwrap_or_default();
|
let show_hidden = data.show_hidden;
|
||||||
|
let show_read = data.show_read;
|
||||||
|
|
||||||
let liked_only = data.liked_only.unwrap_or_default();
|
let liked_only = data.liked_only;
|
||||||
let disliked_only = data.disliked_only.unwrap_or_default();
|
let disliked_only = data.disliked_only;
|
||||||
if liked_only && disliked_only {
|
if liked_only.unwrap_or_default() && disliked_only.unwrap_or_default() {
|
||||||
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
return Err(LemmyError::from(LemmyErrorType::ContradictingFilters));
|
||||||
}
|
}
|
||||||
|
|
||||||
let local_user_ref = local_user_view.as_ref().map(|u| &u.local_user);
|
let local_user = local_user_view.as_ref().map(|u| &u.local_user);
|
||||||
let listing_type = Some(listing_type_with_default(
|
let listing_type = Some(listing_type_with_default(
|
||||||
data.type_,
|
data.type_,
|
||||||
local_user_ref,
|
local_user,
|
||||||
&local_site.local_site,
|
&local_site.local_site,
|
||||||
community_id,
|
community_id,
|
||||||
));
|
));
|
||||||
|
|
||||||
let sort = Some(sort_type_with_default(
|
let sort = Some(sort_type_with_default(
|
||||||
data.sort,
|
data.sort,
|
||||||
local_user_ref,
|
local_user,
|
||||||
&local_site.local_site,
|
&local_site.local_site,
|
||||||
));
|
));
|
||||||
|
|
||||||
|
@ -71,7 +72,7 @@ pub async fn list_posts(
|
||||||
};
|
};
|
||||||
|
|
||||||
let posts = PostQuery {
|
let posts = PostQuery {
|
||||||
local_user: local_user_view.as_ref(),
|
local_user,
|
||||||
listing_type,
|
listing_type,
|
||||||
sort,
|
sort,
|
||||||
community_id,
|
community_id,
|
||||||
|
@ -82,6 +83,7 @@ pub async fn list_posts(
|
||||||
page_after,
|
page_after,
|
||||||
limit,
|
limit,
|
||||||
show_hidden,
|
show_hidden,
|
||||||
|
show_read,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&local_site.site, &mut context.pool())
|
.list(&local_site.site, &mut context.pool())
|
||||||
|
|
|
@ -55,20 +55,22 @@ pub async fn read_person(
|
||||||
let sort = data.sort;
|
let sort = data.sort;
|
||||||
let page = data.page;
|
let page = data.page;
|
||||||
let limit = data.limit;
|
let limit = data.limit;
|
||||||
let saved_only = data.saved_only.unwrap_or_default();
|
let saved_only = data.saved_only;
|
||||||
let community_id = data.community_id;
|
let community_id = data.community_id;
|
||||||
// If its saved only, you don't care what creator it was
|
// If its saved only, you don't care what creator it was
|
||||||
// Or, if its not saved, then you only want it for that specific creator
|
// Or, if its not saved, then you only want it for that specific creator
|
||||||
let creator_id = if !saved_only {
|
let creator_id = if !saved_only.unwrap_or_default() {
|
||||||
Some(person_details_id)
|
Some(person_details_id)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
||||||
|
|
||||||
let posts = PostQuery {
|
let posts = PostQuery {
|
||||||
sort,
|
sort,
|
||||||
saved_only,
|
saved_only,
|
||||||
local_user: local_user_view.as_ref(),
|
local_user,
|
||||||
community_id,
|
community_id,
|
||||||
page,
|
page,
|
||||||
limit,
|
limit,
|
||||||
|
@ -79,7 +81,7 @@ pub async fn read_person(
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let comments = CommentQuery {
|
let comments = CommentQuery {
|
||||||
local_user: local_user_view.as_ref(),
|
local_user,
|
||||||
sort: sort.map(post_to_comment_sort_type),
|
sort: sort.map(post_to_comment_sort_type),
|
||||||
saved_only,
|
saved_only,
|
||||||
community_id,
|
community_id,
|
||||||
|
|
|
@ -55,7 +55,7 @@ pub async fn search(
|
||||||
data.community_id
|
data.community_id
|
||||||
};
|
};
|
||||||
let creator_id = data.creator_id;
|
let creator_id = data.creator_id;
|
||||||
let local_user = local_user_view.as_ref().map(|luv| &luv.local_user);
|
let local_user = local_user_view.as_ref().map(|l| &l.local_user);
|
||||||
|
|
||||||
match search_type {
|
match search_type {
|
||||||
SearchType::Posts => {
|
SearchType::Posts => {
|
||||||
|
@ -64,7 +64,7 @@ pub async fn search(
|
||||||
listing_type: (listing_type),
|
listing_type: (listing_type),
|
||||||
community_id: (community_id),
|
community_id: (community_id),
|
||||||
creator_id: (creator_id),
|
creator_id: (creator_id),
|
||||||
local_user: (local_user_view.as_ref()),
|
local_user,
|
||||||
search_term: (Some(q)),
|
search_term: (Some(q)),
|
||||||
page: (page),
|
page: (page),
|
||||||
limit: (limit),
|
limit: (limit),
|
||||||
|
@ -80,7 +80,7 @@ pub async fn search(
|
||||||
search_term: (Some(q)),
|
search_term: (Some(q)),
|
||||||
community_id: (community_id),
|
community_id: (community_id),
|
||||||
creator_id: (creator_id),
|
creator_id: (creator_id),
|
||||||
local_user: (local_user_view.as_ref()),
|
local_user,
|
||||||
page: (page),
|
page: (page),
|
||||||
limit: (limit),
|
limit: (limit),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -125,7 +125,7 @@ pub async fn search(
|
||||||
listing_type: (listing_type),
|
listing_type: (listing_type),
|
||||||
community_id: (community_id),
|
community_id: (community_id),
|
||||||
creator_id: (creator_id),
|
creator_id: (creator_id),
|
||||||
local_user: (local_user_view.as_ref()),
|
local_user,
|
||||||
search_term: (Some(q)),
|
search_term: (Some(q)),
|
||||||
page: (page),
|
page: (page),
|
||||||
limit: (limit),
|
limit: (limit),
|
||||||
|
@ -142,7 +142,7 @@ pub async fn search(
|
||||||
search_term: (Some(q)),
|
search_term: (Some(q)),
|
||||||
community_id: (community_id),
|
community_id: (community_id),
|
||||||
creator_id: (creator_id),
|
creator_id: (creator_id),
|
||||||
local_user: (local_user_view.as_ref()),
|
local_user,
|
||||||
page: (page),
|
page: (page),
|
||||||
limit: (limit),
|
limit: (limit),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
@ -192,6 +192,7 @@ pub async fn search(
|
||||||
community_id: (community_id),
|
community_id: (community_id),
|
||||||
creator_id: (creator_id),
|
creator_id: (creator_id),
|
||||||
url_search: (Some(q)),
|
url_search: (Some(q)),
|
||||||
|
local_user,
|
||||||
page: (page),
|
page: (page),
|
||||||
limit: (limit),
|
limit: (limit),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
|
|
|
@ -488,7 +488,7 @@ BEGIN
|
||||||
INNER JOIN old_post ON old_post.id = new_post.id
|
INNER JOIN old_post ON old_post.id = new_post.id
|
||||||
AND (old_post.featured_community,
|
AND (old_post.featured_community,
|
||||||
old_post.featured_local) != (new_post.featured_community,
|
old_post.featured_local) != (new_post.featured_community,
|
||||||
old_post.featured_local)
|
new_post.featured_local)
|
||||||
WHERE
|
WHERE
|
||||||
post_aggregates.post_id = new_post.id;
|
post_aggregates.post_id = new_post.id;
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
|
|
|
@ -133,8 +133,9 @@ impl Crud for Comment {
|
||||||
type IdType = CommentId;
|
type IdType = CommentId;
|
||||||
|
|
||||||
/// This is unimplemented, use [[Comment::create]]
|
/// This is unimplemented, use [[Comment::create]]
|
||||||
async fn create(_pool: &mut DbPool<'_>, _comment_form: &Self::InsertForm) -> Result<Self, Error> {
|
async fn create(pool: &mut DbPool<'_>, comment_form: &Self::InsertForm) -> Result<Self, Error> {
|
||||||
unimplemented!();
|
debug_assert!(false);
|
||||||
|
Comment::create(pool, comment_form, None).await
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn update(
|
async fn update(
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
use crate::{
|
use crate::{
|
||||||
newtypes::DbUrl,
|
newtypes::DbUrl,
|
||||||
schema::{local_image, remote_image},
|
schema::{image_details, local_image, remote_image},
|
||||||
source::images::{LocalImage, LocalImageForm, RemoteImage, RemoteImageForm},
|
source::images::{
|
||||||
|
ImageDetails,
|
||||||
|
ImageDetailsForm,
|
||||||
|
LocalImage,
|
||||||
|
LocalImageForm,
|
||||||
|
RemoteImage,
|
||||||
|
RemoteImageForm,
|
||||||
|
},
|
||||||
utils::{get_conn, DbPool},
|
utils::{get_conn, DbPool},
|
||||||
};
|
};
|
||||||
use diesel::{
|
use diesel::{
|
||||||
|
@ -13,15 +20,29 @@ use diesel::{
|
||||||
NotFound,
|
NotFound,
|
||||||
QueryDsl,
|
QueryDsl,
|
||||||
};
|
};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::{AsyncPgConnection, RunQueryDsl};
|
||||||
use url::Url;
|
|
||||||
|
|
||||||
impl LocalImage {
|
impl LocalImage {
|
||||||
pub async fn create(pool: &mut DbPool<'_>, form: &LocalImageForm) -> Result<Self, Error> {
|
pub async fn create(
|
||||||
|
pool: &mut DbPool<'_>,
|
||||||
|
form: &LocalImageForm,
|
||||||
|
image_details_form: &ImageDetailsForm,
|
||||||
|
) -> Result<Self, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
insert_into(local_image::table)
|
conn
|
||||||
.values(form)
|
.build_transaction()
|
||||||
.get_result::<Self>(conn)
|
.run(|conn| {
|
||||||
|
Box::pin(async move {
|
||||||
|
let local_insert = insert_into(local_image::table)
|
||||||
|
.values(form)
|
||||||
|
.get_result::<Self>(conn)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
ImageDetails::create(conn, image_details_form).await?;
|
||||||
|
|
||||||
|
local_insert
|
||||||
|
}) as _
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,16 +60,26 @@ impl LocalImage {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RemoteImage {
|
impl RemoteImage {
|
||||||
pub async fn create(pool: &mut DbPool<'_>, links: Vec<Url>) -> Result<usize, Error> {
|
pub async fn create(pool: &mut DbPool<'_>, form: &ImageDetailsForm) -> Result<usize, Error> {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
let forms = links
|
conn
|
||||||
.into_iter()
|
.build_transaction()
|
||||||
.map(|url| RemoteImageForm { link: url.into() })
|
.run(|conn| {
|
||||||
.collect::<Vec<_>>();
|
Box::pin(async move {
|
||||||
insert_into(remote_image::table)
|
let remote_image_form = RemoteImageForm {
|
||||||
.values(forms)
|
link: form.link.clone(),
|
||||||
.on_conflict_do_nothing()
|
};
|
||||||
.execute(conn)
|
let remote_insert = insert_into(remote_image::table)
|
||||||
|
.values(remote_image_form)
|
||||||
|
.on_conflict_do_nothing()
|
||||||
|
.execute(conn)
|
||||||
|
.await;
|
||||||
|
|
||||||
|
ImageDetails::create(conn, form).await?;
|
||||||
|
|
||||||
|
remote_insert
|
||||||
|
}) as _
|
||||||
|
})
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,3 +98,16 @@ impl RemoteImage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ImageDetails {
|
||||||
|
pub(crate) async fn create(
|
||||||
|
conn: &mut AsyncPgConnection,
|
||||||
|
form: &ImageDetailsForm,
|
||||||
|
) -> Result<usize, Error> {
|
||||||
|
insert_into(image_details::table)
|
||||||
|
.values(form)
|
||||||
|
.on_conflict_do_nothing()
|
||||||
|
.execute(conn)
|
||||||
|
.await
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ use crate::{
|
||||||
actor_language::LocalUserLanguage,
|
actor_language::LocalUserLanguage,
|
||||||
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
local_user::{LocalUser, LocalUserInsertForm, LocalUserUpdateForm},
|
||||||
local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm},
|
local_user_vote_display_mode::{LocalUserVoteDisplayMode, LocalUserVoteDisplayModeInsertForm},
|
||||||
|
site::Site,
|
||||||
},
|
},
|
||||||
utils::{
|
utils::{
|
||||||
action_query,
|
action_query,
|
||||||
|
@ -216,6 +217,44 @@ impl LocalUser {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Adds some helper functions for an optional LocalUser
|
||||||
|
pub trait LocalUserOptionHelper {
|
||||||
|
fn person_id(&self) -> Option<PersonId>;
|
||||||
|
fn local_user_id(&self) -> Option<LocalUserId>;
|
||||||
|
fn show_bot_accounts(&self) -> bool;
|
||||||
|
fn show_read_posts(&self) -> bool;
|
||||||
|
fn is_admin(&self) -> bool;
|
||||||
|
fn show_nsfw(&self, site: &Site) -> bool;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LocalUserOptionHelper for Option<&LocalUser> {
|
||||||
|
fn person_id(&self) -> Option<PersonId> {
|
||||||
|
self.map(|l| l.person_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn local_user_id(&self) -> Option<LocalUserId> {
|
||||||
|
self.map(|l| l.id)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_bot_accounts(&self) -> bool {
|
||||||
|
self.map(|l| l.show_bot_accounts).unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_read_posts(&self) -> bool {
|
||||||
|
self.map(|l| l.show_read_posts).unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn is_admin(&self) -> bool {
|
||||||
|
self.map(|l| l.admin).unwrap_or(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn show_nsfw(&self, site: &Site) -> bool {
|
||||||
|
self
|
||||||
|
.map(|l| l.show_nsfw)
|
||||||
|
.unwrap_or(site.content_warning.is_some())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LocalUserInsertForm {
|
impl LocalUserInsertForm {
|
||||||
pub fn test_form(person_id: PersonId) -> Self {
|
pub fn test_form(person_id: PersonId) -> Self {
|
||||||
Self::builder()
|
Self::builder()
|
||||||
|
|
|
@ -281,6 +281,15 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
diesel::table! {
|
||||||
|
image_details (link) {
|
||||||
|
link -> Text,
|
||||||
|
width -> Int4,
|
||||||
|
height -> Int4,
|
||||||
|
content_type -> Text,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
instance (id) {
|
instance (id) {
|
||||||
id -> Int4,
|
id -> Int4,
|
||||||
|
@ -786,8 +795,7 @@ diesel::table! {
|
||||||
}
|
}
|
||||||
|
|
||||||
diesel::table! {
|
diesel::table! {
|
||||||
remote_image (id) {
|
remote_image (link) {
|
||||||
id -> Int4,
|
|
||||||
link -> Text,
|
link -> Text,
|
||||||
published -> Timestamptz,
|
published -> Timestamptz,
|
||||||
}
|
}
|
||||||
|
@ -972,6 +980,7 @@ diesel::allow_tables_to_appear_in_same_query!(
|
||||||
federation_allowlist,
|
federation_allowlist,
|
||||||
federation_blocklist,
|
federation_blocklist,
|
||||||
federation_queue_state,
|
federation_queue_state,
|
||||||
|
image_details,
|
||||||
instance,
|
instance,
|
||||||
instance_actions,
|
instance_actions,
|
||||||
language,
|
language,
|
||||||
|
|
|
@ -1,13 +1,12 @@
|
||||||
use crate::newtypes::{DbUrl, LocalUserId};
|
use crate::newtypes::{DbUrl, LocalUserId};
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use crate::schema::{local_image, remote_image};
|
use crate::schema::{image_details, local_image, remote_image};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_with::skip_serializing_none;
|
use serde_with::skip_serializing_none;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
#[cfg(feature = "full")]
|
#[cfg(feature = "full")]
|
||||||
use ts_rs::TS;
|
use ts_rs::TS;
|
||||||
use typed_builder::TypedBuilder;
|
|
||||||
|
|
||||||
#[skip_serializing_none]
|
#[skip_serializing_none]
|
||||||
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||||
|
@ -30,7 +29,7 @@ pub struct LocalImage {
|
||||||
pub published: DateTime<Utc>,
|
pub published: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, TypedBuilder)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = local_image))]
|
#[cfg_attr(feature = "full", diesel(table_name = local_image))]
|
||||||
pub struct LocalImageForm {
|
pub struct LocalImageForm {
|
||||||
|
@ -46,15 +45,39 @@ pub struct LocalImageForm {
|
||||||
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable))]
|
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = remote_image))]
|
#[cfg_attr(feature = "full", diesel(table_name = remote_image))]
|
||||||
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
#[cfg_attr(feature = "full", diesel(primary_key(link)))]
|
||||||
pub struct RemoteImage {
|
pub struct RemoteImage {
|
||||||
pub id: i32,
|
|
||||||
pub link: DbUrl,
|
pub link: DbUrl,
|
||||||
pub published: DateTime<Utc>,
|
pub published: DateTime<Utc>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, TypedBuilder)]
|
#[derive(Debug, Clone)]
|
||||||
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||||
#[cfg_attr(feature = "full", diesel(table_name = remote_image))]
|
#[cfg_attr(feature = "full", diesel(table_name = remote_image))]
|
||||||
pub struct RemoteImageForm {
|
pub struct RemoteImageForm {
|
||||||
pub link: DbUrl,
|
pub link: DbUrl,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[skip_serializing_none]
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Serialize, Deserialize)]
|
||||||
|
#[cfg_attr(feature = "full", derive(Queryable, Selectable, Identifiable, TS))]
|
||||||
|
#[cfg_attr(feature = "full", ts(export))]
|
||||||
|
#[cfg_attr(feature = "full", diesel(table_name = image_details))]
|
||||||
|
#[cfg_attr(feature = "full", diesel(check_for_backend(diesel::pg::Pg)))]
|
||||||
|
#[cfg_attr(feature = "full", diesel(primary_key(link)))]
|
||||||
|
pub struct ImageDetails {
|
||||||
|
pub link: DbUrl,
|
||||||
|
pub width: i32,
|
||||||
|
pub height: i32,
|
||||||
|
pub content_type: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
#[cfg_attr(feature = "full", derive(Insertable, AsChangeset))]
|
||||||
|
#[cfg_attr(feature = "full", diesel(table_name = image_details))]
|
||||||
|
pub struct ImageDetailsForm {
|
||||||
|
pub link: DbUrl,
|
||||||
|
pub width: i32,
|
||||||
|
pub height: i32,
|
||||||
|
pub content_type: String,
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
pub mod uplete;
|
pub mod uplete;
|
||||||
|
|
||||||
use crate::{newtypes::DbUrl, CommentSortType, SortType};
|
use crate::{
|
||||||
|
newtypes::{DbUrl, PersonId},
|
||||||
|
schema::community,
|
||||||
|
CommentSortType,
|
||||||
|
CommunityVisibility,
|
||||||
|
SortType,
|
||||||
|
};
|
||||||
use chrono::{DateTime, TimeDelta, Utc};
|
use chrono::{DateTime, TimeDelta, Utc};
|
||||||
use deadpool::Runtime;
|
use deadpool::Runtime;
|
||||||
use diesel::{
|
use diesel::{
|
||||||
|
@ -337,6 +343,10 @@ pub fn diesel_url_create(opt: Option<&str>) -> LemmyResult<Option<DbUrl>> {
|
||||||
|
|
||||||
fn establish_connection(config: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
|
fn establish_connection(config: &str) -> BoxFuture<ConnectionResult<AsyncPgConnection>> {
|
||||||
let fut = async {
|
let fut = async {
|
||||||
|
rustls::crypto::ring::default_provider()
|
||||||
|
.install_default()
|
||||||
|
.expect("Failed to install rustls crypto provider");
|
||||||
|
|
||||||
let rustls_config = DangerousClientConfigBuilder {
|
let rustls_config = DangerousClientConfigBuilder {
|
||||||
cfg: ClientConfig::builder(),
|
cfg: ClientConfig::builder(),
|
||||||
}
|
}
|
||||||
|
@ -678,6 +688,20 @@ impl<RF, LF> Queries<RF, LF> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn visible_communities_only<Q>(my_person_id: Option<PersonId>, query: Q) -> Q
|
||||||
|
where
|
||||||
|
Q: diesel::query_dsl::methods::FilterDsl<
|
||||||
|
dsl::Eq<community::visibility, CommunityVisibility>,
|
||||||
|
Output = Q,
|
||||||
|
>,
|
||||||
|
{
|
||||||
|
if my_person_id.is_none() {
|
||||||
|
query.filter(community::visibility.eq(CommunityVisibility::Public))
|
||||||
|
} else {
|
||||||
|
query
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[allow(clippy::indexing_slicing)]
|
#[allow(clippy::indexing_slicing)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::structs::{CommentView, LocalUserView};
|
use crate::structs::CommentView;
|
||||||
use diesel::{
|
use diesel::{
|
||||||
dsl::{exists, not},
|
dsl::{exists, not},
|
||||||
pg::Pg,
|
pg::Pg,
|
||||||
|
@ -14,6 +14,7 @@ use diesel_async::RunQueryDsl;
|
||||||
use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions};
|
use diesel_ltree::{nlevel, subpath, Ltree, LtreeExtensions};
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aliases::creator_community_actions,
|
aliases::creator_community_actions,
|
||||||
|
impls::local_user::LocalUserOptionHelper,
|
||||||
newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId},
|
newtypes::{CommentId, CommunityId, LocalUserId, PersonId, PostId},
|
||||||
schema::{
|
schema::{
|
||||||
comment,
|
comment,
|
||||||
|
@ -28,12 +29,13 @@ use lemmy_db_schema::{
|
||||||
person_actions,
|
person_actions,
|
||||||
post,
|
post,
|
||||||
},
|
},
|
||||||
source::community::CommunityFollower,
|
source::{community::CommunityFollower, local_user::LocalUser},
|
||||||
utils::{
|
utils::{
|
||||||
actions,
|
actions,
|
||||||
actions_alias,
|
actions_alias,
|
||||||
fuzzy_search,
|
fuzzy_search,
|
||||||
limit_and_offset,
|
limit_and_offset,
|
||||||
|
visible_communities_only,
|
||||||
DbConn,
|
DbConn,
|
||||||
DbPool,
|
DbPool,
|
||||||
ListFn,
|
ListFn,
|
||||||
|
@ -41,7 +43,6 @@ use lemmy_db_schema::{
|
||||||
ReadFn,
|
ReadFn,
|
||||||
},
|
},
|
||||||
CommentSortType,
|
CommentSortType,
|
||||||
CommunityVisibility,
|
|
||||||
ListingType,
|
ListingType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,21 +115,18 @@ fn queries<'a>() -> Queries<
|
||||||
let read = move |mut conn: DbConn<'a>,
|
let read = move |mut conn: DbConn<'a>,
|
||||||
(comment_id, my_person_id): (CommentId, Option<PersonId>)| async move {
|
(comment_id, my_person_id): (CommentId, Option<PersonId>)| async move {
|
||||||
let mut query = all_joins(comment::table.find(comment_id).into_boxed(), my_person_id);
|
let mut query = all_joins(comment::table.find(comment_id).into_boxed(), my_person_id);
|
||||||
// Hide local only communities from unauthenticated users
|
query = visible_communities_only(my_person_id, query);
|
||||||
if my_person_id.is_none() {
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
|
||||||
query.first(&mut conn).await
|
query.first(&mut conn).await
|
||||||
};
|
};
|
||||||
|
|
||||||
let list = move |mut conn: DbConn<'a>, options: CommentQuery<'a>| async move {
|
let list = move |mut conn: DbConn<'a>, options: CommentQuery<'a>| async move {
|
||||||
let my_person_id = options.local_user.map(|l| l.person.id);
|
|
||||||
let my_local_user_id = options.local_user.map(|l| l.local_user.id);
|
|
||||||
|
|
||||||
// The left join below will return None in this case
|
// The left join below will return None in this case
|
||||||
let local_user_id_join = my_local_user_id.unwrap_or(LocalUserId(-1));
|
let local_user_id_join = options
|
||||||
|
.local_user
|
||||||
|
.local_user_id()
|
||||||
|
.unwrap_or(LocalUserId(-1));
|
||||||
|
|
||||||
let mut query = all_joins(comment::table.into_boxed(), my_person_id);
|
let mut query = all_joins(comment::table.into_boxed(), options.local_user.person_id());
|
||||||
|
|
||||||
if let Some(creator_id) = options.creator_id {
|
if let Some(creator_id) = options.creator_id {
|
||||||
query = query.filter(comment::creator_id.eq(creator_id));
|
query = query.filter(comment::creator_id.eq(creator_id));
|
||||||
|
@ -172,30 +170,26 @@ fn queries<'a>() -> Queries<
|
||||||
}
|
}
|
||||||
|
|
||||||
// If its saved only, then filter, and order by the saved time, not the comment creation time.
|
// If its saved only, then filter, and order by the saved time, not the comment creation time.
|
||||||
if options.saved_only {
|
if options.saved_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(comment_actions::saved.is_not_null())
|
.filter(comment_actions::saved.is_not_null())
|
||||||
.then_order_by(comment_actions::saved.desc());
|
.then_order_by(comment_actions::saved.desc());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(my_id) = my_person_id {
|
if let Some(my_id) = options.local_user.person_id() {
|
||||||
let not_creator_filter = comment::creator_id.ne(my_id);
|
let not_creator_filter = comment::creator_id.ne(my_id);
|
||||||
if options.liked_only {
|
if options.liked_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(not_creator_filter)
|
.filter(not_creator_filter)
|
||||||
.filter(comment_actions::like_score.eq(1));
|
.filter(comment_actions::like_score.eq(1));
|
||||||
} else if options.disliked_only {
|
} else if options.disliked_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(not_creator_filter)
|
.filter(not_creator_filter)
|
||||||
.filter(comment_actions::like_score.eq(-1));
|
.filter(comment_actions::like_score.eq(-1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !options
|
if !options.local_user.show_bot_accounts() {
|
||||||
.local_user
|
|
||||||
.map(|l| l.local_user.show_bot_accounts)
|
|
||||||
.unwrap_or(true)
|
|
||||||
{
|
|
||||||
query = query.filter(person::bot_account.eq(false));
|
query = query.filter(person::bot_account.eq(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -218,10 +212,7 @@ fn queries<'a>() -> Queries<
|
||||||
.filter(person_actions::blocked.is_null());
|
.filter(person_actions::blocked.is_null());
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide comments in local only communities from unauthenticated users
|
query = visible_communities_only(options.local_user.person_id(), query);
|
||||||
if options.local_user.is_none() {
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
|
||||||
|
|
||||||
// A Max depth given means its a tree fetch
|
// A Max depth given means its a tree fetch
|
||||||
let (limit, offset) = if let Some(max_depth) = options.max_depth {
|
let (limit, offset) = if let Some(max_depth) = options.max_depth {
|
||||||
|
@ -316,11 +307,11 @@ pub struct CommentQuery<'a> {
|
||||||
pub post_id: Option<PostId>,
|
pub post_id: Option<PostId>,
|
||||||
pub parent_path: Option<Ltree>,
|
pub parent_path: Option<Ltree>,
|
||||||
pub creator_id: Option<PersonId>,
|
pub creator_id: Option<PersonId>,
|
||||||
pub local_user: Option<&'a LocalUserView>,
|
pub local_user: Option<&'a LocalUser>,
|
||||||
pub search_term: Option<String>,
|
pub search_term: Option<String>,
|
||||||
pub saved_only: bool,
|
pub saved_only: Option<bool>,
|
||||||
pub liked_only: bool,
|
pub liked_only: Option<bool>,
|
||||||
pub disliked_only: bool,
|
pub disliked_only: Option<bool>,
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
pub max_depth: Option<i32>,
|
pub max_depth: Option<i32>,
|
||||||
|
@ -579,7 +570,7 @@ mod tests {
|
||||||
let read_comment_views_with_person = CommentQuery {
|
let read_comment_views_with_person = CommentQuery {
|
||||||
sort: (Some(CommentSortType::Old)),
|
sort: (Some(CommentSortType::Old)),
|
||||||
post_id: (Some(data.inserted_post.id)),
|
post_id: (Some(data.inserted_post.id)),
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: (Some(&data.timmy_local_user_view.local_user)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -631,8 +622,8 @@ mod tests {
|
||||||
CommentLike::like(pool, &comment_like_form).await?;
|
CommentLike::like(pool, &comment_like_form).await?;
|
||||||
|
|
||||||
let read_liked_comment_views = CommentQuery {
|
let read_liked_comment_views = CommentQuery {
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: Some(&data.timmy_local_user_view.local_user),
|
||||||
liked_only: (true),
|
liked_only: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -647,8 +638,8 @@ mod tests {
|
||||||
assert_length!(1, read_liked_comment_views);
|
assert_length!(1, read_liked_comment_views);
|
||||||
|
|
||||||
let read_disliked_comment_views: Vec<CommentView> = CommentQuery {
|
let read_disliked_comment_views: Vec<CommentView> = CommentQuery {
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: Some(&data.timmy_local_user_view.local_user),
|
||||||
disliked_only: (true),
|
disliked_only: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -742,7 +733,7 @@ mod tests {
|
||||||
// by default, user has all languages enabled and should see all comments
|
// by default, user has all languages enabled and should see all comments
|
||||||
// (except from blocked user)
|
// (except from blocked user)
|
||||||
let all_languages = CommentQuery {
|
let all_languages = CommentQuery {
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: (Some(&data.timmy_local_user_view.local_user)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -760,7 +751,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let finnish_comments = CommentQuery {
|
let finnish_comments = CommentQuery {
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: (Some(&data.timmy_local_user_view.local_user)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -786,7 +777,7 @@ mod tests {
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
let undetermined_comment = CommentQuery {
|
let undetermined_comment = CommentQuery {
|
||||||
local_user: (Some(&data.timmy_local_user_view)),
|
local_user: (Some(&data.timmy_local_user_view.local_user)),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -899,8 +890,8 @@ mod tests {
|
||||||
|
|
||||||
// Fetch the saved comments
|
// Fetch the saved comments
|
||||||
let comments = CommentQuery {
|
let comments = CommentQuery {
|
||||||
local_user: Some(&data.timmy_local_user_view),
|
local_user: Some(&data.timmy_local_user_view.local_user),
|
||||||
saved_only: true,
|
saved_only: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
@ -1078,7 +1069,7 @@ mod tests {
|
||||||
assert_eq!(0, unauthenticated_query.len());
|
assert_eq!(0, unauthenticated_query.len());
|
||||||
|
|
||||||
let authenticated_query = CommentQuery {
|
let authenticated_query = CommentQuery {
|
||||||
local_user: Some(&data.timmy_local_user_view),
|
local_user: Some(&data.timmy_local_user_view.local_user),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(pool)
|
.list(pool)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::structs::{LocalUserView, PaginationCursor, PostView};
|
use crate::structs::{PaginationCursor, PostView};
|
||||||
use diesel::{
|
use diesel::{
|
||||||
debug_query,
|
debug_query,
|
||||||
dsl::{exists, not, IntervalDsl},
|
dsl::{exists, not, IntervalDsl},
|
||||||
|
@ -18,10 +18,12 @@ use i_love_jesus::PaginatedQueryBuilder;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
aggregates::structs::{post_aggregates_keys as key, PostAggregates},
|
aggregates::structs::{post_aggregates_keys as key, PostAggregates},
|
||||||
aliases::creator_community_actions,
|
aliases::creator_community_actions,
|
||||||
|
impls::local_user::LocalUserOptionHelper,
|
||||||
newtypes::{CommunityId, LocalUserId, PersonId, PostId},
|
newtypes::{CommunityId, LocalUserId, PersonId, PostId},
|
||||||
schema::{
|
schema::{
|
||||||
community,
|
community,
|
||||||
community_actions,
|
community_actions,
|
||||||
|
image_details,
|
||||||
instance_actions,
|
instance_actions,
|
||||||
local_user,
|
local_user,
|
||||||
local_user_language,
|
local_user_language,
|
||||||
|
@ -31,7 +33,7 @@ use lemmy_db_schema::{
|
||||||
post_actions,
|
post_actions,
|
||||||
post_aggregates,
|
post_aggregates,
|
||||||
},
|
},
|
||||||
source::{community::CommunityFollower, site::Site},
|
source::{community::CommunityFollower, local_user::LocalUser, site::Site},
|
||||||
utils::{
|
utils::{
|
||||||
action_query,
|
action_query,
|
||||||
actions,
|
actions,
|
||||||
|
@ -41,6 +43,7 @@ use lemmy_db_schema::{
|
||||||
get_conn,
|
get_conn,
|
||||||
limit_and_offset,
|
limit_and_offset,
|
||||||
now,
|
now,
|
||||||
|
visible_communities_only,
|
||||||
Commented,
|
Commented,
|
||||||
DbConn,
|
DbConn,
|
||||||
DbPool,
|
DbPool,
|
||||||
|
@ -49,7 +52,6 @@ use lemmy_db_schema::{
|
||||||
ReadFn,
|
ReadFn,
|
||||||
ReverseTimestampKey,
|
ReverseTimestampKey,
|
||||||
},
|
},
|
||||||
CommunityVisibility,
|
|
||||||
ListingType,
|
ListingType,
|
||||||
SortType,
|
SortType,
|
||||||
};
|
};
|
||||||
|
@ -73,6 +75,7 @@ fn queries<'a>() -> Queries<
|
||||||
.inner_join(person::table)
|
.inner_join(person::table)
|
||||||
.inner_join(community::table)
|
.inner_join(community::table)
|
||||||
.inner_join(post::table)
|
.inner_join(post::table)
|
||||||
|
.left_join(image_details::table.on(post::thumbnail_url.eq(image_details::link.nullable())))
|
||||||
.left_join(actions(
|
.left_join(actions(
|
||||||
community_actions::table,
|
community_actions::table,
|
||||||
my_person_id,
|
my_person_id,
|
||||||
|
@ -102,6 +105,7 @@ fn queries<'a>() -> Queries<
|
||||||
post::all_columns,
|
post::all_columns,
|
||||||
person::all_columns,
|
person::all_columns,
|
||||||
community::all_columns,
|
community::all_columns,
|
||||||
|
image_details::all_columns.nullable(),
|
||||||
creator_community_actions
|
creator_community_actions
|
||||||
.field(community_actions::received_ban)
|
.field(community_actions::received_ban)
|
||||||
.nullable()
|
.nullable()
|
||||||
|
@ -165,10 +169,7 @@ fn queries<'a>() -> Queries<
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide posts in local only communities from unauthenticated users
|
query = visible_communities_only(my_person_id, query);
|
||||||
if my_person_id.is_none() {
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
|
||||||
|
|
||||||
Commented::new(query)
|
Commented::new(query)
|
||||||
.text("PostView::read")
|
.text("PostView::read")
|
||||||
|
@ -177,30 +178,29 @@ fn queries<'a>() -> Queries<
|
||||||
};
|
};
|
||||||
|
|
||||||
let list = move |mut conn: DbConn<'a>, (options, site): (PostQuery<'a>, &'a Site)| async move {
|
let list = move |mut conn: DbConn<'a>, (options, site): (PostQuery<'a>, &'a Site)| async move {
|
||||||
let my_person_id = options.local_user.map(|l| l.person.id);
|
|
||||||
let my_local_user_id = options.local_user.map(|l| l.local_user.id);
|
|
||||||
|
|
||||||
// The left join below will return None in this case
|
// The left join below will return None in this case
|
||||||
let local_user_id_join = my_local_user_id.unwrap_or(LocalUserId(-1));
|
let local_user_id_join = options
|
||||||
|
.local_user
|
||||||
|
.local_user_id()
|
||||||
|
.unwrap_or(LocalUserId(-1));
|
||||||
|
|
||||||
let mut query = all_joins(post_aggregates::table.into_boxed(), my_person_id);
|
let mut query = all_joins(
|
||||||
|
post_aggregates::table.into_boxed(),
|
||||||
|
options.local_user.person_id(),
|
||||||
|
);
|
||||||
|
|
||||||
// hide posts from deleted communities
|
// hide posts from deleted communities
|
||||||
query = query.filter(community::deleted.eq(false));
|
query = query.filter(community::deleted.eq(false));
|
||||||
|
|
||||||
// only show deleted posts to creator
|
// only show deleted posts to creator
|
||||||
if let Some(person_id) = my_person_id {
|
if let Some(person_id) = options.local_user.person_id() {
|
||||||
query = query.filter(post::deleted.eq(false).or(post::creator_id.eq(person_id)));
|
query = query.filter(post::deleted.eq(false).or(post::creator_id.eq(person_id)));
|
||||||
} else {
|
} else {
|
||||||
query = query.filter(post::deleted.eq(false));
|
query = query.filter(post::deleted.eq(false));
|
||||||
}
|
}
|
||||||
|
|
||||||
let is_admin = options
|
|
||||||
.local_user
|
|
||||||
.map(|l| l.local_user.admin)
|
|
||||||
.unwrap_or(false);
|
|
||||||
// only show removed posts to admin when viewing user profile
|
// only show removed posts to admin when viewing user profile
|
||||||
if !(options.creator_id.is_some() && is_admin) {
|
if !(options.creator_id.is_some() && options.local_user.is_admin()) {
|
||||||
query = query
|
query = query
|
||||||
.filter(community::removed.eq(false))
|
.filter(community::removed.eq(false))
|
||||||
.filter(post::removed.eq(false));
|
.filter(post::removed.eq(false));
|
||||||
|
@ -246,28 +246,18 @@ fn queries<'a>() -> Queries<
|
||||||
.filter(not(post::removed.or(post::deleted)));
|
.filter(not(post::removed.or(post::deleted)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a content warning, show nsfw content by default.
|
if !options.local_user.show_nsfw(site) {
|
||||||
let has_content_warning = site.content_warning.is_some();
|
|
||||||
if !options
|
|
||||||
.local_user
|
|
||||||
.map(|l| l.local_user.show_nsfw)
|
|
||||||
.unwrap_or(has_content_warning)
|
|
||||||
{
|
|
||||||
query = query
|
query = query
|
||||||
.filter(post::nsfw.eq(false))
|
.filter(post::nsfw.eq(false))
|
||||||
.filter(community::nsfw.eq(false));
|
.filter(community::nsfw.eq(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
if !options
|
if !options.local_user.show_bot_accounts() {
|
||||||
.local_user
|
|
||||||
.map(|l| l.local_user.show_bot_accounts)
|
|
||||||
.unwrap_or(true)
|
|
||||||
{
|
|
||||||
query = query.filter(person::bot_account.eq(false));
|
query = query.filter(person::bot_account.eq(false));
|
||||||
};
|
};
|
||||||
|
|
||||||
// If its saved only, then filter, and order by the saved time, not the comment creation time.
|
// If its saved only, then filter, and order by the saved time, not the comment creation time.
|
||||||
if options.saved_only {
|
if options.saved_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(post_actions::saved.is_not_null())
|
.filter(post_actions::saved.is_not_null())
|
||||||
.then_order_by(post_actions::saved.desc());
|
.then_order_by(post_actions::saved.desc());
|
||||||
|
@ -275,9 +265,8 @@ fn queries<'a>() -> Queries<
|
||||||
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
|
// Only hide the read posts, if the saved_only is false. Otherwise ppl with the hide_read
|
||||||
// setting wont be able to see saved posts.
|
// setting wont be able to see saved posts.
|
||||||
else if !options
|
else if !options
|
||||||
.local_user
|
.show_read
|
||||||
.map(|l| l.local_user.show_read_posts)
|
.unwrap_or(options.local_user.show_read_posts())
|
||||||
.unwrap_or(true)
|
|
||||||
{
|
{
|
||||||
// Do not hide read posts when it is a user profile view
|
// Do not hide read posts when it is a user profile view
|
||||||
// Or, only hide read posts on non-profile views
|
// Or, only hide read posts on non-profile views
|
||||||
|
@ -287,32 +276,29 @@ fn queries<'a>() -> Queries<
|
||||||
}
|
}
|
||||||
|
|
||||||
// If a creator id isn't given (IE its on home or community pages), hide the hidden posts
|
// If a creator id isn't given (IE its on home or community pages), hide the hidden posts
|
||||||
if !options.show_hidden && options.creator_id.is_none() {
|
if !options.show_hidden.unwrap_or_default() && options.creator_id.is_none() {
|
||||||
query = query.filter(post_actions::hidden.is_null());
|
query = query.filter(post_actions::hidden.is_null());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(my_id) = my_person_id {
|
if let Some(my_id) = options.local_user.person_id() {
|
||||||
let not_creator_filter = post_aggregates::creator_id.ne(my_id);
|
let not_creator_filter = post_aggregates::creator_id.ne(my_id);
|
||||||
if options.liked_only {
|
if options.liked_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(not_creator_filter)
|
.filter(not_creator_filter)
|
||||||
.filter(post_actions::like_score.eq(1));
|
.filter(post_actions::like_score.eq(1));
|
||||||
} else if options.disliked_only {
|
} else if options.disliked_only.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.filter(not_creator_filter)
|
.filter(not_creator_filter)
|
||||||
.filter(post_actions::like_score.eq(-1));
|
.filter(post_actions::like_score.eq(-1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Hide posts in local only communities from unauthenticated users
|
query = visible_communities_only(options.local_user.person_id(), query);
|
||||||
if options.local_user.is_none() {
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dont filter blocks or missing languages for moderator view type
|
// Dont filter blocks or missing languages for moderator view type
|
||||||
if options.listing_type.unwrap_or_default() != ListingType::ModeratorView {
|
if options.listing_type.unwrap_or_default() != ListingType::ModeratorView {
|
||||||
// Filter out the rows with missing languages if user is logged in
|
// Filter out the rows with missing languages if user is logged in
|
||||||
if my_person_id.is_some() {
|
if options.local_user.is_some() {
|
||||||
query = query.filter(exists(
|
query = query.filter(exists(
|
||||||
local_user_language::table.filter(
|
local_user_language::table.filter(
|
||||||
post::language_id
|
post::language_id
|
||||||
|
@ -336,7 +322,7 @@ fn queries<'a>() -> Queries<
|
||||||
let page_after = options.page_after.map(|c| c.0);
|
let page_after = options.page_after.map(|c| c.0);
|
||||||
let page_before_or_equal = options.page_before_or_equal.map(|c| c.0);
|
let page_before_or_equal = options.page_before_or_equal.map(|c| c.0);
|
||||||
|
|
||||||
if options.page_back {
|
if options.page_back.unwrap_or_default() {
|
||||||
query = query
|
query = query
|
||||||
.before(page_after)
|
.before(page_after)
|
||||||
.after_or_equal(page_before_or_equal)
|
.after_or_equal(page_before_or_equal)
|
||||||
|
@ -461,18 +447,19 @@ pub struct PostQuery<'a> {
|
||||||
// if true, the query should be handled as if community_id was not given except adding the
|
// if true, the query should be handled as if community_id was not given except adding the
|
||||||
// literal filter
|
// literal filter
|
||||||
pub community_id_just_for_prefetch: bool,
|
pub community_id_just_for_prefetch: bool,
|
||||||
pub local_user: Option<&'a LocalUserView>,
|
pub local_user: Option<&'a LocalUser>,
|
||||||
pub search_term: Option<String>,
|
pub search_term: Option<String>,
|
||||||
pub url_search: Option<String>,
|
pub url_search: Option<String>,
|
||||||
pub saved_only: bool,
|
pub saved_only: Option<bool>,
|
||||||
pub liked_only: bool,
|
pub liked_only: Option<bool>,
|
||||||
pub disliked_only: bool,
|
pub disliked_only: Option<bool>,
|
||||||
pub page: Option<i64>,
|
pub page: Option<i64>,
|
||||||
pub limit: Option<i64>,
|
pub limit: Option<i64>,
|
||||||
pub page_after: Option<PaginationCursorData>,
|
pub page_after: Option<PaginationCursorData>,
|
||||||
pub page_before_or_equal: Option<PaginationCursorData>,
|
pub page_before_or_equal: Option<PaginationCursorData>,
|
||||||
pub page_back: bool,
|
pub page_back: Option<bool>,
|
||||||
pub show_hidden: bool,
|
pub show_hidden: Option<bool>,
|
||||||
|
pub show_read: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> PostQuery<'a> {
|
impl<'a> PostQuery<'a> {
|
||||||
|
@ -503,11 +490,7 @@ impl<'a> PostQuery<'a> {
|
||||||
"legacy pagination cannot be combined with v2 pagination".into(),
|
"legacy pagination cannot be combined with v2 pagination".into(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
let self_person_id = self
|
let self_person_id = self.local_user.expect("part of the above if").person_id;
|
||||||
.local_user
|
|
||||||
.expect("part of the above if")
|
|
||||||
.local_user
|
|
||||||
.person_id;
|
|
||||||
let largest_subscribed = {
|
let largest_subscribed = {
|
||||||
let conn = &mut get_conn(pool).await?;
|
let conn = &mut get_conn(pool).await?;
|
||||||
action_query(community_actions::followed)
|
action_query(community_actions::followed)
|
||||||
|
@ -544,7 +527,7 @@ impl<'a> PostQuery<'a> {
|
||||||
if (v.len() as i64) < limit {
|
if (v.len() as i64) < limit {
|
||||||
Ok(Some(self.clone()))
|
Ok(Some(self.clone()))
|
||||||
} else {
|
} else {
|
||||||
let item = if self.page_back {
|
let item = if self.page_back.unwrap_or_default() {
|
||||||
// for backward pagination, get first element instead
|
// for backward pagination, get first element instead
|
||||||
v.into_iter().next()
|
v.into_iter().next()
|
||||||
} else {
|
} else {
|
||||||
|
@ -647,7 +630,7 @@ mod tests {
|
||||||
fn default_post_query(&self) -> PostQuery<'_> {
|
fn default_post_query(&self) -> PostQuery<'_> {
|
||||||
PostQuery {
|
PostQuery {
|
||||||
sort: Some(SortType::New),
|
sort: Some(SortType::New),
|
||||||
local_user: Some(&self.local_user_view),
|
local_user: Some(&self.local_user_view.local_user),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -983,7 +966,7 @@ mod tests {
|
||||||
// Read the liked only
|
// Read the liked only
|
||||||
let read_liked_post_listing = PostQuery {
|
let read_liked_post_listing = PostQuery {
|
||||||
community_id: Some(data.inserted_community.id),
|
community_id: Some(data.inserted_community.id),
|
||||||
liked_only: true,
|
liked_only: Some(true),
|
||||||
..data.default_post_query()
|
..data.default_post_query()
|
||||||
}
|
}
|
||||||
.list(&data.site, pool)
|
.list(&data.site, pool)
|
||||||
|
@ -994,7 +977,7 @@ mod tests {
|
||||||
|
|
||||||
let read_disliked_post_listing = PostQuery {
|
let read_disliked_post_listing = PostQuery {
|
||||||
community_id: Some(data.inserted_community.id),
|
community_id: Some(data.inserted_community.id),
|
||||||
disliked_only: true,
|
disliked_only: Some(true),
|
||||||
..data.default_post_query()
|
..data.default_post_query()
|
||||||
}
|
}
|
||||||
.list(&data.site, pool)
|
.list(&data.site, pool)
|
||||||
|
@ -1164,8 +1147,8 @@ mod tests {
|
||||||
// Deleted post is only shown to creator
|
// Deleted post is only shown to creator
|
||||||
for (local_user, expect_contains_deleted) in [
|
for (local_user, expect_contains_deleted) in [
|
||||||
(None, false),
|
(None, false),
|
||||||
(Some(&data.blocked_local_user_view), false),
|
(Some(&data.blocked_local_user_view.local_user), false),
|
||||||
(Some(&data.local_user_view), true),
|
(Some(&data.local_user_view.local_user), true),
|
||||||
] {
|
] {
|
||||||
let contains_deleted = PostQuery {
|
let contains_deleted = PostQuery {
|
||||||
local_user,
|
local_user,
|
||||||
|
@ -1320,7 +1303,7 @@ mod tests {
|
||||||
loop {
|
loop {
|
||||||
let post_listings = PostQuery {
|
let post_listings = PostQuery {
|
||||||
page_after: page_before,
|
page_after: page_before,
|
||||||
page_back: true,
|
page_back: Some(true),
|
||||||
..options.clone()
|
..options.clone()
|
||||||
}
|
}
|
||||||
.list(&data.site, pool)
|
.list(&data.site, pool)
|
||||||
|
@ -1378,6 +1361,26 @@ mod tests {
|
||||||
let post_listings_hide_read = data.default_post_query().list(&data.site, pool).await?;
|
let post_listings_hide_read = data.default_post_query().list(&data.site, pool).await?;
|
||||||
assert_eq!(vec![POST], names(&post_listings_hide_read));
|
assert_eq!(vec![POST], names(&post_listings_hide_read));
|
||||||
|
|
||||||
|
// Test with the show_read override as true
|
||||||
|
let post_listings_show_read_true = PostQuery {
|
||||||
|
show_read: Some(true),
|
||||||
|
..data.default_post_query()
|
||||||
|
}
|
||||||
|
.list(&data.site, pool)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(
|
||||||
|
vec![POST_BY_BOT, POST],
|
||||||
|
names(&post_listings_show_read_true)
|
||||||
|
);
|
||||||
|
|
||||||
|
// Test with the show_read override as false
|
||||||
|
let post_listings_show_read_false = PostQuery {
|
||||||
|
show_read: Some(false),
|
||||||
|
..data.default_post_query()
|
||||||
|
}
|
||||||
|
.list(&data.site, pool)
|
||||||
|
.await?;
|
||||||
|
assert_eq!(vec![POST], names(&post_listings_show_read_false));
|
||||||
cleanup(data, pool).await
|
cleanup(data, pool).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1403,8 +1406,8 @@ mod tests {
|
||||||
// Make sure it does come back with the show_hidden option
|
// Make sure it does come back with the show_hidden option
|
||||||
let post_listings_show_hidden = PostQuery {
|
let post_listings_show_hidden = PostQuery {
|
||||||
sort: Some(SortType::New),
|
sort: Some(SortType::New),
|
||||||
local_user: Some(&data.local_user_view),
|
local_user: Some(&data.local_user_view.local_user),
|
||||||
show_hidden: true,
|
show_hidden: Some(true),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&data.site, pool)
|
.list(&data.site, pool)
|
||||||
|
@ -1495,6 +1498,7 @@ mod tests {
|
||||||
public_key: inserted_person.public_key.clone(),
|
public_key: inserted_person.public_key.clone(),
|
||||||
last_refreshed_at: inserted_person.last_refreshed_at,
|
last_refreshed_at: inserted_person.last_refreshed_at,
|
||||||
},
|
},
|
||||||
|
image_details: None,
|
||||||
creator_banned_from_community: false,
|
creator_banned_from_community: false,
|
||||||
banned_from_community: false,
|
banned_from_community: false,
|
||||||
creator_is_moderator: false,
|
creator_is_moderator: false,
|
||||||
|
@ -1578,7 +1582,7 @@ mod tests {
|
||||||
assert_eq!(0, unauthenticated_query.len());
|
assert_eq!(0, unauthenticated_query.len());
|
||||||
|
|
||||||
let authenticated_query = PostQuery {
|
let authenticated_query = PostQuery {
|
||||||
local_user: Some(&data.local_user_view),
|
local_user: Some(&data.local_user_view.local_user),
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}
|
}
|
||||||
.list(&data.site, pool)
|
.list(&data.site, pool)
|
||||||
|
|
|
@ -8,7 +8,7 @@ use lemmy_db_schema::{
|
||||||
community::Community,
|
community::Community,
|
||||||
custom_emoji::CustomEmoji,
|
custom_emoji::CustomEmoji,
|
||||||
custom_emoji_keyword::CustomEmojiKeyword,
|
custom_emoji_keyword::CustomEmojiKeyword,
|
||||||
images::LocalImage,
|
images::{ImageDetails, LocalImage},
|
||||||
local_site::LocalSite,
|
local_site::LocalSite,
|
||||||
local_site_rate_limit::LocalSiteRateLimit,
|
local_site_rate_limit::LocalSiteRateLimit,
|
||||||
local_user::LocalUser,
|
local_user::LocalUser,
|
||||||
|
@ -131,6 +131,7 @@ pub struct PostView {
|
||||||
pub post: Post,
|
pub post: Post,
|
||||||
pub creator: Person,
|
pub creator: Person,
|
||||||
pub community: Community,
|
pub community: Community,
|
||||||
|
pub image_details: Option<ImageDetails>,
|
||||||
pub creator_banned_from_community: bool,
|
pub creator_banned_from_community: bool,
|
||||||
pub banned_from_community: bool,
|
pub banned_from_community: bool,
|
||||||
pub creator_is_moderator: bool,
|
pub creator_is_moderator: bool,
|
||||||
|
|
|
@ -84,7 +84,7 @@ impl CommunityModeratorView {
|
||||||
.distinct_on(community_actions::community_id)
|
.distinct_on(community_actions::community_id)
|
||||||
.order_by((
|
.order_by((
|
||||||
community_actions::community_id,
|
community_actions::community_id,
|
||||||
community_actions::person_id,
|
community_actions::became_moderator,
|
||||||
))
|
))
|
||||||
.load::<CommunityModeratorView>(conn)
|
.load::<CommunityModeratorView>(conn)
|
||||||
.await
|
.await
|
||||||
|
|
|
@ -4,18 +4,27 @@ use diesel::{
|
||||||
result::Error,
|
result::Error,
|
||||||
BoolExpressionMethods,
|
BoolExpressionMethods,
|
||||||
ExpressionMethods,
|
ExpressionMethods,
|
||||||
JoinOnDsl,
|
|
||||||
NullableExpressionMethods,
|
NullableExpressionMethods,
|
||||||
PgTextExpressionMethods,
|
PgTextExpressionMethods,
|
||||||
QueryDsl,
|
QueryDsl,
|
||||||
};
|
};
|
||||||
use diesel_async::RunQueryDsl;
|
use diesel_async::RunQueryDsl;
|
||||||
use lemmy_db_schema::{
|
use lemmy_db_schema::{
|
||||||
|
impls::local_user::LocalUserOptionHelper,
|
||||||
newtypes::{CommunityId, PersonId},
|
newtypes::{CommunityId, PersonId},
|
||||||
schema::{community, community_actions, community_aggregates, instance_actions, local_user},
|
schema::{community, community_actions, community_aggregates, instance_actions},
|
||||||
source::{community::CommunityFollower, local_user::LocalUser, site::Site},
|
source::{community::CommunityFollower, local_user::LocalUser, site::Site},
|
||||||
utils::{actions, fuzzy_search, limit_and_offset, DbConn, DbPool, ListFn, Queries, ReadFn},
|
utils::{
|
||||||
CommunityVisibility,
|
actions,
|
||||||
|
fuzzy_search,
|
||||||
|
limit_and_offset,
|
||||||
|
visible_communities_only,
|
||||||
|
DbConn,
|
||||||
|
DbPool,
|
||||||
|
ListFn,
|
||||||
|
Queries,
|
||||||
|
ReadFn,
|
||||||
|
},
|
||||||
ListingType,
|
ListingType,
|
||||||
SortType,
|
SortType,
|
||||||
};
|
};
|
||||||
|
@ -68,10 +77,7 @@ fn queries<'a>() -> Queries<
|
||||||
query = query.filter(not_removed_or_deleted);
|
query = query.filter(not_removed_or_deleted);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide local only communities from unauthenticated users
|
query = visible_communities_only(my_person_id, query);
|
||||||
if my_person_id.is_none() {
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
|
||||||
|
|
||||||
query.first(&mut conn).await
|
query.first(&mut conn).await
|
||||||
};
|
};
|
||||||
|
@ -79,14 +85,11 @@ fn queries<'a>() -> Queries<
|
||||||
let list = move |mut conn: DbConn<'a>, (options, site): (CommunityQuery<'a>, &'a Site)| async move {
|
let list = move |mut conn: DbConn<'a>, (options, site): (CommunityQuery<'a>, &'a Site)| async move {
|
||||||
use SortType::*;
|
use SortType::*;
|
||||||
|
|
||||||
let my_person_id = options.local_user.map(|l| l.person_id);
|
let mut query = all_joins(
|
||||||
|
community::table.into_boxed(),
|
||||||
// The left join below will return None in this case
|
options.local_user.person_id(),
|
||||||
let person_id_join = my_person_id.unwrap_or(PersonId(-1));
|
)
|
||||||
|
.select(selection);
|
||||||
let mut query = all_joins(community::table.into_boxed(), my_person_id)
|
|
||||||
.left_join(local_user::table.on(local_user::person_id.eq(person_id_join)))
|
|
||||||
.select(selection);
|
|
||||||
|
|
||||||
if let Some(search_term) = options.search_term {
|
if let Some(search_term) = options.search_term {
|
||||||
let searcher = fuzzy_search(&search_term);
|
let searcher = fuzzy_search(&search_term);
|
||||||
|
@ -133,21 +136,14 @@ fn queries<'a>() -> Queries<
|
||||||
|
|
||||||
// Don't show blocked communities and communities on blocked instances. nsfw communities are
|
// Don't show blocked communities and communities on blocked instances. nsfw communities are
|
||||||
// also hidden (based on profile setting)
|
// also hidden (based on profile setting)
|
||||||
if options.local_user.is_some() {
|
query = query.filter(instance_actions::blocked.is_null());
|
||||||
query = query.filter(instance_actions::blocked.is_null());
|
query = query.filter(community_actions::blocked.is_null());
|
||||||
query = query.filter(community_actions::blocked.is_null());
|
if !(options.local_user.show_nsfw(site) || options.show_nsfw) {
|
||||||
query = query.filter(community::nsfw.eq(false).or(local_user::show_nsfw.eq(true)));
|
query = query.filter(community::nsfw.eq(false));
|
||||||
} else {
|
|
||||||
// No person in request, only show nsfw communities if show_nsfw is passed into request or if
|
|
||||||
// site has content warning.
|
|
||||||
let has_content_warning = site.content_warning.is_some();
|
|
||||||
if !options.show_nsfw && !has_content_warning {
|
|
||||||
query = query.filter(community::nsfw.eq(false));
|
|
||||||
}
|
|
||||||
// Hide local only communities from unauthenticated users
|
|
||||||
query = query.filter(community::visibility.eq(CommunityVisibility::Public));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
query = visible_communities_only(options.local_user.person_id(), query);
|
||||||
|
|
||||||
let (limit, offset) = limit_and_offset(options.page, options.limit)?;
|
let (limit, offset) = limit_and_offset(options.page, options.limit)?;
|
||||||
query
|
query
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|
|
@ -167,6 +167,14 @@ impl InstanceWorker {
|
||||||
latest_id
|
latest_id
|
||||||
};
|
};
|
||||||
if id >= latest_id {
|
if id >= latest_id {
|
||||||
|
if id > latest_id {
|
||||||
|
tracing::error!(
|
||||||
|
"{}: last successful id {} is higher than latest id {} in database (did the db get cleared?)",
|
||||||
|
self.instance.domain,
|
||||||
|
id.0,
|
||||||
|
latest_id.0
|
||||||
|
);
|
||||||
|
}
|
||||||
// no more work to be done, wait before rechecking
|
// no more work to be done, wait before rechecking
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
() = sleep(*WORK_FINISHED_RECHECK_DELAY) => {},
|
() = sleep(*WORK_FINISHED_RECHECK_DELAY) => {},
|
||||||
|
|
|
@ -355,7 +355,7 @@ async fn get_feed_front(
|
||||||
|
|
||||||
let posts = PostQuery {
|
let posts = PostQuery {
|
||||||
listing_type: (Some(ListingType::Subscribed)),
|
listing_type: (Some(ListingType::Subscribed)),
|
||||||
local_user: (Some(&local_user)),
|
local_user: (Some(&local_user.local_user)),
|
||||||
sort: (Some(*sort_type)),
|
sort: (Some(*sort_type)),
|
||||||
limit: (Some(*limit)),
|
limit: (Some(*limit)),
|
||||||
page: (Some(*page)),
|
page: (Some(*page)),
|
||||||
|
|
|
@ -103,7 +103,13 @@ async fn upload(
|
||||||
pictrs_alias: image.file.to_string(),
|
pictrs_alias: image.file.to_string(),
|
||||||
pictrs_delete_token: image.delete_token.to_string(),
|
pictrs_delete_token: image.delete_token.to_string(),
|
||||||
};
|
};
|
||||||
LocalImage::create(&mut context.pool(), &form).await?;
|
|
||||||
|
let protocol_and_hostname = context.settings().get_protocol_and_hostname();
|
||||||
|
let thumbnail_url = image.thumbnail_url(&protocol_and_hostname)?;
|
||||||
|
|
||||||
|
// Also store the details for the image
|
||||||
|
let details_form = image.details.build_image_details_form(&thumbnail_url);
|
||||||
|
LocalImage::create(&mut context.pool(), &form, &details_form).await?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,10 @@ static VALID_MATRIX_ID_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||||
});
|
});
|
||||||
// taken from https://en.wikipedia.org/wiki/UTM_parameters
|
// taken from https://en.wikipedia.org/wiki/UTM_parameters
|
||||||
static CLEAN_URL_PARAMS_REGEX: Lazy<Regex> = Lazy::new(|| {
|
static CLEAN_URL_PARAMS_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||||
Regex::new(r"^utm_source|utm_medium|utm_campaign|utm_term|utm_content|gclid|gclsrc|dclid|fbclid$")
|
Regex::new(
|
||||||
.expect("compile regex")
|
r"^(utm_source|utm_medium|utm_campaign|utm_term|utm_content|gclid|gclsrc|dclid|fbclid)=",
|
||||||
|
)
|
||||||
|
.expect("compile regex")
|
||||||
});
|
});
|
||||||
const ALLOWED_POST_URL_SCHEMES: [&str; 3] = ["http", "https", "magnet"];
|
const ALLOWED_POST_URL_SCHEMES: [&str; 3] = ["http", "https", "magnet"];
|
||||||
|
|
||||||
|
@ -256,12 +258,11 @@ pub fn build_and_check_regex(regex_str_opt: &Option<&str>) -> LemmyResult<Option
|
||||||
|
|
||||||
pub fn clean_url_params(url: &Url) -> Url {
|
pub fn clean_url_params(url: &Url) -> Url {
|
||||||
let mut url_out = url.clone();
|
let mut url_out = url.clone();
|
||||||
if url.query().is_some() {
|
if let Some(query) = url.query() {
|
||||||
let new_query = url
|
let new_query = query
|
||||||
.query_pairs()
|
.split_inclusive('&')
|
||||||
.filter(|q| !CLEAN_URL_PARAMS_REGEX.is_match(&q.0))
|
.filter(|q| !CLEAN_URL_PARAMS_REGEX.is_match(q))
|
||||||
.map(|q| format!("{}={}", q.0, q.1))
|
.collect::<String>();
|
||||||
.join("&");
|
|
||||||
url_out.set_query(Some(&new_query));
|
url_out.set_query(Some(&new_query));
|
||||||
}
|
}
|
||||||
url_out
|
url_out
|
||||||
|
@ -369,9 +370,9 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_clean_url_params() -> LemmyResult<()> {
|
fn test_clean_url_params() -> LemmyResult<()> {
|
||||||
let url = Url::parse("https://example.com/path/123?utm_content=buffercf3b2&utm_medium=social&username=randomuser&id=123")?;
|
let url = Url::parse("https://example.com/path/123?utm_content=buffercf3b2&utm_medium=social&user+name=random+user%20&id=123")?;
|
||||||
let cleaned = clean_url_params(&url);
|
let cleaned = clean_url_params(&url);
|
||||||
let expected = Url::parse("https://example.com/path/123?username=randomuser&id=123")?;
|
let expected = Url::parse("https://example.com/path/123?user+name=random+user%20&id=123")?;
|
||||||
assert_eq!(expected.to_string(), cleaned.to_string());
|
assert_eq!(expected.to_string(), cleaned.to_string());
|
||||||
|
|
||||||
let url = Url::parse("https://example.com/path/123")?;
|
let url = Url::parse("https://example.com/path/123")?;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit b3bdd9cf78a234438dcc7ccb904739280eda5915
|
Subproject commit ee2cffac809ad466644f061ad79ac577b6c2e4fd
|
|
@ -1,4 +1,4 @@
|
||||||
# syntax=docker/dockerfile:1.7
|
# syntax=docker/dockerfile:1.8
|
||||||
ARG RUST_VERSION=1.78
|
ARG RUST_VERSION=1.78
|
||||||
ARG CARGO_BUILD_FEATURES=default
|
ARG CARGO_BUILD_FEATURES=default
|
||||||
ARG RUST_RELEASE_MODE=debug
|
ARG RUST_RELEASE_MODE=debug
|
||||||
|
|
|
@ -23,7 +23,7 @@ services:
|
||||||
|
|
||||||
lemmy:
|
lemmy:
|
||||||
# use "image" to pull down an already compiled lemmy. make sure to comment out "build".
|
# use "image" to pull down an already compiled lemmy. make sure to comment out "build".
|
||||||
# image: dessalines/lemmy:0.19.4
|
# image: dessalines/lemmy:0.19.5
|
||||||
# platform: linux/x86_64 # no arm64 support. uncomment platform if using m1.
|
# platform: linux/x86_64 # no arm64 support. uncomment platform if using m1.
|
||||||
# use "build" to build your local lemmy server image for development. make sure to comment out "image".
|
# use "build" to build your local lemmy server image for development. make sure to comment out "image".
|
||||||
# run: docker compose up --build
|
# run: docker compose up --build
|
||||||
|
@ -53,7 +53,7 @@ services:
|
||||||
|
|
||||||
lemmy-ui:
|
lemmy-ui:
|
||||||
# use "image" to pull down an already compiled lemmy-ui. make sure to comment out "build".
|
# use "image" to pull down an already compiled lemmy-ui. make sure to comment out "build".
|
||||||
image: dessalines/lemmy-ui:0.19.4
|
image: dessalines/lemmy-ui:0.19.5
|
||||||
# platform: linux/x86_64 # no arm64 support. uncomment platform if using m1.
|
# platform: linux/x86_64 # no arm64 support. uncomment platform if using m1.
|
||||||
# use "build" to build your local lemmy ui image for development. make sure to comment out "image".
|
# use "build" to build your local lemmy ui image for development. make sure to comment out "image".
|
||||||
# run: docker compose up --build
|
# run: docker compose up --build
|
||||||
|
@ -75,7 +75,7 @@ services:
|
||||||
init: true
|
init: true
|
||||||
|
|
||||||
pictrs:
|
pictrs:
|
||||||
image: asonix/pictrs:0.5.14
|
image: asonix/pictrs:0.5.16
|
||||||
# this needs to match the pictrs url in lemmy.hjson
|
# this needs to match the pictrs url in lemmy.hjson
|
||||||
hostname: pictrs
|
hostname: pictrs
|
||||||
# we can set options to pictrs like this, here we set max. image size and forced format for conversion
|
# we can set options to pictrs like this, here we set max. image size and forced format for conversion
|
||||||
|
|
|
@ -2,7 +2,7 @@ version: "3.7"
|
||||||
|
|
||||||
x-ui-default: &ui-default
|
x-ui-default: &ui-default
|
||||||
init: true
|
init: true
|
||||||
image: dessalines/lemmy-ui:0.19.4
|
image: dessalines/lemmy-ui:0.19.5
|
||||||
# assuming lemmy-ui is cloned besides lemmy directory
|
# assuming lemmy-ui is cloned besides lemmy directory
|
||||||
# build:
|
# build:
|
||||||
# context: ../../../lemmy-ui
|
# context: ../../../lemmy-ui
|
||||||
|
@ -49,7 +49,7 @@ services:
|
||||||
|
|
||||||
pictrs:
|
pictrs:
|
||||||
restart: always
|
restart: always
|
||||||
image: asonix/pictrs:0.5.14
|
image: asonix/pictrs:0.5.16
|
||||||
user: 991:991
|
user: 991:991
|
||||||
volumes:
|
volumes:
|
||||||
- ./volumes/pictrs_alpha:/mnt:Z
|
- ./volumes/pictrs_alpha:/mnt:Z
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
ALTER TABLE remote_image
|
||||||
|
ADD UNIQUE (link),
|
||||||
|
DROP CONSTRAINT remote_image_pkey,
|
||||||
|
ADD COLUMN id serial PRIMARY KEY;
|
||||||
|
|
||||||
|
DROP TABLE image_details;
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
-- Drop the id column from the remote_image table, just use link
|
||||||
|
ALTER TABLE remote_image
|
||||||
|
DROP COLUMN id,
|
||||||
|
ADD PRIMARY KEY (link),
|
||||||
|
DROP CONSTRAINT remote_image_link_key;
|
||||||
|
|
||||||
|
-- No good way to do references here unfortunately, unless we combine the images tables
|
||||||
|
-- The link should be the URL, not the pictrs_alias, to allow joining from post.thumbnail_url
|
||||||
|
CREATE TABLE image_details (
|
||||||
|
link text PRIMARY KEY,
|
||||||
|
width integer NOT NULL,
|
||||||
|
height integer NOT NULL,
|
||||||
|
content_type text NOT NULL
|
||||||
|
);
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
SELECT
|
||||||
|
;
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
-- Fix rows that were not updated because of the old incorrect trigger
|
||||||
|
UPDATE
|
||||||
|
post_aggregates
|
||||||
|
SET
|
||||||
|
featured_local = post.featured_local
|
||||||
|
FROM
|
||||||
|
post
|
||||||
|
WHERE
|
||||||
|
post.id = post_aggregates.post_id
|
||||||
|
AND post.featured_local != post_aggregates.featured_local;
|
||||||
|
|
Loading…
Reference in New Issue