aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock203
-rw-r--r--Cargo.toml1
-rw-r--r--common/Cargo.toml1
-rw-r--r--common/src/helpers.rs91
-rw-r--r--common/src/impl.rs18
-rw-r--r--common/src/lib.rs232
-rw-r--r--common/src/routes.rs4
-rw-r--r--common/src/user.rs15
-rw-r--r--database/Cargo.toml2
-rw-r--r--database/src/lib.rs65
-rw-r--r--import/asset_token/src/lib.rs5
-rw-r--r--import/src/lib.rs54
-rw-r--r--logic/src/assets.rs2
-rw-r--r--logic/src/filter_sort.rs20
-rw-r--r--logic/src/home.rs6
-rw-r--r--server/src/compat/jellyfin/mod.rs2
-rw-r--r--ui/src/node_page.rs8
-rw-r--r--ui/src/props.rs18
18 files changed, 321 insertions, 426 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 86c9521..5ac8357 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -148,22 +148,22 @@ dependencies = [
[[package]]
name = "anstyle-query"
-version = "1.1.4"
+version = "1.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e231f6134f61b71076a3eab506c379d4f36122f2af15a9ff04415ea4c3339e2"
+checksum = "40c48f72fd53cd289104fc64099abca73db4166ad86ea0b4341abe65af83dadc"
dependencies = [
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
name = "anstyle-wincon"
-version = "3.0.10"
+version = "3.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3e0633414522a32ffaac8ac6cc8f748e090c5717661fddeea04219e2344f5f2a"
+checksum = "291e6a250ff86cd4a820112fb8898808a366d8f9f58ce16d1f538353ad55747d"
dependencies = [
"anstyle",
"once_cell_polyfill",
- "windows-sys 0.60.2",
+ "windows-sys 0.61.2",
]
[[package]]
@@ -412,12 +412,6 @@ dependencies = [
[[package]]
name = "bitstream-io"
-version = "2.6.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6099cdc01846bc367c4e7dd630dc5966dccf36b652fae7a74e17b640411a91b2"
-
-[[package]]
-name = "bitstream-io"
version = "4.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60d4bd9d1db2c6bdf285e223a7fa369d5ce98ec767dec949c6ca62863ce61757"
@@ -483,12 +477,6 @@ dependencies = [
[[package]]
name = "built"
-version = "0.7.7"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56ed6191a7e78c36abdb16ab65341eefd73d64d303fffccdbb00d51e4205967b"
-
-[[package]]
-name = "built"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64"
@@ -519,15 +507,15 @@ checksum = "8f1fe948ff07f4bd06c30984e69f5b4899c516a3ef74f34df92a2df2ab535495"
[[package]]
name = "bytes"
-version = "1.10.1"
+version = "1.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
+checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3"
[[package]]
name = "cc"
-version = "1.2.45"
+version = "1.2.46"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "35900b6c8d709fb1d854671ae27aeaa9eec2f8b01b364e1619a40da3e6fe2afe"
+checksum = "b97463e1064cb1b1c1384ad0a0b9c8abd0988e2a91f52606c80ef14aadb63e36"
dependencies = [
"find-msvc-tools",
"jobserver",
@@ -542,16 +530,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f4c707c6a209cbe82d10abd08e1ea8995e9ea937d2550646e02798948992be0"
[[package]]
-name = "cfg-expr"
-version = "0.15.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d067ad48b8650848b989a59a86c6c36a995d02d2bf778d45c3c5d57bc2718f02"
-dependencies = [
- "smallvec 1.15.1",
- "target-lexicon",
-]
-
-[[package]]
name = "cfg-if"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -778,9 +756,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "crypto-common"
-version = "0.1.6"
+version = "0.1.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
+checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a"
dependencies = [
"generic-array",
"rand_core 0.6.4",
@@ -924,7 +902,7 @@ checksum = "117240f60069e65410b3ae1bb213295bd828f707b5bec6596a1afc8793ce0cbc"
[[package]]
name = "ebml"
version = "0.1.0"
-source = "git+https://codeberg.org/metamuffin/ebml-rs#d5b998e076331172adf2a6cfd4043f5219fc8143"
+source = "git+https://codeberg.org/metamuffin/ebml-rs#b93e9c26f3b465cd747d28a7ade6f5617bcf3f44"
dependencies = [
"ebml-derive",
]
@@ -932,7 +910,7 @@ dependencies = [
[[package]]
name = "ebml-derive"
version = "0.1.0"
-source = "git+https://codeberg.org/metamuffin/ebml-rs#d5b998e076331172adf2a6cfd4043f5219fc8143"
+source = "git+https://codeberg.org/metamuffin/ebml-rs#b93e9c26f3b465cd747d28a7ade6f5617bcf3f44"
dependencies = [
"darling",
"quote",
@@ -1099,9 +1077,9 @@ dependencies = [
[[package]]
name = "find-msvc-tools"
-version = "0.1.4"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
+checksum = "3a3076410a55c90011c298b04d0cfa770b00fa04e1e3c97d3f6c9de105a03844"
[[package]]
name = "flate2"
@@ -1263,9 +1241,9 @@ dependencies = [
[[package]]
name = "generic-array"
-version = "0.14.9"
+version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2"
+checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
dependencies = [
"typenum",
"version_check",
@@ -1310,9 +1288,9 @@ dependencies = [
[[package]]
name = "gif"
-version = "0.13.3"
+version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b"
+checksum = "f954a9e9159ec994f73a30a12b96a702dde78f5547bcb561174597924f7d4162"
dependencies = [
"color_quant",
"weezl",
@@ -1516,9 +1494,9 @@ dependencies = [
[[package]]
name = "hyper"
-version = "1.7.0"
+version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e"
+checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11"
dependencies = [
"atomic-waker",
"bytes",
@@ -1542,7 +1520,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58"
dependencies = [
"http 1.3.1",
- "hyper 1.7.0",
+ "hyper 1.8.1",
"hyper-util",
"rustls",
"rustls-pki-types",
@@ -1554,9 +1532,9 @@ dependencies = [
[[package]]
name = "hyper-util"
-version = "0.1.17"
+version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8"
+checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56"
dependencies = [
"base64",
"bytes",
@@ -1565,7 +1543,7 @@ dependencies = [
"futures-util",
"http 1.3.1",
"http-body 1.0.1",
- "hyper 1.7.0",
+ "hyper 1.8.1",
"ipnet",
"libc",
"percent-encoding",
@@ -1719,9 +1697,9 @@ dependencies = [
[[package]]
name = "image"
-version = "0.25.8"
+version = "0.25.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "529feb3e6769d234375c4cf1ee2ce713682b8e76538cb13f9fc23e1400a591e7"
+checksum = "e6506c6c10786659413faa717ceebcb8f70731c0a60cbae39795fdf114519c1a"
dependencies = [
"bytemuck",
"byteorder-lite",
@@ -1733,12 +1711,12 @@ dependencies = [
"num-traits",
"png",
"qoi",
- "ravif 0.11.20",
+ "ravif",
"rayon",
"rgb",
"tiff",
- "zune-core",
- "zune-jpeg",
+ "zune-core 0.5.0",
+ "zune-jpeg 0.5.5",
]
[[package]]
@@ -1902,7 +1880,6 @@ dependencies = [
name = "jellycommon"
version = "0.1.0"
dependencies = [
- "bincode",
"blake3",
"chrono",
"hex",
@@ -1915,11 +1892,11 @@ name = "jellydb"
version = "0.1.0"
dependencies = [
"anyhow",
- "bincode",
"jellycommon",
"log",
"redb",
"serde",
+ "serde_json",
"tantivy",
]
@@ -2104,8 +2081,8 @@ dependencies = [
"libavif-image",
"log",
"matroska",
- "rav1e 0.8.1",
- "ravif 0.12.0",
+ "rav1e",
+ "ravif",
"rayon",
"rgb",
"serde",
@@ -2371,7 +2348,7 @@ dependencies = [
[[package]]
name = "matroska"
version = "0.1.0"
-source = "git+https://codeberg.org/metamuffin/ebml-rs#d5b998e076331172adf2a6cfd4043f5219fc8143"
+source = "git+https://codeberg.org/metamuffin/ebml-rs#b93e9c26f3b465cd747d28a7ade6f5617bcf3f44"
dependencies = [
"ebml",
"serde",
@@ -3125,41 +3102,6 @@ dependencies = [
[[package]]
name = "rav1e"
-version = "0.7.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cd87ce80a7665b1cce111f8a16c1f3929f6547ce91ade6addf4ec86a8dda5ce9"
-dependencies = [
- "arbitrary",
- "arg_enum_proc_macro",
- "arrayvec",
- "av1-grain",
- "bitstream-io 2.6.0",
- "built 0.7.7",
- "cfg-if",
- "interpolate_name",
- "itertools 0.12.1",
- "libc",
- "libfuzzer-sys",
- "log",
- "maybe-rayon",
- "new_debug_unreachable",
- "noop_proc_macro",
- "num-derive",
- "num-traits",
- "once_cell",
- "paste",
- "profiling",
- "rand 0.8.5",
- "rand_chacha 0.3.1",
- "simd_helpers",
- "system-deps",
- "thiserror 1.0.69",
- "v_frame",
- "wasm-bindgen",
-]
-
-[[package]]
-name = "rav1e"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43b6dd56e85d9483277cde964fd1bdb0428de4fec5ebba7540995639a21cb32b"
@@ -3170,8 +3112,8 @@ dependencies = [
"arrayvec",
"av-scenechange",
"av1-grain",
- "bitstream-io 4.9.0",
- "built 0.8.0",
+ "bitstream-io",
+ "built",
"cc",
"cfg-if",
"interpolate_name",
@@ -3197,21 +3139,6 @@ dependencies = [
[[package]]
name = "ravif"
-version = "0.11.20"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b"
-dependencies = [
- "avif-serialize",
- "imgref",
- "loop9",
- "quick-error",
- "rav1e 0.7.1",
- "rayon",
- "rgb",
-]
-
-[[package]]
-name = "ravif"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef69c1990ceef18a116855938e74793a5f7496ee907562bd0857b6ac734ab285"
@@ -3220,7 +3147,7 @@ dependencies = [
"imgref",
"loop9",
"quick-error",
- "rav1e 0.8.1",
+ "rav1e",
"rayon",
"rgb",
]
@@ -3341,7 +3268,7 @@ dependencies = [
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
- "hyper 1.7.0",
+ "hyper 1.8.1",
"hyper-rustls",
"hyper-util",
"js-sys",
@@ -3875,19 +3802,6 @@ dependencies = [
]
[[package]]
-name = "system-deps"
-version = "6.2.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a3e535eb8dded36d55ec13eddacd30dec501792ff23a0b1682c38601b8cf2349"
-dependencies = [
- "cfg-expr",
- "heck",
- "pkg-config",
- "toml",
- "version-compare",
-]
-
-[[package]]
name = "tantivy"
version = "0.25.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4034,12 +3948,6 @@ dependencies = [
]
[[package]]
-name = "target-lexicon"
-version = "0.12.16"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
-
-[[package]]
name = "tempfile"
version = "3.23.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4112,7 +4020,7 @@ dependencies = [
"half",
"quick-error",
"weezl",
- "zune-jpeg",
+ "zune-jpeg 0.4.21",
]
[[package]]
@@ -4468,9 +4376,9 @@ checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
[[package]]
name = "unit-prefix"
-version = "0.5.1"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "323402cff2dd658f39ca17c789b502021b3f18707c91cdf22e3838e1b4023817"
+checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3"
[[package]]
name = "universal-hash"
@@ -4572,12 +4480,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
[[package]]
-name = "version-compare"
-version = "0.2.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "03c2856837ef78f57382f06b2b8563a2f512f7185d732608fd9176cb3b8edf0e"
-
-[[package]]
name = "version_check"
version = "0.9.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -4712,9 +4614,9 @@ dependencies = [
[[package]]
name = "weezl"
-version = "0.1.11"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "009936b22a61d342859b5f0ea64681cbb35a358ab548e2a44a8cf0dac2d980b8"
+checksum = "a28ac98ddc8b9274cb41bb4d9d4d5c425b6020c50c46f25559911905610b4a88"
[[package]]
name = "wide"
@@ -5212,6 +5114,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
[[package]]
+name = "zune-core"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "111f7d9820f05fd715df3144e254d6fc02ee4088b0644c0ffd0efc9e6d9d2773"
+
+[[package]]
name = "zune-inflate"
version = "0.2.54"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5226,5 +5134,14 @@ version = "0.4.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "29ce2c8a9384ad323cf564b67da86e21d3cfdff87908bc1223ed5c99bc792713"
dependencies = [
- "zune-core",
+ "zune-core 0.4.12",
+]
+
+[[package]]
+name = "zune-jpeg"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dc6fb7703e32e9a07fb3f757360338b3a567a5054f21b5f52a666752e333d58e"
+dependencies = [
+ "zune-core 0.5.0",
]
diff --git a/Cargo.toml b/Cargo.toml
index 15923db..1922d6d 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -18,7 +18,6 @@ members = [
resolver = "3"
[workspace.dependencies]
-# rocket = { git = "https://github.com/SergioBenitez/Rocket", rev = "2cf38a5aa37fe046e46b03740835787f0396307b" }
rocket = "0.5"
rocket_ws = "0.1"
diff --git a/common/Cargo.toml b/common/Cargo.toml
index cbe940b..37e9c6c 100644
--- a/common/Cargo.toml
+++ b/common/Cargo.toml
@@ -5,7 +5,6 @@ edition = "2021"
[dependencies]
serde = { version = "1.0.228", features = ["derive", "rc"] }
-bincode = { version = "2.0.1", features = ["derive"] }
chrono = { version = "0.4.42", features = ["serde"] }
blake3 = "1.8.2"
hex = "0.4.3"
diff --git a/common/src/helpers.rs b/common/src/helpers.rs
index 18b8e2b..44e9468 100644
--- a/common/src/helpers.rs
+++ b/common/src/helpers.rs
@@ -3,7 +3,9 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use std::ops::Deref;
+
+use crate::{CreditCategory, IdentifierType};
+use std::{fmt::Display, ops::Deref, str::FromStr};
#[derive(PartialEq)]
pub struct SortAnyway<T>(pub T);
@@ -29,3 +31,90 @@ impl<T> Deref for SortAnyway<T> {
&self.0
}
}
+
+impl Display for CreditCategory {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ CreditCategory::Cast => "cast",
+ CreditCategory::Writing => "writing",
+ CreditCategory::Directing => "directing",
+ CreditCategory::Art => "art",
+ CreditCategory::Sound => "sound",
+ CreditCategory::Camera => "camera",
+ CreditCategory::Lighting => "lighting",
+ CreditCategory::Crew => "crew",
+ CreditCategory::Editing => "editing",
+ CreditCategory::Production => "production",
+ CreditCategory::Vfx => "vfx",
+ CreditCategory::CostumeMakeup => "costume_makeup",
+ CreditCategory::CreatedBy => "created_by",
+ CreditCategory::Performance => "performance",
+ CreditCategory::Instrument => "instrument",
+ CreditCategory::Vocal => "vocal",
+ CreditCategory::Arranger => "arranger",
+ CreditCategory::Producer => "producer",
+ CreditCategory::Engineer => "engineer",
+ })
+ }
+}
+impl FromStr for CreditCategory {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "cast" => CreditCategory::Cast,
+ "writing" => CreditCategory::Writing,
+ "directing" => CreditCategory::Directing,
+ "art" => CreditCategory::Art,
+ "sound" => CreditCategory::Sound,
+ "camera" => CreditCategory::Camera,
+ "lighting" => CreditCategory::Lighting,
+ "crew" => CreditCategory::Crew,
+ "editing" => CreditCategory::Editing,
+ "production" => CreditCategory::Production,
+ "vfx" => CreditCategory::Vfx,
+ "costume_makeup" => CreditCategory::CostumeMakeup,
+ "created_by" => CreditCategory::CreatedBy,
+ "performance" => CreditCategory::Performance,
+ "instrument" => CreditCategory::Instrument,
+ "vocal" => CreditCategory::Vocal,
+ "arranger" => CreditCategory::Arranger,
+ "producer" => CreditCategory::Producer,
+ "engineer" => CreditCategory::Engineer,
+ _ => return Err(()),
+ })
+ }
+}
+impl Display for IdentifierType {
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+ f.write_str(match self {
+ IdentifierType::MusicbrainzRecording => "musicbrainz_recording",
+ IdentifierType::MusicbrainzArtist => "musicbrainz_artist",
+ IdentifierType::MusicbrainzRelease => "musicbrainz_release",
+ IdentifierType::MusicbrainzReleaseGroup => "musicbrainz_release_group",
+ IdentifierType::Isrc => "isrc",
+ IdentifierType::Trakt => "trakt",
+ IdentifierType::Imdb => "imdb",
+ IdentifierType::Tmdb => "tmdb",
+ IdentifierType::Tvdb => "tvdb",
+ IdentifierType::Omdb => "omdb",
+ })
+ }
+}
+impl FromStr for IdentifierType {
+ type Err = ();
+ fn from_str(s: &str) -> Result<Self, Self::Err> {
+ Ok(match s {
+ "musicbrainz_recording" => IdentifierType::MusicbrainzRecording,
+ "musicbrainz_artist" => IdentifierType::MusicbrainzArtist,
+ "musicbrainz_release" => IdentifierType::MusicbrainzRelease,
+ "musicbrainz_release_group" => IdentifierType::MusicbrainzReleaseGroup,
+ "isrc" => IdentifierType::Isrc,
+ "trakt" => IdentifierType::Trakt,
+ "imdb" => IdentifierType::Imdb,
+ "tmdb" => IdentifierType::Tmdb,
+ "tvdb" => IdentifierType::Tvdb,
+ "omdb" => IdentifierType::Omdb,
+ _ => return Err(()),
+ })
+ }
+}
diff --git a/common/src/impl.rs b/common/src/impl.rs
index d4c863e..ef1a874 100644
--- a/common/src/impl.rs
+++ b/common/src/impl.rs
@@ -4,7 +4,8 @@
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use crate::{
- Node, NodeID, NodeIDOrSlug, ObjectIds, SourceTrack, SourceTrackKind, TmdbKind, TraktKind,
+ IdentifierType, Identifiers, Node, NodeID, NodeIDOrSlug, SourceTrack, SourceTrackKind,
+ TmdbKind, TraktKind,
};
use serde::{Deserialize, Serialize};
use std::{fmt::Display, str::FromStr};
@@ -86,24 +87,21 @@ impl Display for TraktKind {
})
}
}
-impl Display for ObjectIds {
+impl Display for Identifiers {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- if let Some(id) = self.trakt {
+ if let Some(id) = self.0.get(&IdentifierType::Trakt) {
f.write_fmt(format_args!("trakt={}", id))?;
}
- if let Some(_id) = &self.slug {
- f.write_str(",slug")?;
- }
- if let Some(id) = self.tmdb {
+ if let Some(id) = &self.0.get(&IdentifierType::Tmdb) {
f.write_fmt(format_args!(",tmdb={}", id))?;
}
- if let Some(_id) = &self.imdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Imdb) {
f.write_str(",imdb")?;
}
- if let Some(_id) = &self.tvdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Tvdb) {
f.write_str(",tvdb")?;
}
- if let Some(_id) = &self.omdb {
+ if let Some(_id) = &self.0.get(&IdentifierType::Omdb) {
f.write_str(",omdb")?;
}
Ok(())
diff --git a/common/src/lib.rs b/common/src/lib.rs
index 0cc9ab5..d09153e 100644
--- a/common/src/lib.rs
+++ b/common/src/lib.rs
@@ -15,7 +15,6 @@ pub use jellystream_types as stream;
pub use chrono;
-use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use std::{
collections::{BTreeMap, BTreeSet},
@@ -46,7 +45,7 @@ macro_rules! url_enum {
};
}
-#[derive(Clone, Copy, Debug, Encode, Decode, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct NodeID(pub [u8; 32]);
pub enum NodeIDOrSlug {
@@ -54,15 +53,11 @@ pub enum NodeIDOrSlug {
Slug(String),
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Node {
- #[serde(default)]
pub slug: String,
- #[serde(default)]
pub parents: BTreeSet<NodeID>,
pub kind: NodeKind,
- pub poster: Option<Asset>,
- pub backdrop: Option<Asset>,
pub title: Option<String>,
pub subtitle: Option<String>,
pub tagline: Option<String>,
@@ -70,94 +65,78 @@ pub struct Node {
pub release_date: Option<i64>, // in unix millis
pub index: Option<usize>,
pub media: Option<MediaInfo>,
- #[serde(default)]
- pub ratings: BTreeMap<Rating, f64>,
pub federated: Option<String>,
- #[serde(default)]
pub tags: BTreeSet<String>,
- #[serde(default)]
- pub people: BTreeMap<PeopleGroup, Vec<Appearance>>,
- #[serde(default)]
- pub external_ids: BTreeMap<String, String>,
- #[serde(default)]
+ pub ratings: BTreeMap<RatingType, f64>,
+ pub pictures: BTreeMap<PictureSlot, Asset>,
+ pub credits: BTreeMap<CreditCategory, Vec<Appearance>>,
+ pub identifiers: Identifiers,
pub visibility: Visibility,
- #[serde(default)]
pub storage_size: u64,
}
-#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
+pub struct Identifiers(pub BTreeMap<IdentifierType, String>);
+
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum PictureSlot {
+ Poster,
+ Cover,
+ Backdrop,
+ Headshot,
+}
+
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum IdentifierType {
+ MusicbrainzRecording,
+ MusicbrainzArtist,
+ MusicbrainzRelease,
+ MusicbrainzReleaseGroup,
+ Isrc,
+ Trakt,
+ Imdb,
+ Tmdb,
+ Tvdb,
+ Omdb,
+}
+
+#[derive(Debug, Serialize, Deserialize, PartialEq, Eq, Clone)]
pub struct Asset(pub String);
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct Appearance {
- #[serde(default)]
pub jobs: Vec<String>,
- #[serde(default)]
pub characters: Vec<String>,
- pub person: Person,
-}
-
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
-pub struct Person {
- pub name: String,
- pub headshot: Option<Asset>,
- pub ids: ObjectIds,
+ pub node: NodeID,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
-pub struct ObjectIds {
- pub trakt: Option<u64>,
- pub slug: Option<String>,
- pub imdb: Option<String>,
- pub tmdb: Option<u64>,
- pub omdb: Option<u64>,
- pub tvdb: Option<u64>,
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum CreditCategory {
+ Cast,
+ Writing,
+ Directing,
+ Art,
+ Sound,
+ Camera,
+ Lighting,
+ Crew,
+ Editing,
+ Production,
+ Vfx,
+ CostumeMakeup,
+ CreatedBy,
+ Performance,
+ Instrument,
+ Vocal,
+ Arranger,
+ Producer,
+ Engineer,
}
-url_enum!(
- #[derive(
- Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Encode, Decode,
- )]
- #[serde(rename_all = "snake_case")]
- enum PeopleGroup {
- Cast = "cast",
- Writing = "writing",
- Directing = "directing",
- Art = "art",
- Sound = "sound",
- Camera = "camera",
- Lighting = "lighting",
- Crew = "crew",
- Editing = "editing",
- Production = "production",
- Vfx = "vfx",
- CostumeMakeup = "costume_makeup",
- CreatedBy = "created_by",
- // https://musicbrainz.org/relationships/artist-recording
- // modelling after this, but its too many categories
- Performance = "performance",
- Instrument = "instrument",
- Vocal = "vocal",
- Arranger = "arranger",
- Producer = "producer",
- Engineer = "engineer",
- }
-);
-
-#[derive(
- Debug,
- Clone,
- Copy,
- Deserialize,
- Serialize,
- PartialEq,
- Eq,
- PartialOrd,
- Ord,
- Encode,
- Decode,
- Default,
-)]
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Default)]
#[serde(rename_all = "snake_case")]
pub enum Visibility {
Hidden,
@@ -166,39 +145,24 @@ pub enum Visibility {
Visible,
}
-url_enum!(
- #[derive(
- Debug,
- Clone,
- Copy,
- Deserialize,
- Serialize,
- PartialEq,
- Eq,
- Default,
- Encode,
- Decode,
- PartialOrd,
- Ord,
- )]
- #[serde(rename_all = "snake_case")]
- enum NodeKind {
- #[default]
- Unknown = "unknown",
- Movie = "movie",
- Video = "video",
- Music = "music",
- ShortFormVideo = "short_form_video",
- Collection = "collection",
- Channel = "channel",
- Show = "show",
- Series = "series",
- Season = "season",
- Episode = "episode",
- }
-);
+#[derive(Debug, Clone, Copy, Deserialize, Serialize, PartialEq, Eq, Default, PartialOrd, Ord)]
+#[serde(rename_all = "snake_case")]
+pub enum NodeKind {
+ #[default]
+ Unknown,
+ Movie,
+ Video,
+ Music,
+ ShortFormVideo,
+ Collection,
+ Channel,
+ Show,
+ Series,
+ Season,
+ Episode,
+}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum TrackSource {
Local(Asset),
@@ -207,13 +171,13 @@ pub enum TrackSource {
pub type TrackID = usize;
-#[derive(Debug, Clone, Deserialize, Serialize, Hash, Encode, Decode, PartialEq, Eq)]
+#[derive(Debug, Clone, Deserialize, Serialize, Hash, PartialEq, Eq)]
pub struct LocalTrack {
pub path: PathBuf,
pub track: TrackID,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct MediaInfo {
pub duration: f64, // in seconds
pub tracks: Vec<SourceTrack>,
@@ -221,14 +185,14 @@ pub struct MediaInfo {
pub chapters: Vec<Chapter>,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize, Default)]
pub struct Chapter {
pub time_start: Option<f64>,
pub time_end: Option<f64>,
pub labels: Vec<(String, String)>,
}
-#[derive(Debug, Clone, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct SourceTrack {
pub source: TrackSource,
pub kind: SourceTrackKind,
@@ -239,32 +203,25 @@ pub struct SourceTrack {
pub federated: Vec<String>,
}
-url_enum!(
- #[derive(
- Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash, Encode, Decode,
- )]
- #[serde(rename_all = "snake_case")]
- enum Rating {
- Imdb = "imdb",
- Tmdb = "tmdb",
- RottenTomatoes = "rotten_tomatoes",
- Metacritic = "metacritic",
- YoutubeViews = "youtube_views",
- YoutubeLikes = "youtube_likes",
- YoutubeFollowers = "youtube_followers",
- Trakt = "trakt",
- }
-);
+#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq, PartialOrd, Ord, Hash)]
+#[serde(rename_all = "snake_case")]
+pub enum RatingType {
+ Imdb,
+ Tmdb,
+ RottenTomatoes,
+ Metacritic,
+ YoutubeViews,
+ YoutubeLikes,
+ YoutubeFollowers,
+ Trakt,
+}
-#[derive(Debug, Clone, PartialEq, Deserialize, Serialize, Encode, Decode)]
+#[derive(Debug, Clone, PartialEq, Deserialize, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum SourceTrackKind {
Video {
width: u64,
height: u64,
- display_width: Option<u64>,
- display_height: Option<u64>,
- display_unit: u64,
fps: Option<f64>,
},
Audio {
@@ -275,7 +232,8 @@ pub enum SourceTrackKind {
Subtitle,
}
-#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, PartialEq, Encode, Decode)]
+// TODO move this somewhere else
+#[derive(Debug, Serialize, Deserialize, Clone, Copy, Hash, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum TraktKind {
Movie,
diff --git a/common/src/routes.rs b/common/src/routes.rs
index 3e8682b..f78c7f0 100644
--- a/common/src/routes.rs
+++ b/common/src/routes.rs
@@ -3,7 +3,7 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use crate::{api::NodeFilterSort, user::ApiWatchedState, NodeID, PeopleGroup};
+use crate::{api::NodeFilterSort, user::ApiWatchedState, NodeID, CreditCategory};
pub fn u_home() -> String {
"/home".to_owned()
@@ -31,7 +31,7 @@ pub fn u_node_slug_watched(node: &str, state: ApiWatchedState) -> String {
}
pub fn u_node_slug_person_asset(
node: &str,
- group: PeopleGroup,
+ group: CreditCategory,
index: usize,
width: usize,
) -> String {
diff --git a/common/src/user.rs b/common/src/user.rs
index c6da166..481732b 100644
--- a/common/src/user.rs
+++ b/common/src/user.rs
@@ -3,7 +3,6 @@
which is licensed under the GNU Affero General Public License (version 3); see /COPYING.
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
-use bincode::{Decode, Encode};
use serde::{Deserialize, Serialize};
use std::{
collections::{HashMap, HashSet},
@@ -13,7 +12,7 @@ use std::{
use crate::url_enum;
#[rustfmt::skip]
-#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode, Default)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct User {
pub name: String,
pub display_name: String,
@@ -25,14 +24,14 @@ pub struct User {
pub permissions: PermissionSet,
}
-#[derive(Debug, Clone, Serialize, Deserialize, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeUserData {
pub watched: WatchedState,
#[serde(default)]
pub rating: i32,
}
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum WatchedState {
None,
@@ -60,7 +59,7 @@ pub struct CreateSessionParams {
}
url_enum!(
- #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)]
+ #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum Theme {
#[default]
@@ -72,7 +71,7 @@ url_enum!(
);
url_enum!(
- #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq, Encode, Decode)]
+ #[derive(Debug, Clone, Copy, Serialize, Default, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
enum PlayerKind {
#[default]
@@ -82,10 +81,10 @@ url_enum!(
}
);
-#[derive(Debug, Clone, Serialize, Deserialize, Default, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, Default)]
pub struct PermissionSet(pub HashMap<UserPermission, bool>);
-#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash, Encode, Decode)]
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Hash)]
#[serde(rename_all = "snake_case")]
pub enum UserPermission {
Admin,
diff --git a/database/Cargo.toml b/database/Cargo.toml
index 2cf9909..c5bfc9d 100644
--- a/database/Cargo.toml
+++ b/database/Cargo.toml
@@ -8,7 +8,7 @@ tantivy = "0.25.0"
jellycommon = { path = "../common" }
serde = { version = "1.0.228", features = ["derive"] }
log = { workspace = true }
-bincode = "2.0.1"
+serde_json = "1.0.145"
redb = "3.1.0"
anyhow = "1.0.100"
diff --git a/database/src/lib.rs b/database/src/lib.rs
index 8e47298..fe43ad4 100644
--- a/database/src/lib.rs
+++ b/database/src/lib.rs
@@ -6,7 +6,6 @@
pub mod search;
use anyhow::{Context, Result, anyhow, bail};
-use bincode::{Decode, Encode, config::standard};
use jellycommon::{
Node, NodeID,
user::{NodeUserData, User},
@@ -14,6 +13,8 @@ use jellycommon::{
use log::info;
use redb::{Durability, ReadableDatabase, ReadableTable, StorageError, TableDefinition};
use search::NodeTextSearchIndex;
+#[cfg(not(feature = "db_json"))]
+use serde::{Serialize, de::DeserializeOwned};
use std::{
fs::create_dir_all,
hash::{DefaultHasher, Hasher},
@@ -185,21 +186,19 @@ impl Database {
let mut t_tag_node = txn.open_table(T_TAG_NODE)?;
let mut node = t_node.get(id.0)?.map(|v| v.value().0).unwrap_or_default();
- let mut dh_before = HashWriter(DefaultHasher::new());
- bincode::encode_into_writer(&node, &mut dh_before, standard()).unwrap();
+ let dh_before = serde_json::to_vec(&node).unwrap();
update(&mut node)?;
- let mut dh_after = HashWriter(DefaultHasher::new());
- bincode::encode_into_writer(&node, &mut dh_after, standard()).unwrap();
+ let dh_after = serde_json::to_vec(&node).unwrap();
- if dh_before.0.finish() == dh_after.0.finish() {
+ if dh_before == dh_after {
return Ok(());
}
for parent in &node.parents {
t_node_children.insert((parent.0, id.0), ())?;
}
- for (pl, eid) in &node.external_ids {
- t_node_external_id.insert((pl.as_str(), eid.as_str()), id.0)?;
+ for (pl, eid) in &node.identifiers.0 {
+ t_node_external_id.insert((pl.to_string().as_str(), eid.as_str()), id.0)?;
}
for tag in &node.tags {
t_tag_node.insert((tag.as_str(), id.0), ())?;
@@ -468,59 +467,11 @@ impl Database {
}
}
-pub struct HashWriter(DefaultHasher);
-impl bincode::enc::write::Writer for HashWriter {
- fn write(&mut self, bytes: &[u8]) -> std::result::Result<(), bincode::error::EncodeError> {
- self.0.write(bytes);
- Ok(())
- }
-}
-
#[derive(Debug)]
#[cfg(not(feature = "db_json"))]
pub struct Ser<T>(pub T);
#[cfg(not(feature = "db_json"))]
-impl<T: Encode + Decode<()> + std::fmt::Debug> redb::Value for Ser<T> {
- type SelfType<'a>
- = Ser<T>
- where
- Self: 'a;
- type AsBytes<'a>
- = Vec<u8>
- where
- Self: 'a;
-
- fn fixed_width() -> Option<usize> {
- None
- }
-
- fn from_bytes<'a>(data: &'a [u8]) -> Self::SelfType<'a>
- where
- Self: 'a,
- {
- Ser(bincode::decode_from_slice(data, bincode::config::legacy())
- .unwrap()
- .0)
- }
-
- fn as_bytes<'a, 'b: 'a>(value: &'a Self::SelfType<'b>) -> Self::AsBytes<'a>
- where
- Self: 'a,
- Self: 'b,
- {
- bincode::encode_to_vec(&value.0, bincode::config::legacy()).unwrap()
- }
-
- fn type_name() -> redb::TypeName {
- redb::TypeName::new("bincode")
- }
-}
-
-#[derive(Debug)]
-#[cfg(feature = "db_json")]
-pub struct Ser<T>(pub T);
-#[cfg(feature = "db_json")]
-impl<T: Serialize + for<'a> Deserialize<'a> + std::fmt::Debug> redb::Value for Ser<T> {
+impl<T: DeserializeOwned + Serialize + std::fmt::Debug> redb::Value for Ser<T> {
type SelfType<'a>
= Ser<T>
where
diff --git a/import/asset_token/src/lib.rs b/import/asset_token/src/lib.rs
index 0a120f0..ef1850e 100644
--- a/import/asset_token/src/lib.rs
+++ b/import/asset_token/src/lib.rs
@@ -6,7 +6,6 @@
use aes_gcm_siv::{aead::Aead, Aes256GcmSiv, KeyInit};
use anyhow::{anyhow, bail, Context};
use base64::Engine;
-use bincode::{Decode, Encode};
use jellycache::CachePath;
pub use jellycommon as common;
use jellycommon::{Asset, LocalTrack};
@@ -46,10 +45,10 @@ static ASSET_KEY: LazyLock<Aes256GcmSiv> = LazyLock::new(|| {
}
});
-#[derive(Debug, Encode, Decode, Serialize, PartialEq, Eq)]
+#[derive(Debug, Serialize, PartialEq, Eq)]
pub enum AssetInner {
Federated { host: String, asset: Vec<u8> },
- Cache(#[bincode(with_serde)] CachePath),
+ Cache(CachePath),
Assets(PathBuf),
Media(PathBuf),
LocalTrack(LocalTrack),
diff --git a/import/src/lib.rs b/import/src/lib.rs
index 1fd8bc7..1a1d5ad 100644
--- a/import/src/lib.rs
+++ b/import/src/lib.rs
@@ -24,7 +24,7 @@ use infojson::YVideo;
use jellycache::{cache_file, cache_memory};
use jellycommon::{
Appearance, Chapter, LocalTrack, MediaInfo, Node, NodeID, NodeKind, ObjectIds, PeopleGroup,
- Person, Rating, SourceTrack, SourceTrackKind, TmdbKind, TrackSource, TraktKind, Visibility,
+ Person, RatingType, SourceTrack, SourceTrackKind, TmdbKind, TrackSource, TraktKind, Visibility,
};
use jellyimport_fallback_generator::generate_fallback;
use jellyremuxer::{
@@ -291,7 +291,7 @@ fn import_file(
merge_option(&mut node.description, data.description);
merge_option(&mut node.index, data.index);
merge_option(&mut node.release_date, data.release_date);
- node.external_ids.extend(data.external_ids);
+ node.identifiers.extend(data.identifiers);
Ok(())
})?;
@@ -323,10 +323,10 @@ fn import_file(
node.kind = NodeKind::Channel;
node.title = Some(clean_uploader_name(&data.title).to_owned());
if let Some(cid) = data.channel_id {
- node.external_ids.insert("youtube.channel".to_string(), cid);
+ node.identifiers.insert("youtube.channel".to_string(), cid);
}
if let Some(uid) = data.uploader_id {
- node.external_ids
+ node.identifiers
.insert("youtube.channelname".to_string(), uid);
}
if let Some(desc) = data.description {
@@ -334,7 +334,7 @@ fn import_file(
}
if let Some(followers) = data.channel_follower_count {
node.ratings
- .insert(Rating::YoutubeFollowers, followers as f64);
+ .insert(RatingType::YoutubeFollowers, followers as f64);
}
Ok(())
})?;
@@ -401,7 +401,8 @@ fn import_media_file(
.transpose()?;
let mut tags = m
- .tags.first()
+ .tags
+ .first()
.map(|tags| {
tags.tags
.iter()
@@ -508,7 +509,7 @@ fn import_media_file(
node.tagline = tags.remove("COMMENT").or(node.tagline.clone());
node.parents.insert(parent);
- node.external_ids.extend(eids);
+ node.identifiers.extend(eids);
if let Some(ct) = tags.get("CONTENT_TYPE") {
node.kind = match ct.to_lowercase().trim() {
@@ -533,9 +534,6 @@ fn import_media_file(
SourceTrackKind::Video {
width: video.pixel_width,
height: video.pixel_height,
- display_width: video.display_width,
- display_height: video.display_height,
- display_unit: video.display_unit,
fps: video.frame_rate,
}
} else if let Some(audio) = &track.audio {
@@ -594,20 +592,17 @@ fn import_media_file(
}
match infojson.extractor.as_str() {
"youtube" => {
- node.external_ids
+ node.identifiers
.insert("youtube.video".to_string(), infojson.id);
node.ratings.insert(
- Rating::YoutubeViews,
+ RatingType::YoutubeViews,
infojson.view_count.unwrap_or_default() as f64,
);
if let Some(lc) = infojson.like_count {
- node.ratings.insert(Rating::YoutubeLikes, lc as f64);
+ node.ratings.insert(RatingType::YoutubeLikes, lc as f64);
}
}
- "Bandcamp" => drop(
- node.external_ids
- .insert("bandcamp".to_string(), infojson.id),
- ),
+ "Bandcamp" => drop(node.identifiers.insert("bandcamp".to_string(), infojson.id)),
_ => (),
}
}
@@ -686,7 +681,7 @@ fn import_media_file(
node.title = Some(episode.title.clone());
node.poster = poster.or(node.poster.clone());
node.description = episode.overview.clone().or(node.description.clone());
- node.ratings.insert(Rating::Trakt, episode.rating);
+ node.ratings.insert(RatingType::Trakt, episode.rating);
Ok(())
})?
}
@@ -770,11 +765,11 @@ fn apply_musicbrainz_recording(
db.update_node_init(node, |node| {
node.title = Some(rec.title.clone());
- node.external_ids
+ node.identifiers
.insert("musicbrainz.recording".to_string(), rec.id.to_string());
if let Some(a) = rec.artist_credit.first() {
node.subtitle = Some(a.artist.name.clone());
- node.external_ids
+ node.identifiers
.insert("musicbrainz.artist".to_string(), a.artist.id.to_string());
}
@@ -850,24 +845,15 @@ fn apply_musicbrainz_recording(
.ser(),
};
- node.people.entry(group).or_default().push(Appearance {
+ node.credits.entry(group).or_default().push(Appearance {
jobs,
characters: vec![],
- person: Person {
- name: if rel.target_credit.is_empty() {
- artist.name.clone()
- } else {
- rel.target_credit.clone()
- },
- headshot: Some(headshot),
- ids: ObjectIds::default(),
- },
});
}
}
for isrc in &rec.isrcs {
- node.external_ids
+ node.identifiers
.insert("isrc".to_string(), isrc.to_string());
}
Ok(())
@@ -944,7 +930,7 @@ fn apply_trakt_tmdb(
db.update_node_init(node, |node| {
node.title = Some(data.title.clone());
- node.people.extend(people_map);
+ node.credits.extend(people_map);
node.kind = match trakt_kind {
TraktKind::Movie => NodeKind::Movie,
TraktKind::Show => NodeKind::Show,
@@ -960,7 +946,7 @@ fn apply_trakt_tmdb(
node.tagline = Some(tagline.clone())
}
if let Some(rating) = &data.rating {
- node.ratings.insert(Rating::Trakt, *rating);
+ node.ratings.insert(RatingType::Trakt, *rating);
}
if let Some(poster) = poster {
node.poster = Some(poster);
@@ -972,7 +958,7 @@ fn apply_trakt_tmdb(
node.title = data.title.clone().or(node.title.clone());
node.tagline = data.tagline.clone().or(node.tagline.clone());
node.description = Some(data.overview.clone());
- node.ratings.insert(Rating::Tmdb, data.vote_average);
+ node.ratings.insert(RatingType::Tmdb, data.vote_average);
if let Some(date) = data.release_date.clone() {
if let Ok(date) = tmdb::parse_release_date(&date) {
node.release_date = date;
diff --git a/logic/src/assets.rs b/logic/src/assets.rs
index c6d6a11..02d0c2e 100644
--- a/logic/src/assets.rs
+++ b/logic/src/assets.rs
@@ -58,7 +58,7 @@ pub fn get_node_person_asset(
.get_node(id)?
.ok_or(anyhow!("node does not exist"))?;
let app = node
- .people
+ .credits
.get(&group)
.ok_or(anyhow!("group has no members"))?
.get(index)
diff --git a/logic/src/filter_sort.rs b/logic/src/filter_sort.rs
index 3ccbc0d..d3244af 100644
--- a/logic/src/filter_sort.rs
+++ b/logic/src/filter_sort.rs
@@ -4,7 +4,7 @@
Copyright (C) 2025 metamuffin <metamuffin.org>
*/
use jellycommon::{
- Node, NodeKind, Rating,
+ Node, NodeKind, RatingType,
api::{FilterProperty, NodeFilterSort, SortOrder, SortProperty},
helpers::SortAnyway,
user::NodeUserData,
@@ -65,28 +65,28 @@ pub fn filter_and_sort_nodes(
.cmp(&b.index.unwrap_or(usize::MAX))
}),
SortProperty::RatingRottenTomatoes => nodes.sort_by_cached_key(|(n, _)| {
- SortAnyway(*n.ratings.get(&Rating::RottenTomatoes).unwrap_or(&0.))
+ SortAnyway(*n.ratings.get(&RatingType::RottenTomatoes).unwrap_or(&0.))
}),
SortProperty::RatingMetacritic => nodes.sort_by_cached_key(|(n, _)| {
- SortAnyway(*n.ratings.get(&Rating::Metacritic).unwrap_or(&0.))
+ SortAnyway(*n.ratings.get(&RatingType::Metacritic).unwrap_or(&0.))
}),
SortProperty::RatingImdb => nodes
- .sort_by_cached_key(|(n, _)| SortAnyway(*n.ratings.get(&Rating::Imdb).unwrap_or(&0.))),
+ .sort_by_cached_key(|(n, _)| SortAnyway(*n.ratings.get(&RatingType::Imdb).unwrap_or(&0.))),
SortProperty::RatingTmdb => nodes
- .sort_by_cached_key(|(n, _)| SortAnyway(*n.ratings.get(&Rating::Tmdb).unwrap_or(&0.))),
+ .sort_by_cached_key(|(n, _)| SortAnyway(*n.ratings.get(&RatingType::Tmdb).unwrap_or(&0.))),
SortProperty::RatingYoutubeViews => nodes.sort_by_cached_key(|(n, _)| {
- SortAnyway(*n.ratings.get(&Rating::YoutubeViews).unwrap_or(&0.))
+ SortAnyway(*n.ratings.get(&RatingType::YoutubeViews).unwrap_or(&0.))
}),
SortProperty::RatingYoutubeLikes => nodes.sort_by_cached_key(|(n, _)| {
- SortAnyway(*n.ratings.get(&Rating::YoutubeLikes).unwrap_or(&0.))
+ SortAnyway(*n.ratings.get(&RatingType::YoutubeLikes).unwrap_or(&0.))
}),
SortProperty::RatingYoutubeFollowers => nodes.sort_by_cached_key(|(n, _)| {
- SortAnyway(*n.ratings.get(&Rating::YoutubeFollowers).unwrap_or(&0.))
+ SortAnyway(*n.ratings.get(&RatingType::YoutubeFollowers).unwrap_or(&0.))
}),
SortProperty::RatingLikesDivViews => nodes.sort_by_cached_key(|(n, _)| {
SortAnyway(
- *n.ratings.get(&Rating::YoutubeLikes).unwrap_or(&0.)
- / (1. + *n.ratings.get(&Rating::YoutubeViews).unwrap_or(&0.)),
+ *n.ratings.get(&RatingType::YoutubeLikes).unwrap_or(&0.)
+ / (1. + *n.ratings.get(&RatingType::YoutubeViews).unwrap_or(&0.)),
)
}),
SortProperty::RatingUser => nodes.sort_by_cached_key(|(_, u)| u.rating),
diff --git a/logic/src/home.rs b/logic/src/home.rs
index ff85ba1..db8a397 100644
--- a/logic/src/home.rs
+++ b/logic/src/home.rs
@@ -7,7 +7,7 @@
use crate::{DATABASE, node::DatabaseNodeUserDataExt, session::Session};
use anyhow::{Context, Result};
use jellycommon::{
- NodeID, NodeKind, Rating, Visibility,
+ NodeID, NodeKind, RatingType, Visibility,
api::ApiHomeResponse,
chrono::{Datelike, Utc},
user::WatchedState,
@@ -77,7 +77,7 @@ pub fn home(session: &Session) -> Result<ApiHomeResponse> {
items.sort_by_key(|(n, _)| {
n.ratings
- .get(&Rating::Tmdb)
+ .get(&RatingType::Tmdb)
.map(|x| (*x * -1000.) as i32)
.unwrap_or(0)
});
@@ -87,7 +87,7 @@ pub fn home(session: &Session) -> Result<ApiHomeResponse> {
items
.iter()
.take(16)
- .filter(|(n, _)| n.ratings.contains_key(&Rating::Tmdb))
+ .filter(|(n, _)| n.ratings.contains_key(&RatingType::Tmdb))
.cloned()
.collect(),
));
diff --git a/server/src/compat/jellyfin/mod.rs b/server/src/compat/jellyfin/mod.rs
index be9278e..3f04705 100644
--- a/server/src/compat/jellyfin/mod.rs
+++ b/server/src/compat/jellyfin/mod.rs
@@ -735,7 +735,7 @@ fn item_object(node: &Node, userdata: &NodeUserData) -> JellyfinItem {
_ => JellyfinItemType::CollectionFolder,
},
people: node
- .people
+ .credits
.iter()
.flat_map(|(_pg, ps)| {
ps.iter().map(|p| JellyfinPerson {
diff --git a/ui/src/node_page.rs b/ui/src/node_page.rs
index 39b66df..1e029ae 100644
--- a/ui/src/node_page.rs
+++ b/ui/src/node_page.rs
@@ -116,9 +116,9 @@ markup::define! {
}}
}}
}
- @if !node.people.is_empty() {
+ @if !node.credits.is_empty() {
h2 { @trs(lang, "node.people") }
- @for (group, people) in &node.people {
+ @for (group, people) in &node.credits {
details[open=group==&PeopleGroup::Cast] {
summary { h3 { @format!("{}", group) } }
ul.children.hlist { @for (i, pe) in people.iter().enumerate() {
@@ -149,11 +149,11 @@ markup::define! {
}}
}
}
- @if !node.external_ids.is_empty() {
+ @if !node.identifiers.is_empty() {
details {
summary { @trs(lang, "node.external_ids") }
table {
- @for (key, value) in &node.external_ids { tr {
+ @for (key, value) in &node.identifiers { tr {
tr {
td { @trs(lang, &format!("eid.{}", key)) }
@if let Some(url) = external_id_url(key, value) {
diff --git a/ui/src/props.rs b/ui/src/props.rs
index fbeddca..64713ea 100644
--- a/ui/src/props.rs
+++ b/ui/src/props.rs
@@ -8,7 +8,7 @@ use crate::{
locale::{Language, tr, trs},
};
use jellycommon::{
- Node, Rating, Visibility,
+ Node, RatingType, Visibility,
chrono::DateTime,
user::{NodeUserData, WatchedState},
};
@@ -38,14 +38,14 @@ markup::define! {
// }
@for (kind, value) in &node.ratings {
@match kind {
- Rating::YoutubeLikes => {p.likes{ @format_count(*value as usize) " Likes" }}
- Rating::YoutubeViews => {p{ @format_count(*value as usize) " Views" }}
- Rating::YoutubeFollowers => {p{ @format_count(*value as usize) " Subscribers" }}
- Rating::RottenTomatoes => {p.rating{ @value " Tomatoes" }}
- Rating::Metacritic if *full => {p{ "Metacritic Score: " @value }}
- Rating::Imdb => {p.rating{ "IMDb " @value }}
- Rating::Tmdb => {p.rating{ "TMDB " @value }}
- Rating::Trakt if *full => {p.rating{ "Trakt " @value }}
+ RatingType::YoutubeLikes => {p.likes{ @format_count(*value as usize) " Likes" }}
+ RatingType::YoutubeViews => {p{ @format_count(*value as usize) " Views" }}
+ RatingType::YoutubeFollowers => {p{ @format_count(*value as usize) " Subscribers" }}
+ RatingType::RottenTomatoes => {p.rating{ @value " Tomatoes" }}
+ RatingType::Metacritic if *full => {p{ "Metacritic Score: " @value }}
+ RatingType::Imdb => {p.rating{ "IMDb " @value }}
+ RatingType::Tmdb => {p.rating{ "TMDB " @value }}
+ RatingType::Trakt if *full => {p.rating{ "Trakt " @value }}
_ => {}
}
}