From b6ad5929510cffa056ec734380c59f11941f60ff Mon Sep 17 00:00:00 2001 From: David Skrundz Date: Fri, 29 May 2026 22:26:22 -0600 Subject: [PATCH] Model updates, bugfixes, and a new muxing cli tool --- .zed/settings.json | 8 - Cargo.lock | 474 ++++++------ Cargo.toml | 19 +- README.md | 1 + crates/cli-mux/Cargo.toml | 57 ++ crates/cli-mux/README.md | 11 + crates/cli-mux/src/cli.rs | 49 ++ crates/cli-mux/src/main.rs | 66 ++ crates/cli-mux/src/model.rs | 101 +++ crates/cli-mux/src/mux.rs | 227 ++++++ crates/cli-mux/src/parser.rs | 159 ++++ crates/cli-mux/src/probe.rs | 53 ++ crates/cli-mux/src/scan.rs | 58 ++ crates/cli/Cargo.toml | 2 +- crates/cli/README.md | 1 + crates/cli/src/cli/mod.rs | 7 +- crates/cli/src/main.rs | 8 +- crates/cli/src/run/flix.rs | 18 +- crates/cli/src/run/tmdb.rs | 82 +-- crates/db/Cargo.toml | 2 +- crates/db/src/entity/content.rs | 20 +- crates/flix/Cargo.toml | 2 +- crates/fs/Cargo.toml | 2 +- crates/fs/src/scanner/generic.rs | 5 +- crates/fs/src/scanner/mod.rs | 10 + crates/model/Cargo.toml | 2 +- crates/model/src/text.rs | 33 +- crates/tmdb/Cargo.toml | 2 +- crates/tmdb/src/model/episode.rs | 8 +- crates/tmdb/src/model/mod.rs | 22 +- flix.sh | 1184 +++++++++++++++++++++++++++--- tombi.toml | 6 + 32 files changed, 2246 insertions(+), 453 deletions(-) create mode 100644 crates/cli-mux/Cargo.toml create mode 100644 crates/cli-mux/README.md create mode 100644 crates/cli-mux/src/cli.rs create mode 100644 crates/cli-mux/src/main.rs create mode 100644 crates/cli-mux/src/model.rs create mode 100644 crates/cli-mux/src/mux.rs create mode 100644 crates/cli-mux/src/parser.rs create mode 100644 crates/cli-mux/src/probe.rs create mode 100644 crates/cli-mux/src/scan.rs diff --git a/.zed/settings.json b/.zed/settings.json index 557a88e..14b551a 100644 --- a/.zed/settings.json +++ b/.zed/settings.json @@ -1,18 +1,10 @@ { - "project_name": null, - - "auto_install_extensions": { - "tombi": true, - "cargo-appraiser": true, - }, - "languages": { "TOML": { "format_on_save": "on", "formatter": { "language_server": { "name": "tombi" } }, }, }, - "lsp": { "rust-analyzer": { "initialization_options": { diff --git a/Cargo.lock b/Cargo.lock index fa4fd2e..4e279f2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -121,9 +121,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50" [[package]] name = "arrow" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4754a624e5ae42081f464514be454b39711daae0458906dacde5f4c632f33a8" +checksum = "3bd47f2a6ddc39244bd722a27ee5da66c03369d087b9e024eafdb03e98b98ea7" dependencies = [ "arrow-arith", "arrow-array", @@ -139,9 +139,9 @@ dependencies = [ [[package]] name = "arrow-arith" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7b3141e0ec5145a22d8694ea8b6d6f69305971c4fa1c1a13ef0195aef2d678b" +checksum = "7c7bbd679c5418b8639b92be01f361d60013c4906574b578b77b63c78356594c" dependencies = [ "arrow-array", "arrow-buffer", @@ -153,9 +153,9 @@ dependencies = [ [[package]] name = "arrow-array" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c8955af33b25f3b175ee10af580577280b4bd01f7e823d94c7cdef7cf8c9aef" +checksum = "c8a4ab47b3f3eac60f7fd31b81e9028fda018607bcc63451aca4f2b755269862" dependencies = [ "ahash 0.8.12", "arrow-buffer", @@ -171,9 +171,9 @@ dependencies = [ [[package]] name = "arrow-buffer" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c697ddca96183182f35b3a18e50b9110b11e916d7b7799cbfd4d34662f2c56c2" +checksum = "0d18b89b4c4f4811d0858175e79541fe98e33e18db3b011708bc287b1240593f" dependencies = [ "bytes", "half", @@ -183,9 +183,9 @@ dependencies = [ [[package]] name = "arrow-cast" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "646bbb821e86fd57189c10b4fcdaa941deaf4181924917b0daa92735baa6ada5" +checksum = "722b5c41dd1d14d0a879a1bce92c6fe33f546101bb2acce57a209825edd075b3" dependencies = [ "arrow-array", "arrow-buffer", @@ -204,9 +204,9 @@ dependencies = [ [[package]] name = "arrow-data" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fdd994a9d28e6365aa78e15da3f3950c0fdcea6b963a12fa1c391afb637b304" +checksum = "c1683705c63dcf0d18972759eda48489028cbbff67af7d6bef2c6b7b74ab778a" dependencies = [ "arrow-buffer", "arrow-schema", @@ -217,9 +217,9 @@ dependencies = [ [[package]] name = "arrow-ord" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d8f1870e03d4cbed632959498bcc84083b5a24bded52905ae1695bd29da45b" +checksum = "082342947d4e5a2bcccf029a0a0397e21cb3bb8421edd9571d34fb5dd2670256" dependencies = [ "arrow-array", "arrow-buffer", @@ -230,9 +230,9 @@ dependencies = [ [[package]] name = "arrow-row" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18228633bad92bff92a95746bbeb16e5fc318e8382b75619dec26db79e4de4c0" +checksum = "e3a931b520a2a5e22033e01a6f2486b4cdc26f9106b759abeebc320f125e94d7" dependencies = [ "arrow-array", "arrow-buffer", @@ -243,15 +243,15 @@ dependencies = [ [[package]] name = "arrow-schema" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c872d36b7bf2a6a6a2b40de9156265f0242910791db366a2c17476ba8330d68" +checksum = "e4cf0d4a6609679e03002167a61074a21d7b1ad9ea65e462b2c0a97f8a3b2bc6" [[package]] name = "arrow-select" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68bf3e3efbd1278f770d67e5dc410257300b161b93baedb3aae836144edcaf4b" +checksum = "0b320d86a9806923663bb0fd9baa65ecaba81cb0cd77ff8c1768b9716b4ef891" dependencies = [ "ahash 0.8.12", "arrow-array", @@ -263,9 +263,9 @@ dependencies = [ [[package]] name = "arrow-string" -version = "57.3.0" +version = "57.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85e968097061b3c0e9fe3079cf2e703e487890700546b5b0647f60fca1b5a8d8" +checksum = "b493e99162e5764077e7823e50ba284858d365922631c7aaefe9487b1abd02c2" dependencies = [ "arrow-array", "arrow-buffer", @@ -328,15 +328,15 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autocfg" -version = "1.5.0" +version = "1.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53" [[package]] name = "aws-lc-rs" -version = "1.16.3" +version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f" +checksum = "5ec2f1fc3ec205783a5da9a7e6c1509cc69dedf09a1949e412c1e18469326d00" dependencies = [ "aws-lc-sys", "zeroize", @@ -344,9 +344,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.40.0" +version = "0.41.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7" +checksum = "1a2f9779ce85b93ab6170dd940ad0169b5766ff848247aff13bb788b832fe3f4" dependencies = [ "cc", "cmake", @@ -436,9 +436,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.20.2" +version = "3.20.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb" +checksum = "72f5acc6cb2ba439de613abc23857ec3d78374d8ed5ac84e9d11336e87da8649" [[package]] name = "bytecheck" @@ -476,9 +476,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33" [[package]] name = "cc" -version = "1.2.61" +version = "1.2.63" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d" +checksum = "556e016178bb5662a08681bbe0f00f8e17631781a4dfc8c45e466e4b185ec27f" dependencies = [ "find-msvc-tools", "jobserver", @@ -486,12 +486,6 @@ dependencies = [ "shlex", ] -[[package]] -name = "cesu8" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d43a04d8753f35258c91f8ec639f792891f748a1edbd759cf1dcea3382ad83c" - [[package]] name = "cfg-if" version = "1.0.4" @@ -590,6 +584,18 @@ dependencies = [ "crossbeam-utils", ] +[[package]] +name = "console" +version = "0.16.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d64e8af5551369d19cf50138de61f1c42074ab970f74e99be916646777f8fc87" +dependencies = [ + "encode_unicode", + "libc", + "unicode-width", + "windows-sys 0.61.2", +] + [[package]] name = "const-oid" version = "0.9.6" @@ -764,6 +770,16 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "dialoguer" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25f104b501bf2364e78d0d3974cbc774f738f5865306ed128e1e0d7499c0ad96" +dependencies = [ + "console", + "shell-words", +] + [[package]] name = "digest" version = "0.10.7" @@ -778,9 +794,9 @@ dependencies = [ [[package]] name = "displaydoc" -version = "0.2.5" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +checksum = "1ac70aa55017e108007fbaf5aa0f54b021c98f92ff8af59d42eda9da96e3dd4f" dependencies = [ "proc-macro2", "quote", @@ -801,13 +817,19 @@ checksum = "92773504d58c093f6de2459af4af33faa518c13451eb8f2b5698ed3d36e7c813" [[package]] name = "either" -version = "1.15.0" +version = "1.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +checksum = "91622ff5e7162018101f2fea40d6ebf4a78bbe5a49736a2020649edf9693679e" dependencies = [ "serde", ] +[[package]] +name = "encode_unicode" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34aa73646ffb006b8f5147f3dc182bd4bcb190227ce861fc4a4844bf8e3cb2c0" + [[package]] name = "equivalent" version = "1.0.2" @@ -844,7 +866,7 @@ checksum = "5baebc0774151f905a1a2cc41989300b1e6fbb29aff0ceffa1064fdd3088d582" [[package]] name = "flix" -version = "0.0.18" +version = "0.0.19" dependencies = [ "flix-db", "flix-fs", @@ -854,7 +876,7 @@ dependencies = [ [[package]] name = "flix-cli" -version = "0.0.18" +version = "0.0.19" dependencies = [ "anyhow", "chrono", @@ -871,7 +893,7 @@ dependencies = [ [[package]] name = "flix-db" -version = "0.0.18" +version = "0.0.19" dependencies = [ "chrono", "flix-model", @@ -884,30 +906,44 @@ dependencies = [ [[package]] name = "flix-fs" -version = "0.0.18" +version = "0.0.19" dependencies = [ "async-stream", "either", "flix-model", "regex", - "thiserror 2.0.18", + "thiserror", "tokio", "tokio-stream", ] [[package]] name = "flix-model" -version = "0.0.18" +version = "0.0.19" dependencies = [ "itertools", "seamantic", "serde", - "thiserror 2.0.18", + "thiserror", +] + +[[package]] +name = "flix-mux" +version = "0.0.19" +dependencies = [ + "anyhow", + "clap", + "console", + "dialoguer", + "indicatif", + "serde", + "serde_json", + "walkdir", ] [[package]] name = "flix-tmdb" -version = "0.0.18" +version = "0.0.19" dependencies = [ "bytes", "chrono", @@ -920,7 +956,7 @@ dependencies = [ "serde", "serde_json", "serde_test", - "thiserror 2.0.18", + "thiserror", "url", "url-macro", ] @@ -1047,9 +1083,9 @@ checksum = "037711b3d59c33004d3856fbdc83b99d4ff37a24768fa1be9ce3538a1cde4393" [[package]] name = "futures-timer" -version = "3.0.3" +version = "3.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f288b0a4f20f9a56b5d1da57e2227c661b7b16168e2f72365f57b63326e29b24" +checksum = "af43fadb8a98512d547e37b4e92e0ced13e205c061b87b4623eff01d918d6968" [[package]] name = "futures-util" @@ -1175,9 +1211,9 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.17.0" +version = "0.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f467dd6dccf739c208452f8014c75c18bb8301b050ad1cfb27153803edb0f51" +checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a" [[package]] name = "hashlink" @@ -1235,9 +1271,9 @@ dependencies = [ [[package]] name = "http" -version = "1.4.0" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3ba2a386d7f85a81f119ad7498ebe444d2e22c2af0b86b069416ace48b3311a" +checksum = "8be7462df143984c4598a256ef469b251d7d7f9e271135073e78fc535414f3d0" dependencies = [ "bytes", "itoa", @@ -1274,9 +1310,9 @@ checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" [[package]] name = "hyper" -version = "1.9.0" +version = "1.10.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "55281c53a1894c864990125767da440a4e630446785086f52523b20033b74498" dependencies = [ "atomic-waker", "bytes", @@ -1455,9 +1491,9 @@ dependencies = [ [[package]] name = "idna_adapter" -version = "1.2.1" +version = "1.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714" dependencies = [ "icu_normalizer", "icu_properties", @@ -1470,7 +1506,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d466e9454f08e4a911e14806c24e16fba1b4c121d1ea474396f396069cf949d9" dependencies = [ "equivalent", - "hashbrown 0.17.0", + "hashbrown 0.17.1", +] + +[[package]] +name = "indicatif" +version = "0.18.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25470f23803092da7d239834776d653104d551bc4d7eacaf31e6837854b8e9eb" +dependencies = [ + "console", + "portable-atomic", + "unit-prefix", ] [[package]] @@ -1508,16 +1555,6 @@ version = "2.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" -[[package]] -name = "iri-string" -version = "0.7.12" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" -dependencies = [ - "memchr", - "serde", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.2" @@ -1541,27 +1578,32 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jni" -version = "0.21.1" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a87aa2bb7d2af34197c04845522473242e1aa17c12f4935d5856491a7fb8c97" +checksum = "5efd9a482cf3a427f00d6b35f14332adc7902ce91efb778580e180ff90fa3498" dependencies = [ - "cesu8", "cfg-if", "combine", - "jni-sys 0.3.1", + "jni-macros", + "jni-sys", "log", - "thiserror 1.0.69", + "simd_cesu8", + "thiserror", "walkdir", - "windows-sys 0.45.0", + "windows-link", ] [[package]] -name = "jni-sys" -version = "0.3.1" +name = "jni-macros" +version = "0.22.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +checksum = "a00109accc170f0bdb141fed3e393c565b6f5e072365c3bd58f5b062591560a3" dependencies = [ - "jni-sys 0.4.1", + "proc-macro2", + "quote", + "rustc_version", + "simd_cesu8", + "syn 2.0.117", ] [[package]] @@ -1595,9 +1637,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.95" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca" +checksum = "142bc4740e452c1e57ade0cbc129f139c9093e354346f0872ef985f4f5cf5f11" dependencies = [ "cfg-if", "futures-util", @@ -1685,14 +1727,14 @@ checksum = "b6d2cec3eae94f9f509c767b45932f1ada8350c4bdb85af2fcab4a3c14807981" [[package]] name = "libredox" -version = "0.1.16" +version = "0.1.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02f3bb43d335493c96bf3fd3a321600bf6bd07ed34bc64118e9293bdffea46c" +checksum = "f02ab6bace2054fb888a3c16f990117b579d14a3088e472d63c6011fa185c9d3" dependencies = [ "bitflags", "libc", "plain", - "redox_syscall 0.7.4", + "redox_syscall 0.8.0", ] [[package]] @@ -1723,9 +1765,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.29" +version = "0.4.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" +checksum = "616ec5685824bcc94416c6d4a7a446eea774a31efd7062c8480ba6fd06d7a6e5" [[package]] name = "lru-slab" @@ -1765,9 +1807,9 @@ dependencies = [ [[package]] name = "memchr" -version = "2.8.0" +version = "2.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8ca58f447f06ed17d5fc4043ce1b10dd205e060fb3ce5b979b8ed8e59ff3f79" +checksum = "6b947ae49db0d222b1dbc6b113ce7248a3fc3a6ca21b696717bfc000ba4484d8" [[package]] name = "memoffset" @@ -1780,9 +1822,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "02bd0af71c67b473010cbbc60715ee815645a4dc942899111f494b4b737d6fda" dependencies = [ "libc", "wasi", @@ -1845,9 +1887,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "521739c6d2bac4aa25192232afe6841231376b2b26d4d9fae5ecf8ca5772e441" [[package]] name = "num-integer" @@ -1976,9 +2018,9 @@ checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" [[package]] name = "pgvector" -version = "0.4.1" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc58e2d255979a31caa7cabfa7aac654af0354220719ab7a68520ae7a91e8c0b" +checksum = "3673cba5b9a124916096a423b806a9f29620972c6c97b08db5f2053e9428b481" dependencies = [ "serde", ] @@ -2149,7 +2191,7 @@ dependencies = [ "rustc-hash", "rustls", "socket2", - "thiserror 2.0.18", + "thiserror", "tokio", "tracing", "web-time", @@ -2171,7 +2213,7 @@ dependencies = [ "rustls", "rustls-pki-types", "slab", - "thiserror 2.0.18", + "thiserror", "tinyvec", "tracing", "web-time", @@ -2291,9 +2333,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.7.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f450ad9c3b1da563fb6948a8e0fb0fb9269711c9c73d9ea1de5058c79c8d643a" +checksum = "7c7591fa2c6b601dfcfe5f043f65a1c39fcdf50efefcd7f1572e538c1f4b398d" dependencies = [ "bitflags", ] @@ -2338,9 +2380,9 @@ dependencies = [ [[package]] name = "reqwest" -version = "0.13.2" +version = "0.13.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801" +checksum = "219c5811de6525e5416c7d5d53bb656d3afdbc6c5af816e0802bcfa42dbdc1c3" dependencies = [ "base64", "bytes", @@ -2438,9 +2480,9 @@ dependencies = [ [[package]] name = "rust_decimal" -version = "1.41.0" +version = "1.42.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ce901f9a19d251159075a4c37af514c3b8ef99c22e02dd8c19161cf397ee94a" +checksum = "0c5108e3d4d903e21aac27f12ba5377b6b34f9f44b325e4894c7924169d06995" dependencies = [ "arrayvec", "borsh", @@ -2470,9 +2512,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.39" +version = "0.23.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c2c118cb077cca2822033836dfb1b975355dfb784b5e8da48f7b6c5db74e60e" +checksum = "ef86cd5876211988985292b91c96a8f2d298df24e75989a43a3c73f2d4d8168b" dependencies = [ "aws-lc-rs", "once_cell", @@ -2507,9 +2549,9 @@ dependencies = [ [[package]] name = "rustls-platform-verifier" -version = "0.6.2" +version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d99feebc72bae7ab76ba994bb5e121b8d83d910ca40b36e0921f53becc41784" +checksum = "26d1e2536ce4f35f4846aa13bff16bd0ff40157cdb14cc056c7b14ba41233ba0" dependencies = [ "core-foundation", "core-foundation-sys", @@ -2621,7 +2663,7 @@ dependencies = [ "serde_json", "sqlx", "strum", - "thiserror 2.0.18", + "thiserror", "time", "tracing", "url", @@ -2636,7 +2678,7 @@ checksum = "5c2eee8405f16c1f337fe3a83389361caea83c928d14dbd666a480407072c365" dependencies = [ "arrow", "sea-query", - "thiserror 2.0.18", + "thiserror", ] [[package]] @@ -2705,16 +2747,16 @@ dependencies = [ [[package]] name = "sea-query-derive" -version = "1.0.0-rc.12" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d88ad44b6ad9788c8b9476b6b91f94c7461d1e19d39cd8ea37838b1e6ff5aa8" +checksum = "a0b0f466921cdd3cf4b89d5c3ac2173dba89a873ab395b123a645de181ec7537" dependencies = [ "darling", "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.117", - "thiserror 2.0.18", + "thiserror", ] [[package]] @@ -2760,9 +2802,9 @@ checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" [[package]] name = "seamantic" -version = "0.0.13" +version = "0.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a7c9658b032d7bcb6938fb7e16b1425b1ce7f7c25dfaae667e0c30bc6dc3f1b" +checksum = "04509950290d9b38f521bb7e5a2490330b1e9c4ee433ce33cc2268efb5d06cab" dependencies = [ "sea-orm", "sea-orm-migration", @@ -2829,9 +2871,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.149" +version = "1.0.150" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86" +checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9" dependencies = [ "itoa", "memchr", @@ -2902,10 +2944,16 @@ dependencies = [ ] [[package]] -name = "shlex" -version = "1.3.0" +name = "shell-words" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" +checksum = "dc6fe69c597f9c37bfeeeeeb33da3530379845f10be461a66d16d03eca2ded77" + +[[package]] +name = "shlex" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" [[package]] name = "signature" @@ -2917,6 +2965,16 @@ dependencies = [ "rand_core 0.6.4", ] +[[package]] +name = "simd_cesu8" +version = "1.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94f90157bb87cddf702797c5dadfa0be7d266cdf49e22da2fcaa32eff75b2c33" +dependencies = [ + "rustc_version", + "simdutf8", +] + [[package]] name = "simdutf8" version = "0.1.5" @@ -2940,9 +2998,9 @@ dependencies = [ [[package]] name = "socket2" -version = "0.6.3" +version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3a766e1110788c36f4fa1c2b71b387a7815aa65f88ce0229841826633d93723e" +checksum = "52d1cfed4120b4d927bf7c0f86d2087a4a7d6027c906d9f9d525a80573b9be51" dependencies = [ "libc", "windows-sys 0.61.2", @@ -3019,7 +3077,7 @@ dependencies = [ "serde_json", "sha2", "smallvec", - "thiserror 2.0.18", + "thiserror", "time", "tokio", "tokio-stream", @@ -3106,7 +3164,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.18", + "thiserror", "time", "tracing", "uuid", @@ -3147,7 +3205,7 @@ dependencies = [ "smallvec", "sqlx-core", "stringprep", - "thiserror 2.0.18", + "thiserror", "time", "tracing", "uuid", @@ -3174,7 +3232,7 @@ dependencies = [ "serde", "serde_urlencoded", "sqlx-core", - "thiserror 2.0.18", + "thiserror", "time", "tracing", "url", @@ -3270,33 +3328,13 @@ version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" -[[package]] -name = "thiserror" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" -dependencies = [ - "thiserror-impl 1.0.69", -] - [[package]] name = "thiserror" version = "2.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4288b5bcbc7920c07a1149a35cf9590a2aa808e0bc1eafaade0b80947865fbc4" dependencies = [ - "thiserror-impl 2.0.18", -] - -[[package]] -name = "thiserror-impl" -version = "1.0.69" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", + "thiserror-impl", ] [[package]] @@ -3386,9 +3424,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.52.1" +version = "1.52.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b67dee974fe86fd92cc45b7a95fdd2f99a36a6d7b0d431a231178d3d670bbcc6" +checksum = "8fc7f01b389ac15039e4dc9531aa973a135d7a4135281b12d7c1bc79fd57fffe" dependencies = [ "bytes", "libc", @@ -3455,9 +3493,9 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.11+spec-1.1.0" +version = "0.25.12+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b59c4d22ed448339746c59b905d24568fcbb3ab65a500494f7b8c3e97739f2b" +checksum = "d2153edc6955a6c354fad8f5efd38b6a8769bdccf9fe50f8e1329f81b0baa5d7" dependencies = [ "indexmap", "toml_datetime", @@ -3491,20 +3529,20 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.6.8" +version = "0.6.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d4e6559d53cc268e5031cd8429d05415bc4cb4aefc4aa5d6cc35fbf5b924a1f8" +checksum = "4cfcf7e2740e6fc6d4d688b4ef00650406bb94adf4731e43c096c3a19fe40840" dependencies = [ "bitflags", "bytes", "futures-util", "http", "http-body", - "iri-string", "pin-project-lite", "tower", "tower-layer", "tower-service", + "url", ] [[package]] @@ -3574,9 +3612,9 @@ checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" [[package]] name = "typenum" -version = "1.20.0" +version = "1.20.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20" [[package]] name = "unicode-bidi" @@ -3605,12 +3643,24 @@ version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7df058c713841ad818f1dc5d3fd88063241cc61f49f5fbea4b951e8cf5a8d71d" +[[package]] +name = "unicode-width" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4ac048d71ede7ee76d585517add45da530660ef4390e49b098733c6e897f254" + [[package]] name = "unicode-xid" version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" +[[package]] +name = "unit-prefix" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81e544489bf3d8ef66c953931f56617f423cd4b5494be343d9b9d3dda037b9a3" + [[package]] name = "untrusted" version = "0.9.0" @@ -3652,9 +3702,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.1" +version = "1.23.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddd74a9687298c6858e9b88ec8935ec45d22e8fd5e6394fa1bd4e99a87789c76" +checksum = "d258b83ceec21034727ecee8c382cfa6c3e133699b0742c64571814fb420c9f7" dependencies = [ "js-sys", "serde_core", @@ -3715,9 +3765,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89" +checksum = "3ed04576f974d2b2fba0f38c51dbc5518011e38c36bf1143164be765528fd409" dependencies = [ "cfg-if", "once_cell", @@ -3729,9 +3779,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.68" +version = "0.4.72" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8" +checksum = "9473dbd2991ae90b6291c3c32c30c6187ac49aa32f9905d1cce280ec1e110b0f" dependencies = [ "js-sys", "wasm-bindgen", @@ -3739,9 +3789,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed" +checksum = "916151b09da36bd82f6615cbf3a419e2f0ba23a03c6160e8e92eb6bd4aa1dec6" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3749,9 +3799,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904" +checksum = "299047362ccbfce148b67ab7e73349f77748e00c8296f9542adfad2ad82c5c5e" dependencies = [ "bumpalo", "proc-macro2", @@ -3762,18 +3812,18 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.118" +version = "0.2.122" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129" +checksum = "9a929b2c61f11ba3e9bc35b50c1f25cb38e0e892c0c231ae2b8cf78d5dad4437" dependencies = [ "unicode-ident", ] [[package]] name = "web-sys" -version = "0.3.95" +version = "0.3.99" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d" +checksum = "6d621441cfc37b84979402712047321980c178f299193a3589d05b99e8763436" dependencies = [ "js-sys", "wasm-bindgen", @@ -3916,15 +3966,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-sys" -version = "0.45.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75283be5efb2831d37ea142365f009c02ec203cd29a3ebecbc093d52315b66d0" -dependencies = [ - "windows-targets 0.42.2", -] - [[package]] name = "windows-sys" version = "0.48.0" @@ -3961,21 +4002,6 @@ dependencies = [ "windows-link", ] -[[package]] -name = "windows-targets" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e5180c00cd44c9b1c88adb3693291f1cd93605ded80c250a75d472756b4d071" -dependencies = [ - "windows_aarch64_gnullvm 0.42.2", - "windows_aarch64_msvc 0.42.2", - "windows_i686_gnu 0.42.2", - "windows_i686_msvc 0.42.2", - "windows_x86_64_gnu 0.42.2", - "windows_x86_64_gnullvm 0.42.2", - "windows_x86_64_msvc 0.42.2", -] - [[package]] name = "windows-targets" version = "0.48.5" @@ -4024,12 +4050,6 @@ dependencies = [ "windows_x86_64_msvc 0.53.1", ] -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "597a5118570b68bc08d8d59125332c54f1ba9d9adeedeef5b99b02ba2b0698f8" - [[package]] name = "windows_aarch64_gnullvm" version = "0.48.5" @@ -4048,12 +4068,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a9d8416fa8b42f5c947f8482c43e7d89e73a173cead56d044f6a56104a6d1b53" -[[package]] -name = "windows_aarch64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e08e8864a60f06ef0d0ff4ba04124db8b0fb3be5776a5cd47641e942e58c4d43" - [[package]] name = "windows_aarch64_msvc" version = "0.48.5" @@ -4072,12 +4086,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b9d782e804c2f632e395708e99a94275910eb9100b2114651e04744e9b125006" -[[package]] -name = "windows_i686_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c61d927d8da41da96a81f029489353e68739737d3beca43145c8afec9a31a84f" - [[package]] name = "windows_i686_gnu" version = "0.48.5" @@ -4108,12 +4116,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fa7359d10048f68ab8b09fa71c3daccfb0e9b559aed648a8f95469c27057180c" -[[package]] -name = "windows_i686_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44d840b6ec649f480a41c8d80f9c65108b92d89345dd94027bfe06ac444d1060" - [[package]] name = "windows_i686_msvc" version = "0.48.5" @@ -4132,12 +4134,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e7ac75179f18232fe9c285163565a57ef8d3c89254a30685b57d83a38d326c2" -[[package]] -name = "windows_x86_64_gnu" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8de912b8b8feb55c064867cf047dda097f92d51efad5b491dfb98f6bbb70cb36" - [[package]] name = "windows_x86_64_gnu" version = "0.48.5" @@ -4156,12 +4152,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c3842cdd74a865a8066ab39c8a7a473c0778a3f29370b5fd6b4b9aa7df4a499" -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26d41b46a36d453748aedef1486d5c7a85db22e56aff34643984ea85514e94a3" - [[package]] name = "windows_x86_64_gnullvm" version = "0.48.5" @@ -4180,12 +4170,6 @@ version = "0.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0ffa179e2d07eee8ad8f57493436566c7cc30ac536a3379fdf008f47f6bb7ae1" -[[package]] -name = "windows_x86_64_msvc" -version = "0.42.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9aec5da331524158c6d1a4ac0ab1541149c0b9505fde06423b02f5ef0106b9f0" - [[package]] name = "windows_x86_64_msvc" version = "0.48.5" @@ -4206,9 +4190,9 @@ checksum = "d6bbff5f0aada427a1e5a6da5f1f98158182f26556f345ac9e04d36d0ebed650" [[package]] name = "winnow" -version = "1.0.2" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ee1708bef14716a11bae175f579062d4554d95be2c6829f518df847b7b3fdd0" +checksum = "0592e1c9d151f854e6fd382574c3a0855250e1d9b2f99d9281c6e6391af352f1" dependencies = [ "memchr", ] @@ -4265,18 +4249,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "3b065d4f0e55f82fae73202e189638116a87c55ab6b8e6c2721e13dd9d854ad1" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "0b631b19d36a892ab55420c92dbc83ccd79274f25be714855d3074aa71cab639" dependencies = [ "proc-macro2", "quote", @@ -4285,9 +4269,9 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "0ec05a11813ea801ff6d75110ad09cd0824ddba17dfe17128ea0d5f68e6c5272" dependencies = [ "zerofrom-derive", ] diff --git a/Cargo.toml b/Cargo.toml index 5cc2edd..3124889 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,14 +9,15 @@ edition = "2024" rust-version = "1.89.0" [workspace.dependencies] -flix = { path = "crates/flix", version = "=0.0.18", default-features = false } -flix-cli = { path = "crates/cli", version = "=0.0.18", default-features = false } -flix-db = { path = "crates/db", version = "=0.0.18", default-features = false } -flix-fs = { path = "crates/fs", version = "=0.0.18", default-features = false } -flix-model = { path = "crates/model", version = "=0.0.18", default-features = false } -flix-tmdb = { path = "crates/tmdb", version = "=0.0.18", default-features = false } +flix = { path = "crates/flix", version = "=0.0.19", default-features = false } +flix-cli = { path = "crates/cli", version = "=0.0.19", default-features = false } +flix-db = { path = "crates/db", version = "=0.0.19", default-features = false } +flix-fs = { path = "crates/fs", version = "=0.0.19", default-features = false } +flix-model = { path = "crates/model", version = "=0.0.19", default-features = false } +flix-mux = { path = "crates/cli-mux", version = "=0.0.19", default-features = false } +flix-tmdb = { path = "crates/tmdb", version = "=0.0.19", default-features = false } -seamantic = { version = "^0.0.13", default-features = false } +seamantic = { version = "^0.0.14", default-features = false } sea-orm = { version = "=2.0.0-rc.38", default-features = false } sea-orm-migration = { version = "=2.0.0-rc.38", default-features = false } @@ -26,9 +27,12 @@ async-stream = { version = "^0.3", default-features = false } bytes = { version = "^1", default-features = false } chrono = { version = "^0.4", default-features = false } clap = { version = "^4", default-features = false } +console = { version = "^0.16", default-features = false } +dialoguer = { version = "^0.12", default-features = false } either = { version = "^1", default-features = false } futures = { version = "^0.3", default-features = false } governor = { version = "^0.10", default-features = false } +indicatif = { version = "^0.18", default-features = false } itertools = { version = "^0.14", default-features = false } nonzero_ext = { version = "^0.3", default-features = false } redb = { version = "^4", default-features = false } @@ -45,6 +49,7 @@ tracing = { version = "^0.1", default-features = false } tracing-subscriber = { version = "^0.3", default-features = false } url = { version = "^2", default-features = false } url-macro = { version = "^0.2", default-features = false } +walkdir = { version = "^2", default-features = false } [workspace.lints.clippy] arithmetic_side_effects = "forbid" diff --git a/README.md b/README.md index dfdb02e..28d7e2b 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ Libraries and tools for dealing with media metadata - fmt: `cargo fmt --check` - docs: `RUSTDOCFLAGS="--cfg docsrs" cargo +nightly doc --all-features` - install: `cargo install --path crates/cli` +- install: `cargo install --path crates/cli-mux` - semver: `cargo semver-checks --all-features` - publish: `cargo publish --dry-run --workspace` diff --git a/crates/cli-mux/Cargo.toml b/crates/cli-mux/Cargo.toml new file mode 100644 index 0000000..5ee9ea4 --- /dev/null +++ b/crates/cli-mux/Cargo.toml @@ -0,0 +1,57 @@ +[package] +name = "flix-mux" +version = "0.0.19" +license-file.workspace = true + +description = "CLI for bulk media muxing" +repository = "https://github.com/QuantumShade/flix" +categories = ["command-line-utilities"] + +edition.workspace = true +rust-version.workspace = true + +[package.metadata.docs.rs] +all-features = true +rustdoc-args = ["--cfg", "docsrs"] + +[[bin]] +doc = false +name = "flix-mux" +path = "src/main.rs" + +[dependencies] +anyhow = { workspace = true } +clap = { workspace = true, features = [ + "color", + "derive", + "error-context", + "help", + "std", + "suggestions", + "usage", +] } +console = { workspace = true } +dialoguer = { workspace = true } +indicatif = { workspace = true } +serde = { workspace = true, features = ["derive", "std"] } +serde_json = { workspace = true, features = ["alloc"] } +walkdir = { workspace = true } + +[lints.clippy] +arithmetic_side_effects = "deny" +as_conversions = "deny" +checked_conversions = "deny" +default_union_representation = "deny" +expect_used = "deny" +indexing_slicing = "deny" +integer_division = "deny" +integer_division_remainder_used = "deny" +transmute_undefined_repr = "deny" +unchecked_time_subtraction = "deny" +unwrap_used = "deny" + +[lints.rust] +arithmetic_overflow = "forbid" +missing_docs = "forbid" +unsafe_code = "forbid" +unused_doc_comments = "forbid" diff --git a/crates/cli-mux/README.md b/crates/cli-mux/README.md new file mode 100644 index 0000000..46cd49e --- /dev/null +++ b/crates/cli-mux/README.md @@ -0,0 +1,11 @@ +# flix-mux + +[![Crates Version](https://img.shields.io/crates/v/flix-mux.svg)](https://crates.io/crates/flix-mux) + +CLI for bulk media muxing + +## Commands + +```sh +cargo run -- +``` diff --git a/crates/cli-mux/src/cli.rs b/crates/cli-mux/src/cli.rs new file mode 100644 index 0000000..835f64b --- /dev/null +++ b/crates/cli-mux/src/cli.rs @@ -0,0 +1,49 @@ +use std::path::PathBuf; + +use clap::Parser; + +use crate::parser::Selector; + +#[derive(Parser)] +#[command(version, about, long_about = None)] +pub struct Cli { + /// Dry run and print commands + #[arg(short, long)] + dry_run: bool, + + /// Stream selectors + #[arg( + short, + long, + required = true, + value_name = "SEL", + value_delimiter = ';' + )] + selectors: Vec, + + /// The path to the directory to scan + #[arg(value_name = "DIR")] + scan_dir: PathBuf, +} + +impl Cli { + pub fn is_dry(&self) -> bool { + self.dry_run + } + + pub fn selectors(&self) -> &[Selector] { + &self.selectors + } + + pub fn scan_dir_path(&self) -> PathBuf { + fn expect_home_dir() -> PathBuf { + #[allow(clippy::expect_used)] + std::env::home_dir().expect("you do not have a home directory") + } + + match self.scan_dir.strip_prefix("~/") { + Ok(path) => expect_home_dir().join(path), + Err(_) => self.scan_dir.to_owned(), + } + } +} diff --git a/crates/cli-mux/src/main.rs b/crates/cli-mux/src/main.rs new file mode 100644 index 0000000..db13a88 --- /dev/null +++ b/crates/cli-mux/src/main.rs @@ -0,0 +1,66 @@ +//! flix-mux + +use core::time::Duration; + +use clap::Parser; +use console::style; +use indicatif::{HumanBytes, ProgressBar, ProgressStyle}; + +use crate::mux::mux_files; +use crate::scan::scan_directory; + +mod cli; +mod model; +mod mux; +mod parser; +mod probe; +mod scan; + +fn main() { + let cli = cli::Cli::parse(); + + let (files, size) = scan_directory( + &cli.scan_dir_path(), + || { + let progress = ProgressBar::new_spinner(); + progress.set_message(format!("Scanning {:?}", &cli.scan_dir_path())); + progress.enable_steady_tick(Duration::from_millis(50)); + progress + }, + |progress| progress.finish(), + |len| { + let progress = ProgressBar::new(u64::try_from(len).unwrap_or(0)); + progress.set_style( + #[expect(clippy::expect_used)] + ProgressStyle::with_template("[{elapsed_precise}] {wide_bar} {pos}/{len} ({msg})") + .expect("static template"), + ); + progress + }, + |progress| progress.inc(1), + |progress| progress.finish_and_clear(), + |progress, msg| { + progress.suspend(|| eprintln!("{} {}", style("[WARN]").bold().yellow(), msg)) + }, + ); + println!("Found {} files ({})", files.len(), HumanBytes(size)); + + mux_files( + cli.is_dry(), + &files, + cli.selectors(), + |len| { + let progress = ProgressBar::new(u64::try_from(len).unwrap_or(0)); + progress.set_style( + #[expect(clippy::expect_used)] + ProgressStyle::with_template("[{elapsed_precise}] {wide_bar} {pos}/{len} ({msg})") + .expect("static template"), + ); + progress.enable_steady_tick(Duration::from_secs(1)); + progress + }, + |progress| progress.inc(1), + |progress| progress.finish_with_message("done"), + |progress, msg| progress.suspend(|| eprintln!("{} {}", style("[ERR]").bold().red(), msg)), + ); +} diff --git a/crates/cli-mux/src/model.rs b/crates/cli-mux/src/model.rs new file mode 100644 index 0000000..ffd5756 --- /dev/null +++ b/crates/cli-mux/src/model.rs @@ -0,0 +1,101 @@ +use std::path::PathBuf; + +use serde::Deserialize; + +#[derive(Debug, Clone)] +pub struct MediaFile { + pub path: PathBuf, + pub byte_size: u64, + pub streams: Streams, +} + +#[derive(Debug, Clone)] +pub struct Streams { + pub video: Vec, + pub audio: Vec, + pub subtitle: Vec, +} + +pub trait FFStream: serde::de::DeserializeOwned { + const FF_TYPE_NAME: &str; +} + +#[derive(Debug, Clone, Deserialize)] +pub struct VideoStream { + codec_name: String, + tags: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct VideoTags { + language: Option, +} + +impl VideoStream { + pub fn codec(&self) -> &str { + &self.codec_name + } + + pub fn language(&self) -> Option<&str> { + self.tags.as_ref()?.language.as_deref() + } +} + +impl FFStream for VideoStream { + const FF_TYPE_NAME: &str = "v"; +} + +#[derive(Debug, Clone, Deserialize)] +pub struct AudioStream { + codec_name: String, + tags: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct AudioTags { + language: Option, +} + +impl AudioStream { + pub fn codec(&self) -> &str { + &self.codec_name + } + + pub fn language(&self) -> Option<&str> { + self.tags.as_ref()?.language.as_deref() + } +} + +impl FFStream for AudioStream { + const FF_TYPE_NAME: &str = "a"; +} + +#[derive(Debug, Clone, Deserialize)] +pub struct SubtitleStream { + codec_name: String, + tags: Option, +} + +#[derive(Debug, Clone, Deserialize)] +pub struct SubtitleTags { + language: Option, + title: Option, +} + +impl SubtitleStream { + pub fn codec(&self) -> &str { + &self.codec_name + } + + pub fn language(&self) -> Option<&str> { + self.tags.as_ref()?.language.as_deref() + } + + pub fn title(&self) -> Option<&str> { + self.tags.as_ref()?.title.as_deref() + } +} + +impl FFStream for SubtitleStream { + const FF_TYPE_NAME: &str = "s"; +} diff --git a/crates/cli-mux/src/mux.rs b/crates/cli-mux/src/mux.rs new file mode 100644 index 0000000..8b4e025 --- /dev/null +++ b/crates/cli-mux/src/mux.rs @@ -0,0 +1,227 @@ +use std::process::Command; + +use anyhow::{Context as _, Result}; + +use crate::model::MediaFile; +use crate::parser::{Matcher, Selector, StreamFlag, StreamType}; + +pub fn mux_files( + dry_run: bool, + files: &[MediaFile], + selectors: &[Selector], + fixed_length_start: impl FnOnce(usize) -> T, + fixed_length_update: impl Fn(&mut T), + fixed_length_end: impl FnOnce(T), + print_fn: impl Fn(&T, &str), +) { + let mut progress = fixed_length_start(files.len()); + for file in files { + if let Err(err) = mux(dry_run, file, selectors) { + print_fn(&progress, &format!("{:?}", err)); + } + fixed_length_update(&mut progress); + } + fixed_length_end(progress); +} + +#[expect(clippy::expect_used)] +fn mux(dry_run: bool, file: &MediaFile, selectors: &[Selector]) -> Result<()> { + let mut command = Command::new("ffmpeg"); + let mut command = command.args(["-v", "error"]); + + command = command.arg("-i"); + command = command.arg(file.path.as_os_str()); + + for selector in selectors { + command = command.args( + make_map_args(file, selector) + .with_context(|| format!("Failed to mux {:?}", file.path))?, + ); + } + + command = command.args(["-c:v", "copy", "-c:a", "copy", "-c:s", "mov_text"]); + command = command.args(["-movflags", "faststart+disable_chpl+write_colr"]); + command = command.args(["-map_chapters", "-1"]); + command = command.args(["-map_metadata", "-1"]); + command = command.args(["-metadata:g", "encoding_tool=Skrundzflix"]); + + for selector in selectors { + command = command.args( + make_metadata_args(file, selector) + .with_context(|| format!("Failed to mux {:?}", file.path))?, + ); + } + + let temp_path = file.path.with_extension("mp4"); + command = command.arg(temp_path.file_name().expect("file name exists")); + + if dry_run { + print_command(command); + } else { + let output = command + .output() + .with_context(|| format!("Failed to mux {:?}", file.path))?; + + if !output.status.success() { + anyhow::bail!( + "ffmpeg failed for {:?}:\n\n{}", + file.path, + String::from_utf8_lossy(&output.stderr) + ); + } + } + + Ok(()) +} + +fn make_map_args(file: &MediaFile, selector: &Selector) -> Result> { + let source_index = 0; + let stream_type = selector.stream_type.as_ref(); + let Some(stream_index) = find_stream_index(file, selector) else { + if selector.optional { + return Ok(vec![]); + } else { + anyhow::bail!("unsatisfied stream selection"); + } + }; + + Ok(vec![ + String::from("-map"), + format!("{}:{}:{}", source_index, stream_type, stream_index), + ]) +} + +fn make_metadata_args(file: &MediaFile, selector: &Selector) -> Result> { + let stream_type = selector.stream_type.as_ref(); + let Some(stream_index) = find_stream_index(file, selector) else { + if selector.optional { + return Ok(vec![]); + } else { + anyhow::bail!("unsatisfied stream selection"); + } + }; + + let stream_language = selector.language(); + + let mut args = vec![ + format!("-metadata:s:{}:{}", stream_type, stream_index), + format!("language={}", stream_language), + ]; + + if selector.stream_type == StreamType::Subtitle { + let sub_title = match selector.flag { + Some(StreamFlag::Forced) => "Forced", + Some(StreamFlag::Sdh) => "SDH", + None => match stream_language { + "eng" => "English", + "jpn" => "Japanese", + _ => anyhow::bail!("Unhandled subtitle language: {}", stream_language), + }, + }; + + args.push(format!("-metadata:s:s:{}", stream_index)); + args.push(format!("title={}", sub_title)); + } + + Ok(args) +} + +fn find_stream_index(file: &MediaFile, selector: &Selector) -> Option { + let needs_forced = selector.flag == Some(StreamFlag::Forced); + let needs_sdh = selector.flag == Some(StreamFlag::Sdh); + + match selector.stream_type { + StreamType::Video => match selector.matcher { + Matcher::Index(index) => (file.streams.video.len() > index).then_some(index), + Matcher::Language(ref language) => file + .streams + .video + .iter() + .enumerate() + .filter(|(_, c)| c.language() == Some(language.as_str())) + .map(|(i, _)| i) + .next(), + Matcher::Codec(ref codec) => file + .streams + .video + .iter() + .enumerate() + .filter(|(_, c)| c.codec() == codec) + .map(|(i, _)| i) + .next(), + }, + StreamType::Audio => match selector.matcher { + Matcher::Index(index) => (file.streams.audio.len() > index).then_some(index), + Matcher::Language(ref language) => file + .streams + .audio + .iter() + .enumerate() + .filter(|(_, c)| c.language() == Some(language.as_str())) + .map(|(i, _)| i) + .next(), + Matcher::Codec(ref codec) => file + .streams + .audio + .iter() + .enumerate() + .filter(|(_, c)| c.codec() == codec) + .map(|(i, _)| i) + .next(), + }, + StreamType::Subtitle => match selector.matcher { + Matcher::Index(index) => (file.streams.subtitle.len() > index).then_some(index), + Matcher::Language(ref language) => { + file.streams + .subtitle + .iter() + .enumerate() + .filter(|(_, c)| c.language() == Some(language.as_str())) + .filter(|(_, c)| { + c.title() + .unwrap_or_default() + .to_ascii_lowercase() + .contains("forced") == needs_forced + }) + .filter(|(_, c)| { + c.title() + .unwrap_or_default() + .to_ascii_lowercase() + .contains("sdh") == needs_sdh + }) + .map(|(i, _)| i) + .next() + } + Matcher::Codec(ref codec) => file + .streams + .subtitle + .iter() + .enumerate() + .filter(|(_, c)| c.codec() == codec) + .map(|(i, _)| i) + .next(), + }, + } +} + +fn print_command(cmd: &Command) { + let program = cmd.get_program().to_string_lossy(); + + let args = cmd + .get_args() + .map(|a| shell_escape(a.to_string_lossy().as_ref())) + .collect::>() + .join(" "); + + println!("{} {}", program, args); +} + +fn shell_escape(s: &str) -> String { + if s.chars() + .all(|c| c.is_ascii_alphanumeric() || "-_./".contains(c)) + { + s.to_string() + } else { + format!("{:?}", s) + } +} diff --git a/crates/cli-mux/src/parser.rs b/crates/cli-mux/src/parser.rs new file mode 100644 index 0000000..9933d22 --- /dev/null +++ b/crates/cli-mux/src/parser.rs @@ -0,0 +1,159 @@ +use core::error::Error; +use core::fmt; +use core::str::FromStr; + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum StreamType { + Video, + Audio, + Subtitle, +} + +impl AsRef for StreamType { + fn as_ref(&self) -> &str { + match self { + StreamType::Video => "v", + StreamType::Audio => "a", + StreamType::Subtitle => "s", + } + } +} + +impl FromStr for StreamType { + type Err = ParseSelectorError; + + fn from_str(s: &str) -> Result { + match s { + "v" => Ok(StreamType::Video), + "a" => Ok(StreamType::Audio), + "s" => Ok(StreamType::Subtitle), + other => Err(ParseSelectorError::InvalidStreamType(other.to_string())), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub enum Matcher { + Index(usize), + Language(String), + Codec(String), +} + +impl FromStr for Matcher { + type Err = ParseSelectorError; + + fn from_str(s: &str) -> Result { + if let Ok(idx) = s.parse::() { + return Ok(Matcher::Index(idx)); + } + + if s.len() == 3 { + return Ok(Matcher::Language(s.to_ascii_lowercase())); + } + Ok(Matcher::Codec(s.to_ascii_lowercase())) + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum StreamFlag { + Forced, + Sdh, +} + +impl FromStr for StreamFlag { + type Err = ParseSelectorError; + + fn from_str(s: &str) -> Result { + match s.to_ascii_lowercase().as_str() { + "forced" => Ok(StreamFlag::Forced), + "sdh" => Ok(StreamFlag::Sdh), + other => Err(ParseSelectorError::InvalidFlag(other.to_string())), + } + } +} + +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct Selector { + pub stream_type: StreamType, + pub matcher: Matcher, + pub flag: Option, + pub optional: bool, + pub out_lang: String, +} + +impl Selector { + pub fn language(&self) -> &str { + &self.out_lang + } +} + +impl FromStr for Selector { + type Err = ParseSelectorError; + + fn from_str(input: &str) -> Result { + if input.is_empty() { + return Err(ParseSelectorError::Empty); + } + + let (input, optional) = input + .strip_suffix('?') + .map_or((input, false), |s| (s, true)); + + let (left, out_lang) = input.split_once('>').unwrap_or((input, "")); + + let mut parts = left.splitn(3, ':'); + + let stream_type: StreamType = parts + .next() + .ok_or(ParseSelectorError::InvalidFormat)? + .parse()?; + + let matcher: Matcher = parts + .next() + .ok_or(ParseSelectorError::InvalidFormat)? + .parse()?; + + let flag = parts + .next() + .filter(|s| !s.is_empty()) + .map(str::parse) + .transpose()?; + + let out_lang = match (out_lang.is_empty(), &matcher) { + (false, _) => out_lang.to_owned(), + (true, Matcher::Language(language)) => language.clone(), + (true, _) => return Err(ParseSelectorError::UnspecifiedLanguage), + }; + + Ok(Selector { + stream_type, + matcher, + flag, + optional, + out_lang, + }) + } +} + +#[derive(Debug)] +pub enum ParseSelectorError { + Empty, + InvalidFormat, + InvalidStreamType(String), + InvalidFlag(String), + UnspecifiedLanguage, +} + +impl Error for ParseSelectorError {} + +impl fmt::Display for ParseSelectorError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + Self::Empty => write!(f, "selector was empty"), + Self::InvalidFormat => write!(f, "invalid selector format"), + Self::InvalidStreamType(s) => write!(f, "invalid stream type '{}'", s), + Self::InvalidFlag(s) => write!(f, "invalid stream flag '{}'", s), + Self::UnspecifiedLanguage => write!(f, "unspecified output language"), + } + } +} diff --git a/crates/cli-mux/src/probe.rs b/crates/cli-mux/src/probe.rs new file mode 100644 index 0000000..595420c --- /dev/null +++ b/crates/cli-mux/src/probe.rs @@ -0,0 +1,53 @@ +use std::os::unix::fs::MetadataExt; +use std::process::Command; + +use anyhow::{Context as _, Result}; +use serde::Deserialize; +use walkdir::DirEntry; + +use crate::model::{FFStream, MediaFile, Streams}; + +#[derive(Debug, Deserialize)] +struct FFProbeOutput { + streams: Vec, +} + +fn probe_file_streams(entry: &DirEntry) -> Result> { + let output = Command::new("ffprobe") + .args([ + "-v", + "error", + "-output_format", + "json", + "-show_streams", + "-select_streams", + S::FF_TYPE_NAME, + #[expect(clippy::expect_used)] + entry.path().to_str().expect("path should be utf8"), + ]) + .output() + .with_context(|| format!("Failed to run ffprobe on {:?}", entry.path()))?; + + if !output.status.success() { + anyhow::bail!( + "ffprobe failed for {:?}:\n\n{}", + entry.path(), + String::from_utf8_lossy(&output.stderr) + ); + } + + let parsed: FFProbeOutput = serde_json::from_slice(&output.stdout)?; + Ok(parsed.streams) +} + +pub fn probe_file(entry: &DirEntry) -> Result { + Ok(MediaFile { + path: entry.path().to_path_buf(), + byte_size: entry.metadata()?.size(), + streams: Streams { + video: probe_file_streams(entry)?, + audio: probe_file_streams(entry)?, + subtitle: probe_file_streams(entry)?, + }, + }) +} diff --git a/crates/cli-mux/src/scan.rs b/crates/cli-mux/src/scan.rs new file mode 100644 index 0000000..6e592f6 --- /dev/null +++ b/crates/cli-mux/src/scan.rs @@ -0,0 +1,58 @@ +use std::path::Path; + +use walkdir::WalkDir; + +use crate::model::MediaFile; +use crate::probe::probe_file; + +pub fn scan_directory( + path: &Path, + unknown_length_start: impl FnOnce() -> T, + unknown_length_end: impl FnOnce(T), + fixed_length_start: impl FnOnce(usize) -> T, + fixed_length_update: impl Fn(&mut T), + fixed_length_end: impl FnOnce(T), + print_fn: impl Fn(&T, &str), +) -> (Vec, u64) { + let spinner = unknown_length_start(); + let files: Vec<_> = WalkDir::new(path) + .into_iter() + .filter_map(Result::ok) + .filter(|e| e.file_type().is_file()) + .filter(|e| { + let is_mkv = e + .path() + .extension() + .unwrap_or_default() + .eq_ignore_ascii_case("mkv"); + let is_mp4 = e + .path() + .extension() + .unwrap_or_default() + .eq_ignore_ascii_case("mp4"); + is_mkv || is_mp4 + }) + .collect(); + unknown_length_end(spinner); + + let mut progress = fixed_length_start(files.len()); + let mut total_byte_size = 0u64; + let files: Vec<_> = files + .iter() + .filter_map(|entry| { + let file = match probe_file(entry) { + Ok(file) => Some(file), + Err(err) => { + print_fn(&progress, &format!("{:?}", err)); + None + } + }; + let size = file.as_ref().map(|r| r.byte_size).unwrap_or_default(); + total_byte_size = total_byte_size.saturating_add(size); + fixed_length_update(&mut progress); + file + }) + .collect(); + fixed_length_end(progress); + (files, total_byte_size) +} diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 8be4602..2ae07ad 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix-cli" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "CLI for interacting with a flix database" diff --git a/crates/cli/README.md b/crates/cli/README.md index 7098d7d..59bd92b 100644 --- a/crates/cli/README.md +++ b/crates/cli/README.md @@ -5,6 +5,7 @@ CLI for interacting with a flix database ## Commands + ```sh cargo run -- init cargo run -- add tmdb movie diff --git a/crates/cli/src/cli/mod.rs b/crates/cli/src/cli/mod.rs index 7352aa3..3d65dc1 100644 --- a/crates/cli/src/cli/mod.rs +++ b/crates/cli/src/cli/mod.rs @@ -10,7 +10,12 @@ pub mod tmdb; #[command(version, about, long_about = None)] pub struct Cli { /// Use a custom config file - #[arg(short, long, value_name = "FILE", default_value = "~/.flix")] + #[arg( + short, + long, + value_name = "FILE", + default_value = "~/.config/flix/config.toml" + )] config: PathBuf, /// Use a custom cache file diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 4bc95f2..430e74f 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -30,11 +30,9 @@ async fn main() -> Result<()> { let database_path = cli.database_path()?; - let client = Client::new( - tmdb::Config::new(config.tmdb().bearer_token().to_owned()), - Rc::new(RedbCache::new(cli.cache_path())?), - CachePolicy::Full, - ); + let config = tmdb::Config::new(config.tmdb().bearer_token().to_owned()); + let cache = Rc::new(RedbCache::new(cli.cache_path())?); + let client = Client::new(config, cache, CachePolicy::Full); if cli.trace { tracing_subscriber::fmt() diff --git a/crates/cli/src/run/flix.rs b/crates/cli/src/run/flix.rs index 22e5750..5733ac4 100644 --- a/crates/cli/src/run/flix.rs +++ b/crates/cli/src/run/flix.rs @@ -48,12 +48,12 @@ pub async fn add( }) .await; - let flix_id = match result { - Ok(id) => id, + match result { + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; - println!("Created Collection: {} [{}]", title, flix_id.into_raw()); + println!("Created Collection: {}", title); Ok(()) } @@ -93,18 +93,12 @@ pub async fn add( }) .await; - let (flix_show, season_number, episode_number) = match result { - Ok(id) => id, + match result { + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; - println!( - "Created Episode: {} [{} S{} E{}]", - title, - flix_show.into_raw(), - season_number, - episode_number - ); + println!("Created Episode: {}", title); Ok(()) } diff --git a/crates/cli/src/run/tmdb.rs b/crates/cli/src/run/tmdb.rs index 92741a0..cdfb03a 100644 --- a/crates/cli/src/run/tmdb.rs +++ b/crates/cli/src/run/tmdb.rs @@ -83,12 +83,12 @@ pub async fn add( }) .await; - let flix_id = match result { - Ok(id) => id, + match result { + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; - println!("Created Collection: {} [{}]", title, flix_id.into_raw()); + println!("Created Collection: {}", title); Ok(()) } @@ -151,17 +151,12 @@ pub async fn add( }) .await; - let flix_id = match result { - Ok(id) => id, + match result { + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; - println!( - "Created Movie: {} ({}) [{}]", - title, - year, - flix_id.into_raw(), - ); + println!("Created Movie: {} ({})", title, year); Ok(()) } @@ -215,18 +210,22 @@ pub async fn add( let mut season_episodes = Vec::new(); for episode in 1..=number_of_episodes { let episode = EpisodeNumber::new(episode); - let Ok(episode) = client + let episode = match client .episodes() .get_details(id, season.season_number, episode, None) .await - else { - eprintln!( - "skipping episode ({}, {}, {})", - id.into_raw(), - season.season_number, - episode - ); - break; + { + Ok(value) => value, + Err(err) => { + eprintln!( + "skipping episode ({}, {}, {}) - {}", + id.into_raw(), + season.season_number, + episode, + err + ); + break; + } }; season_episodes.push(episode); } @@ -329,17 +328,12 @@ pub async fn add( }) .await; - let flix_id = match result { - Ok(id) => id, + match result { + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; - println!( - "Created Show: {} ({}) [{}]", - title, - year, - flix_id.into_raw() - ); + println!("Created Show: {} ({})", title, year); Ok(()) } @@ -380,18 +374,22 @@ pub async fn add( for episode in 1..=number_of_episodes { let episode = EpisodeNumber::new(episode); - let Ok(episode) = client + let episode = match client .episodes() .get_details(id, season.season_number, episode, None) .await - else { - eprintln!( - "skipping episode ({}, {}, {})", - id.into_raw(), - season.season_number, - episode - ); - break; + { + Ok(value) => value, + Err(err) => { + eprintln!( + "skipping episode ({}, {}, {}) - {}", + id.into_raw(), + season.season_number, + episode, + err + ); + break; + } }; episodes.push(episode); } @@ -451,7 +449,7 @@ pub async fn add( .await; match result { - Ok(_) => (), + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; @@ -541,7 +539,7 @@ pub async fn add( .await; match result { - Ok(_) => (), + Ok(_) => {} Err(TransactionError::Connection(err)) => Err(err)?, Err(TransactionError::Transaction(err)) => Err(err)?, }; @@ -637,7 +635,7 @@ pub async fn update(client: Client, db: &DatabaseConnection, command: Command) - // Err(TransactionError::Connection(err)) => Err(err)?, // Err(TransactionError::Transaction(err)) => Err(err)?, // }; - // println!("Created Collection: {} [{}]", title, flix_id.into_raw()); + // println!("Created Collection: {}", title, flix_id.into_raw()); // Ok(()) // } @@ -706,7 +704,7 @@ pub async fn update(client: Client, db: &DatabaseConnection, command: Command) - // Err(TransactionError::Transaction(err)) => Err(err)?, // }; // println!( - // "Created Movie: {} ({}) [{}]", + // "Created Movie: {} ({})", // title, // year, // flix_id.into_raw(), @@ -884,7 +882,7 @@ pub async fn update(client: Client, db: &DatabaseConnection, command: Command) - // Err(TransactionError::Transaction(err)) => Err(err)?, // }; // println!( - // "Created Show: {} ({}) [{}]", + // "Created Show: {} ({})", // title, // year, // flix_id.into_raw() diff --git a/crates/db/Cargo.toml b/crates/db/Cargo.toml index d6bd9cd..4c94051 100644 --- a/crates/db/Cargo.toml +++ b/crates/db/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix-db" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "Types for storing persistent data about media" diff --git a/crates/db/src/entity/content.rs b/crates/db/src/entity/content.rs index 8ef625d..a0da637 100644 --- a/crates/db/src/entity/content.rs +++ b/crates/db/src/entity/content.rs @@ -4,6 +4,7 @@ pub mod libraries { use flix_model::id::LibraryId; + use seamantic::model::duration::Seconds; use seamantic::model::path::PathBytes; use chrono::{DateTime, Utc}; @@ -20,7 +21,9 @@ pub mod libraries { /// The library's directory pub directory: PathBytes, /// The library's last scan data - pub last_scan: Option>, + pub last_scan_date: Option>, + /// The library's last scan duration + pub last_scan_duration: Option, /// Collections that are part of this library #[sea_orm(has_many)] @@ -415,7 +418,8 @@ pub mod test { $crate::entity::content::libraries::ActiveModel { id: Set(::flix_model::id::LibraryId::from_raw($id)), directory: Set(::std::path::PathBuf::new().into()), - last_scan: Set(None), + last_scan_date: Set(None), + last_scan_duration: Set(None), } .insert($db) .await @@ -522,10 +526,13 @@ pub mod test { #[cfg(test)] mod tests { + use core::time::Duration; use std::path::Path; use flix_model::id::{CollectionId, LibraryId, MovieId, ShowId}; + use seamantic::model::duration::Seconds; + use chrono::NaiveDate; use sea_orm::ActiveValue::{NotSet, Set}; use sea_orm::entity::prelude::*; @@ -566,7 +573,8 @@ mod tests { assert_eq!(model.id, LibraryId::from_raw($id)); assert_eq!(model.directory, Path::new(concat!("L Directory ", $id)).to_owned().into()); - assert_eq!(model.last_scan, noneable!(last_scan, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt").and_hms_opt(0, 0, 0).expect("and_hms_opt").and_utc() $(, $($skip),+)?)); + assert_eq!(model.last_scan_date, noneable!(last_scan_date, NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt").and_hms_opt(0, 0, 0).expect("and_hms_opt").and_utc() $(, $($skip),+)?)); + assert_eq!(model.last_scan_duration, noneable!(last_scan_duration, Seconds(Duration::from_secs($id)) $(, $($skip),+)?)); }; ($db:expr, $id:literal, $error:ident $(; $($skip:ident),+)?) => { let model = assert_library!(@insert, $db, $id $(; $($skip),+)?) @@ -578,7 +586,8 @@ mod tests { super::libraries::ActiveModel { id: notsettable!(id, LibraryId::from_raw($id) $(, $($skip),+)?), directory: notsettable!(directory, Path::new(concat!("L Directory ", $id)).to_owned().into() $(, $($skip),+)?), - last_scan: notsettable!(last_scan, Some(NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt").and_hms_opt(0, 0, 0).expect("and_hms_opt").and_utc()) $(, $($skip),+)?), + last_scan_date: notsettable!(last_scan_date, Some(NaiveDate::from_yo_opt($id, 1).expect("from_yo_opt").and_hms_opt(0, 0, 0).expect("and_hms_opt").and_utc()) $(, $($skip),+)?), + last_scan_duration: notsettable!(last_scan_duration, Some(Seconds(Duration::from_secs($id))) $(, $($skip),+)?), }.insert($db).await }; } @@ -588,7 +597,8 @@ mod tests { assert_library!(&db, 2, Success); assert_library!(&db, 3, Success; id); assert_library!(&db, 4, NotNullViolation; directory); - assert_library!(&db, 5, Success; last_scan); + assert_library!(&db, 5, Success; last_scan_date); + assert_library!(&db, 6, Success; last_scan_duration); } #[tokio::test] diff --git a/crates/flix/Cargo.toml b/crates/flix/Cargo.toml index 0b9db7b..8fc3ac4 100644 --- a/crates/flix/Cargo.toml +++ b/crates/flix/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "Mechanisms for interacting with flix media" diff --git a/crates/fs/Cargo.toml b/crates/fs/Cargo.toml index ecb2800..8cba725 100644 --- a/crates/fs/Cargo.toml +++ b/crates/fs/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix-fs" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "Filesystem scanner for flix media" diff --git a/crates/fs/src/scanner/generic.rs b/crates/fs/src/scanner/generic.rs index 3456b79..c114300 100644 --- a/crates/fs/src/scanner/generic.rs +++ b/crates/fs/src/scanner/generic.rs @@ -72,11 +72,12 @@ impl From for Scanner { impl Scanner { /// Helper function for stripping allowed numerical prefixes for sorting ("01 - ") - fn strip_numeric_prefix(mut s: &str) -> &str { + fn strip_numeric_prefix(original: &str) -> &str { + let mut s = original; while let Some('0'..='9') = s.chars().next() { s = &s[1..] } - s.strip_prefix(" - ").unwrap_or(s) + s.strip_prefix(" - ").unwrap_or(original) } /// Detect the type of a folder and call the correct scanner. Use diff --git a/crates/fs/src/scanner/mod.rs b/crates/fs/src/scanner/mod.rs index 334ce73..aeddde4 100644 --- a/crates/fs/src/scanner/mod.rs +++ b/crates/fs/src/scanner/mod.rs @@ -27,6 +27,16 @@ pub enum MediaRef { Slug(String), } +impl MediaRef { + /// Get the slug if it exists + pub fn into_slug(self) -> Option { + match self { + MediaRef::Id(_) => None, + MediaRef::Slug(slug) => Some(slug), + } + } +} + /// A scanned collection #[derive(Debug)] pub struct CollectionScan { diff --git a/crates/model/Cargo.toml b/crates/model/Cargo.toml index 96f4956..62018ad 100644 --- a/crates/model/Cargo.toml +++ b/crates/model/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix-model" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "Core types for flix data" diff --git a/crates/model/src/text.rs b/crates/model/src/text.rs index c3939a5..b3012c3 100644 --- a/crates/model/src/text.rs +++ b/crates/model/src/text.rs @@ -12,22 +12,25 @@ fn split_normalized_words(input: &str) -> impl Iterator { panic!("Input is not ASCII: {input}"); } - input.split_ascii_whitespace().map(|s| { - let chars = s - .chars() - .filter(|c| c.is_ascii_alphanumeric() || *c == '-') - .map(|c| c.to_ascii_lowercase()); + input + .split_ascii_whitespace() + .map(|s| { + let chars = s + .chars() + .filter(|c| c.is_ascii_alphanumeric() || *c == '-') + .map(|c| c.to_ascii_lowercase()); - if s.len() > 4 - && s.len().is_multiple_of(2) - && chars.clone().tuples().all(|(l, r)| l != '.' && r == '.') - { - // Collapse acronym - chars.tuples().map(|(l, _)| l).collect() - } else { - chars.collect() - } - }) + if s.len() > 4 + && s.len().is_multiple_of(2) + && chars.clone().tuples().all(|(l, r)| l != '.' && r == '.') + { + // Collapse acronym + chars.tuples().map(|(l, _)| l).collect() + } else { + chars.collect() + } + }) + .filter(|part: &String| !part.is_empty()) } fn split_leading_article>(iter: I) -> (Option, Peekable) { diff --git a/crates/tmdb/Cargo.toml b/crates/tmdb/Cargo.toml index 6365e15..d82b763 100644 --- a/crates/tmdb/Cargo.toml +++ b/crates/tmdb/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "flix-tmdb" -version = "0.0.18" +version = "0.0.19" license-file.workspace = true description = "Clients and models for fetching data from TMDB" diff --git a/crates/tmdb/src/model/episode.rs b/crates/tmdb/src/model/episode.rs index 866c7e5..40a95b4 100644 --- a/crates/tmdb/src/model/episode.rs +++ b/crates/tmdb/src/model/episode.rs @@ -3,8 +3,9 @@ use core::time::Duration; use flix_model::numbers::EpisodeNumber; use chrono::NaiveDate; +use url::Url; -use super::duration_from_minutes; +use super::{duration_from_minutes, still_url_from_path}; /// A deserialized Episode from the TMDB API #[derive(Debug, Clone, serde::Deserialize)] @@ -18,7 +19,10 @@ pub struct Episode { pub overview: String, /// The episode's air date pub air_date: NaiveDate, - /// The movie's runtime + /// The episode's runtime #[serde(deserialize_with = "duration_from_minutes")] pub runtime: Duration, + /// The episode's still path + #[serde(deserialize_with = "still_url_from_path")] + pub still_path: Option, } diff --git a/crates/tmdb/src/model/mod.rs b/crates/tmdb/src/model/mod.rs index 45e50db..d7f2bc5 100644 --- a/crates/tmdb/src/model/mod.rs +++ b/crates/tmdb/src/model/mod.rs @@ -1,8 +1,10 @@ //! Deserializable types from the TMDB API +use core::str::FromStr; use core::time::Duration; use serde::{Deserialize, Deserializer}; +use url::Url; pub mod id; @@ -22,6 +24,24 @@ fn duration_from_minutes<'de, D>(deserializer: D) -> Result where D: Deserializer<'de>, { - let minutes = u64::deserialize(deserializer)?; + let minutes = u64::deserialize(deserializer).unwrap_or(0); Ok(Duration::from_secs(minutes.saturating_mul(60))) } + +fn still_url_from_path<'de, D>(deserializer: D) -> Result, D::Error> +where + D: Deserializer<'de>, +{ + const TMDB_IMAGE_BASE: &str = "http://image.tmdb.org/t/p/"; + const TMDB_IMAGE_QUALITY: &str = "original"; + + let path = Option::<&str>::deserialize(deserializer)?; + + Ok(path.and_then(|path| { + Url::from_str(&format!( + "{}{}{}", + TMDB_IMAGE_BASE, TMDB_IMAGE_QUALITY, path + )) + .ok() + })) +} diff --git a/flix.sh b/flix.sh index 9ce0bdd..17f785d 100755 --- a/flix.sh +++ b/flix.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash -cd "$(dirname "$0")" +cd "$(dirname "$0")" || exit 1 # Init database rm flix.db -cargo run -- init +flix init ############### @@ -12,81 +12,914 @@ cargo run -- init ############### # DC -cargo run -- add flix collection "DC Collection" "" -cargo run -- add tmdb show 60708 # Gotham (2014) +flix add flix collection "DC Collection" "" +flix add tmdb collection 1025281 # Constantine Collection +flix add tmdb movie 561 # Constantine (2005) +flix add tmdb collection 263 # The Dark Knight Collection +flix add tmdb movie 272 # Batman Begins (2005) +flix add tmdb movie 155 # The Dark Knight (2008) +flix add tmdb movie 49026 # The Dark Knight Rises (2012) +flix add tmdb movie 44912 # Green Lantern (2011) +flix add tmdb show 60708 # Gotham (2014) +flix add tmdb show 71340 # Krypton (2018) +flix add tmdb movie 13455 # Push (2009) # DCEU -cargo run -- add --sort-title "dceu" flix collection "Worlds of DC" "American media franchise and shared universe that is centered on a series of superhero films, distributed by Warner Bros. Pictures and based on characters that appear in American comic books by DC Comics." -cargo run -- add tmdb collection 573693 # Aquaman Collection -cargo run -- add tmdb movie 297802 # Aquaman (2018) -cargo run -- add tmdb movie 572802 # Aquaman and the Lost Kingdom (2023) +flix add --sort-title "dceu" flix collection "Worlds of DC" "American media franchise and shared universe that is centered on a series of superhero films, distributed by Warner Bros. Pictures and based on characters that appear in American comic books by DC Comics." +flix add tmdb collection 573693 # Aquaman Collection +flix add tmdb movie 297802 # Aquaman (2018) +flix add tmdb movie 572802 # Aquaman and the Lost Kingdom (2023) +flix add tmdb movie 495764 # Birds of Prey (and the Fantabulous Emancipation of One Harley Quinn) (2020) +flix add tmdb collection 531242 # Suicide Squad Collection +flix add tmdb movie 297761 # Suicide Squad (2016) +flix add tmdb movie 436969 # The Suicide Squad (2021) +flix add tmdb collection 468552 # Wonder Woman Collection +flix add tmdb movie 297762 # Wonder Woman (2017) +flix add tmdb movie 464052 # Wonder Woman 1984 (2020) # Marvel -cargo run -- add --sort-title "marvel" flix collection "In Association With Marvel" "Movies based on Marvel Comics properties not produced by Marvel Studios" -cargo run -- add --fs-slug "cloak and dagger (2018)" --web-slug "cloak-and-dagger-2018" tmdb show 66190 # Marvel's Cloak & Dagger (2018) -cargo run -- add --fs-slug "daredevil (2015)" --web-slug "daredevil-2015" tmdb show 61889 # Marvel's Daredevil (2015) -cargo run -- add --fs-slug "inhumans (2017)" --web-slug "inhumans-2017" tmdb show 68716 # Marvel's Inhumans (2017) -cargo run -- add --fs-slug "iron fist (2017)" --web-slug "iron-fist-2017" tmdb show 62127 # Marvel's Iron Fist (2017) -cargo run -- add --fs-slug "jessica jones (2015)" --web-slug "jessica-jones-2015" tmdb show 38472 # Marvel's Jessica Jones (2015) -cargo run -- add --fs-slug "luke cage (2016)" --web-slug "luke-cage-2016" tmdb show 62126 # Marvel's Luke Cage (2016) -cargo run -- add --fs-slug "runaways (2017)" --web-slug "runaways-2017" tmdb show 67466 # Marvel's Runaways (2017) -cargo run -- add --fs-slug "defenders (2017)" --web-slug "defenders-2017" tmdb show 62285 # Marvel's The Defenders (2017) -cargo run -- add --fs-slug "punisher (2017)" --web-slug "punisher-2017" tmdb show 67178 # Marvel's The Punisher (2017) +flix add --sort-title "marvel" flix collection "In Association With Marvel" "Movies based on Marvel Comics properties not produced by Marvel Studios" +flix add --fs-slug "cloak and dagger (2018)" --web-slug "cloak-and-dagger-2018" tmdb show 66190 # Marvel's Cloak & Dagger (2018) +flix add --fs-slug "daredevil (2015)" --web-slug "daredevil-2015" tmdb show 61889 # Marvel's Daredevil (2015) +flix add --fs-slug "inhumans (2017)" --web-slug "inhumans-2017" tmdb show 68716 # Marvel's Inhumans (2017) +flix add --fs-slug "iron fist (2017)" --web-slug "iron-fist-2017" tmdb show 62127 # Marvel's Iron Fist (2017) +flix add --fs-slug "jessica jones (2015)" --web-slug "jessica-jones-2015" tmdb show 38472 # Marvel's Jessica Jones (2015) +flix add --fs-slug "luke cage (2016)" --web-slug "luke-cage-2016" tmdb show 62126 # Marvel's Luke Cage (2016) +flix add --fs-slug "runaways (2017)" --web-slug "runaways-2017" tmdb show 67466 # Marvel's Runaways (2017) +flix add --fs-slug "defenders (2017)" --web-slug "defenders-2017" tmdb show 62285 # Marvel's The Defenders (2017) +flix add --fs-slug "punisher (2017)" --web-slug "punisher-2017" tmdb show 67178 # Marvel's The Punisher (2017) +flix add tmdb collection 125574 # The Amazing Spider-Man Collection +flix add tmdb movie 1930 # The Amazing Spider-Man (2012) +flix add tmdb movie 102382 # The Amazing Spider-Man 2 (2014) +flix add tmdb collection 735 # Blade Collection +flix add tmdb movie 36647 # Blade (1998) +flix add tmdb movie 36586 # Blade II (2002) +flix add tmdb movie 36648 # Blade: Trinity (2004) +flix add tmdb collection 448150 # Deadpool Collection +flix add tmdb movie 293660 # Deadpool (2016) +flix add tmdb movie 383498 # Deadpool 2 (2018) +flix add --fs-slug "deadpool and wolverine (2024)" --web-slug "deadpool-and-wolverine-2024" tmdb movie 533535 # Deadpool & Wolverine (2024) +flix add tmdb collection 9744 # Fantastic Four Collection +flix add tmdb movie 9738 # Fantastic Four (2005) +flix add tmdb movie 1979 # Fantastic Four: Rise of the Silver Surfer (2007) +flix add tmdb movie 166424 # Fantastic Four (2015) +flix add tmdb movie 1927 # Hulk (2003) +flix add tmdb collection 179892 # Kick-Ass Collection +flix add tmdb movie 23483 # Kick-Ass (2010) +flix add tmdb movie 59859 # Kick-Ass 2 (2013) +flix add tmdb movie 634492 # Madame Web (2024) +flix add tmdb collection 556 # Spider-Man Collection +flix add tmdb movie 557 # Spider-Man (2002) +flix add tmdb movie 558 # Spider-Man 2 (2004) +flix add tmdb movie 559 # Spider-Man 3 (2007) +flix add tmdb collection 453993 # The Wolverine Collection +flix add tmdb movie 2080 # X-Men Origins: Wolverine (2009) +flix add tmdb movie 76170 # The Wolverine (2013) +flix add tmdb movie 263115 # Logan (2017) +flix add tmdb collection 748 # X-Men Collection +flix add tmdb movie 36657 # X-Men (2000) +flix add tmdb movie 36658 # X2 (2003) +flix add tmdb movie 36668 # X-Men: The Last Stand (2006) +flix add tmdb movie 49538 # X-Men: First Class (2011) +flix add tmdb movie 127585 # X-Men: Days of Future Past (2014) +flix add tmdb movie 246655 # X-Men: Apocalypse (2016) +flix add tmdb movie 320288 # Dark Phoenix (2019) +flix add tmdb collection 1645434 # X-Anthology +flix add tmdb movie 26623 # Generation X (1996) +flix add tmdb movie 340102 # The New Mutants (2020) +flix add tmdb collection 558216 # Venom Collection +flix add tmdb movie 335983 # Venom (2018) +flix add tmdb movie 580489 # Venom: Let There Be Carnage (2021) +flix add tmdb movie 912649 # Venom: The Last Dance (2024) # Marvel Cinematic Universe -cargo run -- add flix collection "Marvel Cinematic Universe" "" -cargo run -- add tmdb show 84958 # Loki (2021) -cargo run -- add --fs-slug "agent carter (2015)" --web-slug "agent-carter-2015" tmdb show 61550 # Marvel's Agent Carter (2015) -cargo run -- add --fs-slug "agents of shield (2013)" --web-slug "agents-of-shield-2013" tmdb show 1403 # Marvel's Agents of S.H.I.E.L.D. (2013) +flix add flix collection "Marvel Cinematic Universe" "" +flix add tmdb show 84958 # Loki (2021) +flix add --fs-slug "agent carter (2015)" --web-slug "agent-carter-2015" tmdb show 61550 # Marvel's Agent Carter (2015) +flix add --fs-slug "agents of shield (2013)" --web-slug "agents-of-shield-2013" tmdb show 1403 # Marvel's Agents of S.H.I.E.L.D. (2013) +flix add tmdb collection 422834 # Ant-Man Collection +flix add tmdb movie 102899 # Ant-Man (2015) +flix add tmdb movie 363088 # Ant-Man and the Wasp (2018) +flix add tmdb movie 640146 # Ant-Man and the Wasp: Quantumania (2023) +flix add tmdb collection 86311 # The Avengers Collection +flix add tmdb movie 24428 # The Avengers (2012) +flix add tmdb movie 99861 # Avengers: Age of Ultron (2015) +flix add tmdb movie 299536 # Avengers: Infinity War (2018) +flix add tmdb movie 299534 # Avengers: Endgame (2019) +# flix add tmdb movie 1003596 # upcoming +# flix add tmdb movie 1003598 # upcoming +flix add tmdb collection 529892 # Black Panther Collection +flix add tmdb movie 284054 # Black Panther (2018) +flix add tmdb movie 505642 # Black Panther: Wakanda Forever (2022) +flix add tmdb movie 497698 # Black Widow (2021) +flix add tmdb collection 131295 # Captain America Collection +flix add tmdb movie 1771 # Captain America: The First Avenger (2011) +flix add tmdb movie 100402 # Captain America: The Winter Soldier (2014) +flix add tmdb movie 271110 # Captain America: Civil War (2016) +flix add tmdb movie 822119 # Captain America: Brave New World (2025) +flix add tmdb collection 623911 # Captain Marvel Collection +flix add tmdb movie 299537 # Captain Marvel (2019) +flix add tmdb movie 609681 # The Marvels (2023) +flix add tmdb collection 618529 # Doctor Strange Collection +flix add tmdb movie 284052 # Doctor Strange (2016) +flix add tmdb movie 453395 # Doctor Strange in the Multiverse of Madness (2022) +flix add tmdb movie 524434 # Eternals (2021) +flix add tmdb collection 284433 # Guardians of the Galaxy Collection +flix add tmdb movie 118340 # Guardians of the Galaxy (2014) +flix add tmdb movie 283995 # Guardians of the Galaxy Vol. 2 (2017) +flix add tmdb movie 447365 # Guardians of the Galaxy Vol. 3 (2023) +flix add tmdb collection 131292 # Iron Man Collection +flix add tmdb movie 1726 # Iron Man (2008) +flix add tmdb movie 10138 # Iron Man 2 (2010) +flix add tmdb movie 68721 # Iron Man 3 (2013) +flix add tmdb movie 566525 # Shang-Chi and the Legend of the Ten Rings (2021) +flix add tmdb collection 531241 # Spider-Man (MCU) Collection +flix add tmdb movie 315635 # Spider-Man: Homecoming (2017) +flix add tmdb movie 429617 # Spider-Man: Far From Home (2019) +flix add tmdb movie 634649 # Spider-Man: No Way Home (2021) +# flix add tmdb movie 969681 # upcoming +flix add tmdb movie 617126 # The Fantastic 4: First Steps (2025) +flix add tmdb movie 1724 # The Incredible Hulk (2008) +flix add tmdb collection 131296 # Thor Collection +flix add tmdb movie 10195 # Thor (2011) +flix add tmdb movie 76338 # Thor: The Dark World (2013) +flix add tmdb movie 284053 # Thor: Ragnarok (2017) +flix add tmdb movie 616037 # Thor: Love and Thunder (2022) +flix add tmdb movie 986056 # Thunderbolts* (2025) + +# South Park +flix add flix collection "South Park Collection" "Follow the misadventures of four irreverent grade-schoolers in the quiet, dysfunctional town of South Park, Colorado." +flix add tmdb show 2190 # South Park (1997) +flix add --fs-slug "south park bigger longer and uncut (1999)" --web-slug "south-park-bigger-longer-and-uncut-1999" tmdb movie 9473 # South Park: Bigger, Longer & Uncut (1999) +flix add tmdb collection 913392 # South Park: Post COVID Collection +flix add tmdb movie 874299 # South Park: Post COVID (2021) +flix add tmdb movie 874300 # South Park: Post COVID: The Return of COVID (2021) +flix add tmdb collection 993732 # South Park the Streaming Wars Collection +flix add tmdb movie 974691 # South Park the Streaming Wars (2022) +flix add tmdb movie 993729 # South Park the Streaming Wars Part 2 (2022) +flix add tmdb movie 1190012 # South Park: Joining the Panderverse (2023) +flix add tmdb movie 1219926 # South Park (Not Suitable for Children) (2023) +flix add tmdb movie 1290938 # South Park: The End of Obesity (2024) # Star Wars -cargo run -- add tmdb collection 10 # Star Wars Collection -cargo run -- add --title "Star Wars: Episode I - The Phantom Menace" --sort-title "star wars 1 - the phantom menace" --fs-slug "the phantom menace (1999)" --web-slug "star-wars-the-phantom-menace-1999" tmdb movie 1893 # Star Wars: Episode I - The Phantom Menace (1999) -cargo run -- add --title "Star Wars: Episode II - Attack of the Clones" --sort-title "star wars 2 - attack of the clones" --fs-slug "attack of the clones (2002)" --web-slug "star-wars-attack-of-the-clones-2002" tmdb movie 1894 # Star Wars: Episode II - Attack of the Clones (2002) -cargo run -- add --title "Star Wars: Episode III - Revenge of the Sith" --sort-title "star wars 3 - revenge of the sith" --fs-slug "revenge of the sith (2005)" --web-slug "star-wars-revenge-of-the-sith-2005" tmdb movie 1895 # Star Wars: Episode III - Revenge of the Sith (2005) -cargo run -- add --title "Star Wars: Episode IV - A New Hope" --sort-title "star wars 4 - a new hope" --fs-slug "a new hope (1977)" --web-slug "star-wars-a-new-hope-1977" tmdb movie 11 # Star Wars (1977) -cargo run -- add --title "Star Wars: Episode V - The Empire Strikes Back" --sort-title "star wars 5 - the empire strikes back" --fs-slug "the empire strikes back (1980)" --web-slug "star-wars-the-empire-strikes-back-1980" tmdb movie 1891 # The Empire Strikes Back (1980) -cargo run -- add --title "Star Wars: Episode VI - Return of the Jedi" --sort-title "star wars 6 - return of the jedi" --fs-slug "return of the jedi (1983)" --web-slug "star-wars-return-of-the-jedi-1983" tmdb movie 1892 # Return of the Jedi (1983) -cargo run -- add --title "Star Wars: Episode VII - The Force Awakens" --sort-title "star wars 7 - the force awakens" --fs-slug "the force awakens (2015)" --web-slug "star-wars-the-force-awakens-2015" tmdb movie 140607 # Star Wars: The Force Awakens (2015) -cargo run -- add --title "Star Wars: Episode VIII - The Last Jedi" --sort-title "star wars 8 - the last jedi" --fs-slug "the last jedi (2017)" --web-slug "star-wars-the-last-jedi-2017" tmdb movie 181808 # Star Wars: The Last Jedi (2017) -cargo run -- add --title "Star Wars: Episode IX - The Rise of Skywalker" --sort-title "star wars 9 - the rise of skywalker" --fs-slug "the rise of skywalker (2019)" --web-slug "star-wars-the-rise-of-skywalker-2019" tmdb movie 181812 # Star Wars: The Rise of Skywalker (2019) -cargo run -- add tmdb show 82856 # The Mandalorian (2019) +flix add tmdb collection 10 # Star Wars Collection +flix add --title "Star Wars: Episode I - The Phantom Menace" --sort-title "star wars 1 - the phantom menace" --fs-slug "the phantom menace (1999)" --web-slug "star-wars-the-phantom-menace-1999" tmdb movie 1893 # Star Wars: Episode I - The Phantom Menace (1999) +flix add --title "Star Wars: Episode II - Attack of the Clones" --sort-title "star wars 2 - attack of the clones" --fs-slug "attack of the clones (2002)" --web-slug "star-wars-attack-of-the-clones-2002" tmdb movie 1894 # Star Wars: Episode II - Attack of the Clones (2002) +flix add --title "Star Wars: Episode III - Revenge of the Sith" --sort-title "star wars 3 - revenge of the sith" --fs-slug "revenge of the sith (2005)" --web-slug "star-wars-revenge-of-the-sith-2005" tmdb movie 1895 # Star Wars: Episode III - Revenge of the Sith (2005) +flix add --title "Star Wars: Episode IV - A New Hope" --sort-title "star wars 4 - a new hope" --fs-slug "a new hope (1977)" --web-slug "star-wars-a-new-hope-1977" tmdb movie 11 # Star Wars (1977) +flix add --title "Star Wars: Episode V - The Empire Strikes Back" --sort-title "star wars 5 - the empire strikes back" --fs-slug "the empire strikes back (1980)" --web-slug "star-wars-the-empire-strikes-back-1980" tmdb movie 1891 # The Empire Strikes Back (1980) +flix add --title "Star Wars: Episode VI - Return of the Jedi" --sort-title "star wars 6 - return of the jedi" --fs-slug "return of the jedi (1983)" --web-slug "star-wars-return-of-the-jedi-1983" tmdb movie 1892 # Return of the Jedi (1983) +flix add --title "Star Wars: Episode VII - The Force Awakens" --sort-title "star wars 7 - the force awakens" --fs-slug "the force awakens (2015)" --web-slug "star-wars-the-force-awakens-2015" tmdb movie 140607 # Star Wars: The Force Awakens (2015) +flix add --title "Star Wars: Episode VIII - The Last Jedi" --sort-title "star wars 8 - the last jedi" --fs-slug "the last jedi (2017)" --web-slug "star-wars-the-last-jedi-2017" tmdb movie 181808 # Star Wars: The Last Jedi (2017) +flix add --title "Star Wars: Episode IX - The Rise of Skywalker" --sort-title "star wars 9 - the rise of skywalker" --fs-slug "the rise of skywalker (2019)" --web-slug "star-wars-the-rise-of-skywalker-2019" tmdb movie 181812 # Star Wars: The Rise of Skywalker (2019) +flix add tmdb show 82856 # The Mandalorian (2019) +flix add tmdb movie 330459 # Rogue One: A Star Wars Story (2016) +flix add tmdb movie 348350 # Solo: A Star Wars Story (2018) # Twin Peaks -cargo run -- add flix collection "Twin Peaks Collection" "" -cargo run -- add tmdb show 1920 # Twin Peaks (1990) +flix add flix collection "Twin Peaks Collection" "" +flix add tmdb show 1920 # Twin Peaks (1990) ##################### # Movie Collections # ##################### +# Airplane +flix add tmdb collection 91663 # Airplane Collection +flix add tmdb movie 813 # Airplane! (1980) +flix add tmdb movie 2665 # Airplane II: The Sequel (1982) + +# Alice in Wonderland +flix add tmdb collection 261307 # Alice in Wonderland Collection +flix add tmdb movie 12155 # Alice in Wonderland (2010) +flix add tmdb movie 241259 # Alice Through the Looking Glass (2016) + +# Anastasia +flix add tmdb collection 920650 # Anastasia Collection +flix add tmdb movie 9444 # Anastasia (1997) +flix add tmdb movie 19594 # Bartok the Magnificent (1999) + +# Atlantis +flix add tmdb collection 100965 # Atlantis Collection +flix add tmdb movie 10865 # Atlantis: The Lost Empire (2001) +flix add tmdb movie 8965 # Atlantis: Milo's Return (2003) + +# Austin Powers +flix add tmdb collection 1006 # Austin Powers Collection +flix add tmdb movie 816 # Austin Powers: International Man of Mystery (1997) +flix add tmdb movie 817 # Austin Powers: The Spy Who Shagged Me (1999) +flix add tmdb movie 818 # Austin Powers in Goldmember (2002) + +# AVP (Aliens vs Predator) +flix add tmdb collection 115762 # AVP Collection +flix add tmdb movie 395 # AVP: Alien vs. Predator (2004) +flix add tmdb movie 440 # Aliens vs Predator: Requiem (2007) + +# Avatar +flix add tmdb collection 87096 # Avatar Collection +flix add tmdb movie 19995 # Avatar (2009) +flix add tmdb movie 76600 # Avatar: The Way of Water (2022) +flix add tmdb movie 83533 # Avatar: Fire and Ash (2025) +# flix add tmdb movie 216527 # upcoming +# flix add tmdb movie 393209 # upcoming + # Avatar: The Last Airbender -cargo run -- add tmdb collection 1136366 # Avatar: The Last Airbender - Collection -cargo run -- add tmdb movie 980431 # Avatar: Aang, The Last Airbender (2026) +flix add tmdb collection 1136366 # Avatar: The Last Airbender - Collection +flix add tmdb movie 980431 # Avatar: Aang, The Last Airbender (2026) + +# Barbie +flix add flix collection "Barbie Animated Collection" "Collection of the animated films based on Mattel's Barbie." +flix add tmdb movie 15167 # Barbie in the Nutcracker (2001) +flix add tmdb movie 15015 # Barbie as Rapunzel (2002) +flix add tmdb movie 15016 # Barbie of Swan Lake (2003) +flix add --fs-slug "barbie as the princess and the pauper (2004)" --web-slug "barbie-as-the-princess-and-the-pauper-2004" tmdb movie 15165 # Barbie as The Princess & the Pauper (2004) +flix add tmdb movie 15906 # Barbie and the Magic of Pegasus (2005) +flix add tmdb movie 13002 # Barbie in the 12 Dancing Princesses (2006) +flix add tmdb movie 13283 # Barbie as the Island Princess (2007) +flix add tmdb movie 13004 # Barbie and the Diamond Castle (2008) +flix add tmdb movie 13459 # Barbie in 'A Christmas Carol' (2008) +flix add tmdb movie 23566 # Barbie and the Three Musketeers (2009) +flix add tmdb movie 16418 # Barbie Presents: Thumbelina (2009) +flix add tmdb collection 411859 # Barbie Fairytopia Collection +flix add tmdb movie 13284 # Barbie: Fairytopia (2005) +flix add tmdb movie 13285 # Barbie Fairytopia: Mermaidia (2006) +flix add tmdb movie 16962 # Barbie Fairytopia: Magic of the Rainbow (2007) +flix add tmdb collection 447622 # Barbie Mariposa Collection +flix add tmdb movie 18198 # Barbie Mariposa (2008) +flix add --fs-slug "barbie mariposa and the fairy princess (2013)" --web-slug "barbie-mariposa-and-the-fairy-princess-2013" tmdb movie 196254 # Barbie Mariposa & the Fairy Princess (2013) +flix add tmdb movie 21705 # The Barbie Diaries (2006) + +# Beekeeper +flix add tmdb collection 1440784 # The Beekeeper Collection +flix add tmdb movie 866398 # The Beekeeper (2024) +# flix add tmdb movie 1440769 # upcoming + +# Borat +flix add tmdb collection 747168 # Borat Moviefilms Collection +flix add tmdb movie 496 # Borat: Cultural Learnings of America for Make Benefit Glorious Nation of Kazakhstan (2006) +flix add tmdb movie 740985 # Borat Subsequent Moviefilm: Delivery of Prodigious Bribe to American Regime for Make Benefit Once Glorious Nation of Kazakhstan (2020) + +# Captain Underpants +flix add tmdb collection 732397 # Captain Underpants Collection +flix add tmdb movie 268531 # Captain Underpants: The First Epic Movie (2017) +flix add tmdb movie 637395 # The Spooky Tale of Captain Underpants Hack-a-ween (2019) +flix add tmdb movie 668602 # Captain Underpants Epic Choice-o-Rama (2020) +flix add tmdb movie 768509 # Captain Underpants Mega Blissmas (2020) + +# Cars +flix add tmdb collection 87118 # Cars Collection +flix add tmdb movie 920 # Cars (2006) +flix add tmdb movie 49013 # Cars 2 (2011) +flix add tmdb movie 260514 # Cars 3 (2017) + +# Charlie and Froggy +flix add tmdb collection 700073 # Charlie Strapp and Froggy Ball Collection +flix add tmdb movie 350086 # Charlie Strap, Froggy Ball and Their Friends (1956) +flix add tmdb movie 34700 # Kalle Stropp och Grodan Boll (1987) +flix add tmdb movie 23811 # Charlie Strap and Froggy Ball Flying High (1991) + +# Chickenhare +flix add --title "Chickenhare Collection" tmdb collection 1473079 # Chickenhare Collection +flix add tmdb movie 778855 # Chickenhare and the Hamster of Darkness (2022) +flix add tmdb movie 1215532 # Chickenhare and the Secret of the Groundhog (2025) + +# Chicken Run +flix add tmdb collection 718551 # Chicken Run Collection +flix add tmdb movie 7443 # Chicken Run (2000) +flix add tmdb movie 520758 # Chicken Run: Dawn of the Nugget (2023) + +# Crank +flix add tmdb collection 64751 # Crank Collection +flix add tmdb movie 1948 # Crank (2006) +flix add tmdb movie 15092 # Crank: High Voltage (2009) + +# Death Race +flix add tmdb collection 434533 # Death Race (1975) Collection +flix add tmdb movie 13282 # Death Race 2000 (1975) +flix add tmdb movie 401544 # Death Race 2050 (2017) +flix add tmdb collection 86116 # Death Race (2008) Collection +flix add tmdb movie 10483 # Death Race (2008) +flix add tmdb movie 51620 # Death Race 2 (2010) +flix add tmdb movie 156717 # Death Race: Inferno (2013) +flix add tmdb movie 401478 # Death Race: Beyond Anarchy (2018) + +# Despicable Me +flix add tmdb collection 86066 # Despicable Me Collection +flix add tmdb movie 20352 # Despicable Me (2010) +flix add tmdb movie 93456 # Despicable Me 2 (2013) +flix add tmdb movie 324852 # Despicable Me 3 (2017) +flix add tmdb movie 519182 # Despicable Me 4 (2024) + +# The Devil Wears Prada +flix add tmdb collection 1314623 # The Devil Wears Prada Collection +flix add tmdb movie 350 # The Devil Wears Prada (2006) +flix add tmdb movie 1314481 # The Devil Wears Prada 2 (2026) + +# Die Hard +flix add tmdb collection 1570 # Die Hard Collection +flix add tmdb movie 562 # Die Hard (1988) +flix add tmdb movie 1573 # Die Hard 2 (1990) +flix add tmdb movie 1572 # Die Hard: With a Vengeance (1995) +flix add tmdb movie 1571 # Live Free or Die Hard (2007) +flix add tmdb movie 47964 # A Good Day to Die Hard (2013) # Disney Live-Action Remakes -cargo run -- add flix collection "Disney Live-Action Remakes" "Live-action or photorealistic remakes produced by Walt Disney Pictures of its animated films." -cargo run -- add tmdb movie 447273 # Snow White (2025) +flix add --fs-slug "disney live-action remakes" --web-slug "disney-live-action-remakes" flix collection "Disney Live-Action Remakes" "Live-action or photorealistic remakes produced by Walt Disney Pictures of its animated films." +flix add tmdb movie 447277 # The Little Mermaid (2023) +flix add tmdb movie 447273 # Snow White (2025) + +# Divergent +flix add tmdb collection 283579 # Divergent Collection +flix add tmdb movie 157350 # Divergent (2014) +flix add tmdb movie 262500 # Insurgent (2015) +flix add tmdb movie 262504 # Allegiant (2016) + +# Dune +flix add tmdb collection 726871 # Dune Collection +flix add tmdb movie 438631 # Dune (2021) +flix add tmdb movie 693134 # Dune: Part Two (2024) +flix add tmdb movie 1170608 # Dune: Part Three (2026) + +# Emperor's New Groove +flix add tmdb collection 178117 # The Emperor's New Groove Collection +flix add tmdb movie 11688 # The Emperor's New Groove (2000) +flix add tmdb movie 13417 # Kronk's New Groove (2005) + +# Enchanted +flix add tmdb collection 531799 # Enchanted Collection +flix add tmdb movie 4523 # Enchanted (2007) +flix add tmdb movie 338958 # Disenchanted (2022) + +# Fantastic Beasts +flix add tmdb collection 435259 # Fantastic Beasts Collection +flix add tmdb movie 259316 # Fantastic Beasts and Where to Find Them (2016) +flix add tmdb movie 338952 # Fantastic Beasts: The Crimes of Grindelwald (2018) +flix add tmdb movie 338953 # Fantastic Beasts: The Secrets of Dumbledore (2022) + +# Fast and the Furious +flix add tmdb collection 9485 # The Fast and the Furious Collection +flix add tmdb movie 9799 # The Fast and the Furious (2001) +flix add tmdb movie 584 # 2 Fast 2 Furious (2003) +flix add tmdb movie 9615 # The Fast and the Furious: Tokyo Drift (2006) +flix add --fs-slug "fast and furious (2009)" --web-slug "fast-and-furious-2009" tmdb movie 13804 # Fast & Furious (2009) +flix add tmdb movie 51497 # Fast Five (2011) +flix add --fs-slug "fast and furious 6 (2013)" --web-slug "fast-and-furious-6-2013" tmdb movie 82992 # Fast & Furious 6 (2013) +flix add tmdb movie 168259 # Furious 7 (2015) +flix add tmdb movie 337339 # The Fate of the Furious (2017) +flix add tmdb movie 385128 # F9 (2021) +flix add tmdb movie 385687 # Fast X (2023) +flix add --fs-slug "fast and furious presents hobbs and shaw (2019)" --web-slug "fast-and-furious-presents-hobbs-and-shaw-2019" tmdb movie 384018 # Fast & Furious Presents: Hobbs & Shaw (2019) + +# FernGully +flix add tmdb collection 19160 # FernGully Collection +flix add tmdb movie 13225 # FernGully: The Last Rainforest (1992) +flix add tmdb movie 18948 # FernGully 2: The Magical Rescue (1998) + +# Fifty Shades +flix add tmdb collection 344830 # Fifty Shades Collection +flix add tmdb movie 216015 # Fifty Shades of Grey (2015) +flix add tmdb movie 341174 # Fifty Shades Darker (2017) +flix add tmdb movie 337167 # Fifty Shades Freed (2018) + +# Finding Nemo +flix add tmdb collection 137697 # Finding Nemo Collection +flix add tmdb movie 12 # Finding Nemo (2003) +flix add tmdb movie 127380 # Finding Dory (2016) + +# Frozen +flix add tmdb collection 386382 # Frozen Collection +flix add tmdb movie 109445 # Frozen (2013) +flix add tmdb movie 330457 # Frozen II (2019) +# flix add tmdb movie 1024604 # upcoming +# flix add tmdb movie 1205983 # upcoming + +# Garfield Movie +flix add tmdb collection 1510620 # The Garfield Movie Collection +flix add tmdb movie 748783 # The Garfield Movie (2024) +# flix add tmdb movie 1510501 # upcoming + +# Ghostbusters +flix add tmdb collection 2980 # Ghostbusters Collection +flix add tmdb movie 620 # Ghostbusters (1984) +flix add tmdb movie 2978 # Ghostbusters II (1989) +flix add tmdb movie 43074 # Ghostbusters (2016) +flix add tmdb movie 425909 # Ghostbusters: Afterlife (2021) +flix add tmdb movie 967847 # Ghostbusters: Frozen Empire (2024) + +# Gnomeo & Juliet +flix add --fs-slug "gnomeo and juliet collection" --web-slug "gnomeo-and-juliet-collection" tmdb collection 493668 # Gnomeo & Juliet Collection +flix add --fs-slug "gnomeo and juliet (2011)" --web-slug "gnomeo-and-juliet-2011" tmdb movie 45772 # Gnomeo & Juliet (2011) +flix add tmdb movie 370567 # Sherlock Gnomes (2018) # Happy Gilmore -cargo run -- add tmdb collection 1263259 # Happy Gilmore Collection -cargo run -- add tmdb movie 9614 # Happy Gilmore (1996) -cargo run -- add tmdb movie 1263256 # Happy Gilmore 2 (2025) +flix add tmdb collection 1263259 # Happy Gilmore Collection +flix add tmdb movie 9614 # Happy Gilmore (1996) +flix add tmdb movie 1263256 # Happy Gilmore 2 (2025) + +# Harry Potter +flix add tmdb collection 1241 # Harry Potter Collection +flix add tmdb movie 671 # Harry Potter and the Philosopher's Stone (2001) +flix add tmdb movie 672 # Harry Potter and the Chamber of Secrets (2002) +flix add tmdb movie 673 # Harry Potter and the Prisoner of Azkaban (2004) +flix add tmdb movie 674 # Harry Potter and the Goblet of Fire (2005) +flix add tmdb movie 675 # Harry Potter and the Order of the Phoenix (2007) +flix add tmdb movie 767 # Harry Potter and the Half-Blood Prince (2009) +flix add tmdb movie 12444 # Harry Potter and the Deathly Hallows: Part 1 (2010) +flix add tmdb movie 12445 # Harry Potter and the Deathly Hallows: Part 2 (2011) + +# Jump Street +flix add tmdb collection 212562 # Jump Street Collection +flix add tmdb movie 64688 # 21 Jump Street (2012) +flix add tmdb movie 187017 # 22 Jump Street (2014) + +# Knives Out +flix add tmdb collection 722971 # Knives Out Collection +flix add tmdb movie 546554 # Knives Out (2019) +flix add tmdb movie 661374 # Glass Onion: A Knives Out Mystery (2022) +flix add tmdb movie 812583 # Wake Up Dead Man: A Knives Out Mystery (2025) + +# Home Alone +flix add tmdb collection 9888 # Home Alone Collection +flix add tmdb movie 771 # Home Alone (1990) +flix add tmdb movie 772 # Home Alone 2: Lost in New York (1992) +flix add tmdb movie 9714 # Home Alone 3 (1997) +flix add tmdb movie 12536 # Home Alone 4 (2002) + +# Hotel Transylvania +flix add tmdb collection 185103 # Hotel Transylvania Collection +flix add tmdb movie 76492 # Hotel Transylvania (2012) +flix add tmdb movie 159824 # Hotel Transylvania 2 (2015) +flix add tmdb movie 400155 # Hotel Transylvania 3: Summer Vacation (2018) +flix add tmdb movie 585083 # Hotel Transylvania: Transformania (2022) + +# How to Train Your Dragon +flix add tmdb collection 89137 # How to Train Your Dragon Collection +flix add tmdb movie 10191 # How to Train Your Dragon (2010) +flix add tmdb movie 82702 # How to Train Your Dragon 2 (2014) +flix add tmdb movie 166428 # How to Train Your Dragon: The Hidden World (2019) + +# How to Train Your Dragon (Live-Action) +flix add tmdb collection 1458864 # How to Train Your Dragon (Live-Action) Collection +flix add tmdb movie 1087192 # How to Train Your Dragon (2025) +flix add tmdb movie 1458319 # How to Train Your Dragon 2 (2027) + +# Hunger Games +flix add tmdb collection 131635 # The Hunger Games Collection +flix add tmdb movie 70160 # The Hunger Games (2012) +flix add tmdb movie 101299 # The Hunger Games: Catching Fire (2013) +flix add tmdb movie 131631 # The Hunger Games: Mockingjay - Part 1 (2014) +flix add tmdb movie 131634 # The Hunger Games: Mockingjay - Part 2 (2015) + +# Hunger Games - New Trilogy +flix add --title "The Hunger Games - New Trilogy Collection" --fs-slug "hunger games new trilogy collection" --web-slug "hunger-games-new-trilogy-collection" tmdb collection 1701563 +flix add --fs-slug "hunger games the ballad of songbirds and snakes (2023)" --web-slug "hunger-games-the-ballad-of-songbirds-and-snakes-2023" tmdb movie 695721 # The Hunger Games: The Ballad of Songbirds & Snakes (2023) +# flix add tmdb movie 1300968 # upcoming + +# Huntsman Collection +flix add tmdb collection 393379 # The Huntsman Collection +flix add tmdb movie 58595 # Snow White and the Huntsman (2012) +flix add tmdb movie 290595 # The Huntsman: Winter's War (2016) + +# Incredibles +flix add tmdb collection 468222 # The Incredibles Collection +flix add tmdb movie 9806 # The Incredibles (2004) +flix add tmdb movie 260513 # Incredibles 2 (2018) +# flix add tmdb movie 1327821 # upcoming + +# Inside Out +flix add tmdb collection 1022790 # Inside Out Collection +flix add tmdb movie 150540 # Inside Out (2015) +flix add tmdb movie 1022789 # Inside Out 2 (2024) + +# Jack Reacher +flix add tmdb collection 403374 # Jack Reacher Collection +flix add tmdb movie 75780 # Jack Reacher (2012) +flix add tmdb movie 343611 # Jack Reacher: Never Go Back (2016) + +# Jason Bourne +flix add tmdb collection 31562 # The Bourne Collection +flix add tmdb movie 2501 # The Bourne Identity (2002) +flix add tmdb movie 2502 # The Bourne Supremacy (2004) +flix add tmdb movie 2503 # The Bourne Ultimatum (2007) +flix add tmdb movie 49040 # The Bourne Legacy (2012) +flix add tmdb movie 324668 # Jason Bourne (2016) + +# John Wick +flix add tmdb collection 404609 # John Wick Collection +flix add tmdb movie 245891 # John Wick (2014) +flix add tmdb movie 324552 # John Wick: Chapter 2 (2017) +flix add --web-slug "john-wick-chapter-3-parabellum-2019" tmdb movie 458156 # John Wick: Chapter 3 - Parabellum (2019) +flix add tmdb movie 603692 # John Wick: Chapter 4 (2023) + +# Johnny English +flix add tmdb collection 86117 # Johnny English Collection +flix add tmdb movie 9486 # Johnny English (2003) +flix add tmdb movie 58233 # Johnny English Reborn (2011) +flix add tmdb movie 463272 # Johnny English Strikes Again (2018) +# flix add tmdb movie 1241132 # upcoming + +# Jumanji +flix add tmdb collection 495527 # Jumanji Collection +flix add tmdb movie 8844 # Jumanji (1995) +flix add tmdb movie 353486 # Jumanji: Welcome to the Jungle (2017) +flix add tmdb movie 512200 # Jumanji: The Next Level (2019) +# flix add tmdb movie 1260649 # upcoming + +# Kung Fu Panda +flix add tmdb collection 77816 # Kung Fu Panda Collection +flix add tmdb movie 9502 # Kung Fu Panda (2008) +flix add tmdb movie 49444 # Kung Fu Panda 2 (2011) +flix add tmdb movie 140300 # Kung Fu Panda 3 (2016) +flix add tmdb movie 1011985 # Kung Fu Panda 4 (2024) + +# Last Witch Hunter +flix add tmdb collection 1543569 # The Last Witch Hunter Collection +flix add tmdb movie 274854 # The Last Witch Hunter (2015) +# flix add tmdb movie 1543515 # upcoming + +# Lego Movie +flix add tmdb collection 325470 # The Lego Movie Collection +flix add tmdb movie 137106 # The Lego Movie (2014) +flix add tmdb movie 280217 # The Lego Movie 2: The Second Part (2019) + +# Leo +flix add tmdb collection 1235977 # Leo Collection +flix add tmdb movie 1075794 # Leo (2023) +# flix add tmdb movie 1235976 # upcoming + +# Lilo & Stitch +flix add --fs-slug "lilo and stitch animated collection" --web-slug "lilo-and-stitch-animated-collection" tmdb collection 97461 # Lilo & Stitch (Animated) Collection +flix add --fs-slug "lilo and stitch (2002)" --web-slug "lilo-and-stitch-2002" tmdb movie 11544 # Lilo & Stitch (2002) +flix add tmdb movie 15567 # Stitch! The Movie (2003) +flix add --fs-slug "lilo and stitch 2 stitch has a glitch (2005)" --web-slug "lilo-and-stitch-2-stitch-has-a-glitch-2005" tmdb movie 20760 # Lilo & Stitch 2: Stitch Has a Glitch (2005) +flix add --fs-slug "leroy and stitch (2006)" --web-slug "leroy-and-stitch-2006" tmdb movie 21316 # Leroy & Stitch (2006) + +# Lion King +flix add tmdb collection 94032 # The Lion King Collection +flix add tmdb movie 8587 # The Lion King (1994) +flix add tmdb movie 9732 # The Lion King II: Simba's Pride (1998) +# flix add tmdb movie 11430 # unicode + +# Mad Max +flix add tmdb collection 8945 # Mad Max Collection +flix add tmdb movie 9659 # Mad Max (1979) +flix add tmdb movie 8810 # Mad Max 2 (1981) +flix add tmdb movie 9355 # Mad Max Beyond Thunderdome (1985) +flix add tmdb movie 76341 # Mad Max: Fury Road (2015) +flix add tmdb movie 786892 # Furiosa: A Mad Max Saga (2024) +# flix add tmdb movie 340023 # upcoming + +# Madagascar +flix add tmdb collection 14740 # Madagascar Collection +flix add tmdb movie 953 # Madagascar (2005) +flix add tmdb movie 10527 # Madagascar: Escape 2 Africa (2008) +flix add tmdb movie 80321 # Madagascar 3: Europe's Most Wanted (2012) + +# Matrix +flix add tmdb collection 2344 # The Matrix Collection +flix add tmdb movie 603 # The Matrix (1999) +flix add tmdb movie 604 # The Matrix Reloaded (2003) +flix add tmdb movie 605 # The Matrix Revolutions (2003) +flix add tmdb movie 624860 # The Matrix Resurrections (2021) + +# Mean Girls +flix add tmdb collection 99606 # Mean Girls Collection +flix add tmdb movie 10625 # Mean Girls (2004) +flix add tmdb movie 51481 # Mean Girls 2 (2011) + +# Mechanic +flix add tmdb collection 280504 # Mechanic Collection +flix add tmdb movie 27582 # The Mechanic (2011) +flix add tmdb movie 278924 # Mechanic: Resurrection (2016) + +# Meg +flix add tmdb collection 742536 # The Meg Collection +flix add tmdb movie 345940 # The Meg (2018) +flix add tmdb movie 615656 # Meg 2: The Trench (2023) + +# Megamind +flix add tmdb collection 1239518 # Megamind Collection +flix add tmdb movie 38055 # Megamind (2010) +flix add tmdb movie 1239251 # Megamind vs. the Doom Syndicate (2024) + +# Men in Black +flix add tmdb collection 86055 # Men in Black Collection +flix add tmdb movie 607 # Men in Black (1997) +flix add tmdb movie 608 # Men in Black II (2002) +flix add tmdb movie 41154 # Men in Black 3 (2012) +flix add tmdb movie 479455 # Men in Black: International (2019) + +# Middle-Earth +flix add flix collection "Middle-Earth Collection" "Peter Jackson's film trilogies (Lord of the Rings and The Hobbit) taking place in Tolkien's Middle-Earth" +flix add tmdb collection 121938 # The Hobbit Collection +flix add tmdb movie 49051 # The Hobbit: An Unexpected Journey (2012) +flix add tmdb movie 57158 # The Hobbit: The Desolation of Smaug (2013) +flix add tmdb movie 122917 # The Hobbit: The Battle of the Five Armies (2014) +flix add tmdb collection 119 # The Lord of the Rings Collection +flix add tmdb movie 120 # The Lord of the Rings: The Fellowship of the Ring (2001) +flix add tmdb movie 121 # The Lord of the Rings: The Two Towers (2002) +flix add tmdb movie 122 # The Lord of the Rings: The Return of the King (2003) # Minecraft -cargo run -- add tmdb collection 1461530 # The Minecraft Movie Collection -cargo run -- add tmdb movie 950387 # A Minecraft Movie (2025) +flix add tmdb collection 1461530 # The Minecraft Movie Collection +flix add tmdb movie 950387 # A Minecraft Movie (2025) + +# Minions +flix add tmdb collection 544669 # Minions Collection +flix add tmdb movie 211672 # Minions (2015) +flix add tmdb movie 438148 # Minions: The Rise of Gru (2022) +# flix add tmdb movie 1315772 # upcoming + +# Mission Impossible +flix add tmdb collection 87359 # Mission: Impossible Collection +flix add tmdb movie 954 # Mission: Impossible (1996) +flix add tmdb movie 955 # Mission: Impossible II (2000) +flix add tmdb movie 956 # Mission: Impossible III (2006) +flix add --web-slug "mission-impossible-ghost-protocol-2011" tmdb movie 56292 # Mission: Impossible - Ghost Protocol (2011) +flix add --web-slug "mission-impossible-rogue-nation-2015" tmdb movie 177677 # Mission: Impossible - Rogue Nation (2015) +flix add --web-slug "mission-impossible-fallout-2018" tmdb movie 353081 # Mission: Impossible - Fallout (2018) +flix add --web-slug "mission-impossible-dead-reckoning-part-one-2023" tmdb movie 575264 # Mission: Impossible - Dead Reckoning Part One (2023) +flix add --web-slug "mission-impossible-the-final-reckoning-2025" tmdb movie 575265 # Mission: Impossible - The Final Reckoning (2025) + +# Moana +flix add tmdb collection 1241984 # Moana Collection +flix add tmdb movie 277834 # Moana (2016) +flix add tmdb movie 1241982 # Moana 2 (2024) + +# Monsters Inc +flix add tmdb collection 137696 # Monsters, Inc. Collection +flix add tmdb movie 585 # Monsters, Inc. (2001) +flix add tmdb movie 62211 # Monsters University (2013) + +# Mr. Bean +flix add tmdb collection 103372 # Mr. Bean Collection +flix add tmdb movie 1281 # Bean (1997) +flix add tmdb movie 1268 # Mr. Bean's Holiday (2007) + +# Mummy +flix add tmdb collection 1733 # The Mummy Collection +flix add tmdb movie 564 # The Mummy (1999) +flix add tmdb movie 1734 # The Mummy Returns (2001) +flix add tmdb movie 1735 # The Mummy: Tomb of the Dragon Emperor (2008) +# flix add tmdb movie 1574840 # upcoming + +# My Spy +flix add tmdb collection 1090373 # My Spy Collection +flix add tmdb movie 592834 # My Spy (2020) +flix add tmdb movie 1048241 # My Spy The Eternal City (2024) + +# Now You See Me +flix add tmdb collection 382685 # Now You See Me Collection +flix add tmdb movie 75656 # Now You See Me (2013) +flix add tmdb movie 291805 # Now You See Me 2 (2016) +flix add tmdb movie 425274 # Now You See Me: Now You Don't (2025) +# flix add tmdb movie 1457735 # upcoming + +# Ocean's +flix add tmdb collection 304 # Ocean's Collection +flix add tmdb movie 161 # Ocean's Eleven (2001) +flix add tmdb movie 163 # Ocean's Twelve (2004) +flix add tmdb movie 298 # Ocean's Thirteen (2007) +flix add tmdb movie 402900 # Ocean's Eight (2018) + +# Pacific Rim +flix add tmdb collection 363369 # Pacific Rim Collection +flix add tmdb movie 68726 # Pacific Rim (2013) +flix add tmdb movie 268896 # Pacific Rim: Uprising (2018) + +# Percy Jackson +flix add tmdb collection 179919 # Percy Jackson Collection +flix add --fs-slug "percy jackson and the olympians the lightning thief (2010)" --web-slug "percy-jackson-and-the-olympians-the-lightning-thief-2010" tmdb movie 32657 # Percy Jackson & the Olympians: The Lightning Thief (2010) +flix add tmdb movie 76285 # Percy Jackson: Sea of Monsters (2013) + +# Pink Panther (Steve Martin) +flix add tmdb collection 130440 # The Pink Panther (Steve Martin) Collection +flix add tmdb movie 12096 # The Pink Panther (2006) +flix add tmdb movie 15159 # The Pink Panther 2 (2009) + +# Pirates of the Caribbean +flix add tmdb collection 295 # Pirates of the Caribbean Collection +flix add tmdb movie 22 # Pirates of the Caribbean: The Curse of the Black Pearl (2003) +flix add tmdb movie 58 # Pirates of the Caribbean: Dead Man's Chest (2006) +flix add tmdb movie 285 # Pirates of the Caribbean: At World's End (2007) +flix add tmdb movie 1865 # Pirates of the Caribbean: On Stranger Tides (2011) +flix add tmdb movie 166426 # Pirates of the Caribbean: Dead Men Tell No Tales (2017) + +# Quiet Place +flix add tmdb collection 521226 # A Quiet Place Collection +flix add tmdb movie 447332 # A Quiet Place (2018) +flix add tmdb movie 520763 # A Quiet Place Part II (2021) +# flix add tmdb movie 1324923 # upcoming +flix add tmdb movie 762441 # A Quiet Place: Day One (2024) + +# Resident Evil +flix add tmdb collection 17255 # Resident Evil Collection +flix add tmdb movie 1576 # Resident Evil (2002) +flix add tmdb movie 1577 # Resident Evil: Apocalypse (2004) +flix add tmdb movie 7737 # Resident Evil: Extinction (2007) +flix add tmdb movie 35791 # Resident Evil: Afterlife (2010) +flix add tmdb movie 71679 # Resident Evil: Retribution (2012) +flix add tmdb movie 173897 # Resident Evil: The Final Chapter (2016) +flix add tmdb movie 460458 # Resident Evil: Welcome to Raccoon City (2021) + +# Ring +flix add tmdb collection 14563 # The Ring Collection +flix add tmdb movie 565 # The Ring (2002) +flix add tmdb movie 10320 # The Ring Two (2005) +flix add tmdb movie 14564 # Rings (2017) + +# RIPD +flix add tmdb collection 1041695 # R.I.P.D. Collection +flix add tmdb movie 49524 # R.I.P.D. (2013) +flix add tmdb movie 1013860 # R.I.P.D. 2: Rise of the Damned (2022) + +# Scary Movie +flix add tmdb collection 4246 # Scary Movie Collection +flix add tmdb movie 4247 # Scary Movie (2000) +flix add tmdb movie 4248 # Scary Movie 2 (2001) +flix add tmdb movie 4256 # Scary Movie 3 (2003) +flix add tmdb movie 4257 # Scary Movie 4 (2006) +flix add tmdb movie 4258 # Scary Movie 5 (2013) +# flix add tmdb movie 1273221 # upcoming + +# Scooby-Doo +flix add tmdb collection 86860 # Scooby-Doo Collection +flix add tmdb movie 9637 # Scooby-Doo (2002) +flix add tmdb movie 11024 # Scooby-Doo 2: Monsters Unleashed (2004) + +# Secret Life of Pets +flix add tmdb collection 427084 # The Secret Life of Pets Collection +flix add tmdb movie 328111 # The Secret Life of Pets (2016) +flix add tmdb movie 412117 # The Secret Life of Pets 2 (2019) +# flix add tmdb movie 1109206 # upcoming + +# Secret of NIMH +flix add tmdb collection 141292 # The Secret of NIMH Collection +flix add tmdb movie 11704 # The Secret of NIMH (1982) +flix add tmdb movie 20756 # The Secret of NIMH 2: Timmy to the Rescue (1999) + +# Sharkboy and Lavagirl +flix add tmdb collection 727089 # Sharkboy and Lavagirl Collection +flix add tmdb movie 14199 # The Adventures of Sharkboy and Lavagirl (2005) +flix add tmdb movie 615677 # We Can Be Heroes (2020) +# flix add tmdb movie 783103 # upcoming + +# Shrek +flix add tmdb collection 2150 # Shrek Collection +flix add tmdb movie 808 # Shrek (2001) +flix add tmdb movie 809 # Shrek 2 (2004) +flix add tmdb movie 810 # Shrek the Third (2007) +flix add tmdb movie 10192 # Shrek Forever After (2010) +# flix add tmdb movie 421892 # upcoming + +# Sing +flix add tmdb collection 544670 # Sing Collection +flix add tmdb movie 335797 # Sing (2016) +flix add tmdb movie 438695 # Sing 2 (2021) +# flix add tmdb movie 1108794 # upcoming + +# Sonic +flix add tmdb collection 720879 # Sonic the Hedgehog Collection +flix add tmdb movie 454626 # Sonic the Hedgehog (2020) +flix add tmdb movie 675353 # Sonic the Hedgehog 2 (2022) +flix add tmdb movie 939243 # Sonic the Hedgehog 3 (2024) +# flix add tmdb movie 1401586 # upcoming + +# Space Jam +flix add tmdb collection 722961 # Space Jam Collection +flix add tmdb movie 2300 # Space Jam (1996) +flix add tmdb movie 379686 # Space Jam: A New Legacy (2021) + +# Spaceballs +flix add tmdb collection 1497153 # Spaceballs Collection +flix add tmdb movie 957 # Spaceballs (1987) +# flix add tmdb movie 1306322 # upcoming + +# Spy Kids +flix add tmdb collection 86486 # Spy Kids Collection +flix add tmdb movie 10054 # Spy Kids (2001) +flix add tmdb movie 9488 # Spy Kids 2: The Island of Lost Dreams (2002) +flix add --fs-slug "spy kids 3d game over (2003)" --web-slug "spy-kids-3d-game-over-2003" tmdb movie 12279 # Spy Kids 3-D: Game Over (2003) +flix add tmdb movie 56288 # Spy Kids: All the Time in the World (2011) # Super Mario -cargo run -- add tmdb collection 1434561 # The Super Mario Collection -cargo run -- add tmdb movie 502356 # The Super Mario Bros. Movie (2023) -cargo run -- add tmdb movie 1226863 # The Super Mario Galaxy Movie (2026) +flix add tmdb collection 1434561 # The Super Mario Collection +flix add tmdb movie 502356 # The Super Mario Bros. Movie (2023) +flix add tmdb movie 1226863 # The Super Mario Galaxy Movie (2026) + +# Taken +flix add tmdb collection 135483 # Taken Collection +flix add tmdb movie 8681 # Taken (2008) +flix add tmdb movie 82675 # Taken 2 (2012) +flix add tmdb movie 260346 # Taken 3 (2014) + +# Terminator +flix add tmdb collection 528 # The Terminator Collection +flix add tmdb movie 218 # The Terminator (1984) +flix add tmdb movie 280 # Terminator 2: Judgment Day (1991) +flix add tmdb movie 296 # Terminator 3: Rise of the Machines (2003) +flix add tmdb movie 534 # Terminator Salvation (2009) +flix add tmdb movie 87101 # Terminator Genisys (2015) +flix add tmdb movie 290859 # Terminator: Dark Fate (2019) + +# Tomb Raider +flix add tmdb collection 2467 # Tomb Raider Collection +flix add tmdb movie 1995 # Lara Croft: Tomb Raider (2001) +flix add tmdb movie 1996 # Lara Croft: Tomb Raider - The Cradle of Life (2003) +flix add tmdb movie 338970 # Tomb Raider (2018) + +# Top Gun +flix add tmdb collection 531330 # Top Gun Collection +flix add tmdb movie 744 # Top Gun (1986) +flix add tmdb movie 361743 # Top Gun: Maverick (2022) +# flix add tmdb movie 1229934 # upcoming + +# Toy Story +flix add tmdb collection 10194 # Toy Story Collection +flix add tmdb movie 862 # Toy Story (1995) +flix add tmdb movie 863 # Toy Story 2 (1999) +flix add tmdb movie 10193 # Toy Story 3 (2010) +flix add tmdb movie 301528 # Toy Story 4 (2019) +# flix add tmdb movie 1084244 # upcoming + +# Transporter +flix add tmdb collection 9518 # The Transporter Collection +flix add tmdb movie 4108 # The Transporter (2002) +flix add tmdb movie 9335 # Transporter 2 (2005) +flix add tmdb movie 13387 # Transporter 3 (2008) +flix add tmdb movie 287948 # The Transporter Refueled (2015) + +# Transformers +flix add tmdb collection 8650 # Transformers Collection +flix add tmdb movie 1858 # Transformers (2007) +flix add tmdb movie 8373 # Transformers: Revenge of the Fallen (2009) +flix add tmdb movie 38356 # Transformers: Dark of the Moon (2011) +flix add tmdb movie 91314 # Transformers: Age of Extinction (2014) +flix add tmdb movie 335988 # Transformers: The Last Knight (2017) + +# Trolls +flix add tmdb collection 489724 # The Trolls Collection +flix add tmdb movie 136799 # Trolls (2016) +flix add tmdb movie 446893 # Trolls World Tour (2020) +flix add tmdb movie 901362 # Trolls Band Together (2023) + +# TRON +flix add tmdb collection 63043 # TRON Collection +flix add tmdb movie 97 # Tron (1982) +flix add tmdb movie 20526 # TRON: Legacy (2010) +flix add tmdb movie 533533 # TRON: Ares (2025) + +# Twilight +flix add tmdb collection 33514 # The Twilight Collection +flix add tmdb movie 8966 # Twilight (2008) +flix add tmdb movie 18239 # The Twilight Saga: New Moon (2009) +flix add tmdb movie 24021 # The Twilight Saga: Eclipse (2010) +flix add --web-slug "twilight-saga-breaking-dawn-part-1-2011" tmdb movie 50619 # The Twilight Saga: Breaking Dawn - Part 1 (2011) +flix add --web-slug "twilight-saga-breaking-dawn-part-2-2012" tmdb movie 50620 # The Twilight Saga: Breaking Dawn - Part 2 (2012) + +# Underworld +flix add tmdb collection 2326 # Underworld Collection +flix add tmdb movie 277 # Underworld (2003) +flix add tmdb movie 834 # Underworld: Evolution (2006) +flix add tmdb movie 12437 # Underworld: Rise of the Lycans (2009) +flix add tmdb movie 52520 # Underworld: Awakening (2012) +flix add tmdb movie 346672 # Underworld: Blood Wars (2016) + +# Up +flix add flix collection "Up Collection" "" +flix add tmdb movie 14160 # Up (2009) +flix add tmdb movie 1076364 # Carl's Date (2023) + +# Vampires Suck +flix add tmdb collection 278920 # Vampires Suck Collection +flix add tmdb movie 40264 # Vampires Suck (2010) +flix add tmdb movie 80384 # Breaking Wind (2012) + +# Violent Night +flix add tmdb collection 1078456 # Violent Night Collection +flix add tmdb movie 899112 # Violent Night (2022) +# flix add tmdb movie 1078446 # upcoming + +# Wild Robot +flix add tmdb collection 1370345 # The Wild Robot Collection +flix add tmdb movie 1184918 # The Wild Robot (2024) +# flix add tmdb movie 1370190 # upcoming + +# Wonka +flix add tmdb collection 1393821 # Wonka Collection +flix add tmdb movie 787699 # Wonka (2023) +# flix add tmdb movie 1385209 # upcoming + +# Zombieland +flix add tmdb collection 537982 # Zombieland Collection +flix add tmdb movie 19908 # Zombieland (2009) +flix add tmdb movie 338967 # Zombieland: Double Tap (2019) # Zootopia -cargo run -- add tmdb collection 1084247 # Zootopia Collection -cargo run -- add tmdb movie 269149 # Zootopia (2016) -cargo run -- add tmdb movie 1084242 # Zootopia 2 (2025) +flix add tmdb collection 1084247 # Zootopia Collection +flix add tmdb movie 269149 # Zootopia (2016) +flix add tmdb movie 1084242 # Zootopia 2 (2025) #################### @@ -94,70 +927,217 @@ cargo run -- add tmdb movie 1084242 # Zootopia 2 (2025) #################### # Arrowverse -cargo run -- add flix collection "Arrowverse" "A television franchise that is based on characters that appear in publications by DC Comics." -cargo run -- add tmdb show 1412 # Arrow (2012) -cargo run -- add tmdb show 89247 # Batwoman (2019) -cargo run -- add tmdb show 71663 # Black Lightning (2018) -cargo run -- add tmdb show 60735 # The Flash (2014) -cargo run -- add --fs-slug "legends of tomorrow (2016)" --web-slug "legends-of-tomorrow-2016" tmdb show 62643 -cargo run -- add tmdb show 62688 # Supergirl (2015) +flix add flix collection "Arrowverse" "A television franchise that is based on characters that appear in publications by DC Comics." +flix add tmdb show 1412 # Arrow (2012) +flix add tmdb show 89247 # Batwoman (2019) +flix add tmdb show 71663 # Black Lightning (2018) +flix add tmdb show 60735 # The Flash (2014) +flix add --fs-slug "legends of tomorrow (2016)" --web-slug "legends-of-tomorrow-2016" tmdb show 62643 +flix add tmdb show 62688 # Supergirl (2015) # Avatar Universe -cargo run -- add flix collection "Avatar Universe" "Avatar: The Last Airbender is set in an Asiatic-like world in which some people can manipulate the classical elements with psychokinetic variants of the Chinese martial arts known as 'bending'." -cargo run -- add tmdb show 246 # Avatar: The Last Airbender (2005) -cargo run -- add tmdb show 33880 # The Legend of Korra (2012) +flix add flix collection "Avatar Universe" "Avatar: The Last Airbender is set in an Asiatic-like world in which some people can manipulate the classical elements with psychokinetic variants of the Chinese martial arts known as 'bending'." +flix add tmdb show 246 # Avatar: The Last Airbender (2005) +flix add tmdb show 33880 # The Legend of Korra (2012) # Breaking Bad -cargo run -- add flix collection "Breaking Bad Collection" "Collection containing the original Breaking Bad show along with a documentary chronicling the process of making the final season, a sequel movie and prequel show." -cargo run -- add tmdb show 1396 # Breaking Bad (2008) +flix add flix collection "Breaking Bad Collection" "Collection containing the original Breaking Bad show along with a documentary chronicling the process of making the final season, a sequel movie and prequel show." +flix add tmdb show 1396 # Breaking Bad (2008) # Buffyverse -cargo run -- add flix collection "Buffyverse" "The Buffyverse is a setting in which supernatural phenomena exist, and supernatural evil can be challenged by people willing to fight against such forces." -cargo run -- add tmdb show 2426 # Angel (1999) -cargo run -- add tmdb show 95 # Buffy the Vampire Slayer (1997) +flix add flix collection "Buffyverse" "The Buffyverse is a setting in which supernatural phenomena exist, and supernatural evil can be challenged by people willing to fight against such forces." +flix add tmdb show 2426 # Angel (1999) +flix add tmdb show 95 # Buffy the Vampire Slayer (1997) ########## # Movies # ########## -cargo run -- add tmdb movie 286217 # The Martian (2015) -cargo run -- add tmdb movie 940551 # Migration (2023) - +flix add tmdb movie 16996 # 17 Again (2009) +flix add tmdb movie 6957 # The 40 Year Old Virgin (2005) +flix add tmdb movie 665251 # Altered Carbon: Resleeved (2020) +flix add tmdb movie 1039773 # The American Society of Magical Negroes (2024) +flix add tmdb movie 8916 # Antz (1998) +flix add tmdb movie 1087891 # The Amateur (2025) +flix add tmdb movie 1072790 # Anyone But You (2023) +flix add tmdb movie 339403 # Baby Driver (2017) +flix add tmdb movie 8848 # The Bank Job (2008) +flix add tmdb movie 5559 # Bee Movie (2007) +flix add tmdb movie 401123 # Beta Test (2016) +flix add tmdb movie 55846 # Blitz (2011) +flix add tmdb movie 651571 # Breach (2020) +flix add --sort-title "bruno" --fs-slug "bruno (2009)" --web-slug "bruno-2009" tmdb movie 18480 # Brüno (2009) +flix add tmdb movie 9487 # A Bug's Life (1998) +flix add tmdb movie 9759 # Cellular (2004) +flix add tmdb movie 937287 # Challengers (2024) +flix add tmdb movie 5289 # Chaos (2005) +flix add tmdb movie 118 # Charlie and the Chocolate Factory (2005) +flix add tmdb movie 9982 # Chicken Little (2005) +flix add tmdb movie 15028 # Clockstoppers (2002) +flix add tmdb movie 1538 # Collateral (2004) +flix add tmdb movie 9612 # Coneheads (1993) +flix add --web-slug "constantine-city-of-demons-the-movie-2018" tmdb movie 539517 # Constantine: City of Demons - The Movie (2018) +flix add tmdb movie 241843 # Cooties (2014) +flix add tmdb movie 763215 # Damsel (2024) +flix add tmdb movie 71469 # The Darkest Hour (2011) +flix add tmdb movie 76493 # The Dictator (2012) +flix add tmdb movie 1097870 # Dear Santa (2024) +flix add tmdb movie 351460 # Death Note (2017) +flix add tmdb movie 19901 # Daybreakers (2010) +flix add tmdb movie 10398 # Double Jeopardy (1999) +flix add tmdb movie 37735 # Easy A (2010) +flix add tmdb movie 777443 # The Electric State (2025) +flix add tmdb movie 976573 # Elemental (2023) +flix add tmdb movie 10719 # Elf (2003) +flix add tmdb movie 1022787 # Elio (2025) +flix add tmdb movie 7299 # Equilibrium (2002) +flix add tmdb movie 746036 # The Fall Guy (2024) +flix add tmdb movie 11619 # Flushed Away (2006) +flix add tmdb movie 550988 # Free Guy (2021) +flix add tmdb movie 228150 # Fury (2014) +flix add tmdb movie 11665 # Get Smart (2008) +flix add tmdb movie 10016 # Ghosts of Mars (2001) +flix add tmdb movie 1297842 # GOAT (2026) +flix add tmdb movie 950396 # The Gorge (2025) +flix add tmdb movie 360920 # The Grinch (2018) +flix add tmdb movie 325348 # Hardcore Henry (2015) +flix add tmdb movie 826510 # Harold and the Purple Crayon (2024) +flix add tmdb movie 756397 # Hitpig! (2024) +flix add tmdb movie 228161 # Home (2015) +flix add tmdb movie 204082 # Homefront (2013) +flix add tmdb movie 1327819 # Hoppers (2026) +flix add tmdb movie 136418 # Hummingbird (2013) +flix add tmdb movie 7512 # Idiocracy (2006) +flix add tmdb movie 639720 # IF (2024) +flix add tmdb movie 49530 # In Time (2011) +flix add tmdb movie 27205 # Inception (2010) +flix add tmdb movie 228967 # The Interview (2014) +flix add tmdb movie 9654 # The Italian Job (2003) +flix add tmdb movie 1079091 # It Ends with Us (2024) +flix add tmdb movie 12589 # Jimmy Neutron: Boy Genius (2001) +flix add tmdb movie 9886 # Johnny Mnemonic (1995) +flix add tmdb movie 8247 # Jumper (2008) +flix add tmdb movie 451048 # Jungle Cruise (2021) +flix add tmdb movie 76757 # Jupiter Ascending (2015) +flix add tmdb movie 49021 # Killer Elite (2011) +flix add tmdb movie 1210646 # Lady Ballers (2023) +flix add tmdb movie 586954 # Latte and the Magic Waterstone (2019) +flix add tmdb movie 726209 # Leave the World Behind (2023) +flix add tmdb movie 22894 # Legion (2010) +flix add tmdb movie 51876 # Limitless (2011) +flix add tmdb movie 993784 # Lisa Frankenstein (2024) +flix add tmdb movie 73723 # The Lorax (2012) +flix add tmdb movie 7515 # London (2005) +flix add tmdb movie 59967 # Looper (2012) +flix add tmdb movie 508943 # Luca (2021) +flix add tmdb movie 240832 # Lucy (2014) +flix add tmdb movie 286217 # The Martian (2015) +flix add tmdb movie 13908 # The Master of Disguise (2002) +flix add tmdb movie 673593 # Mean Girls (2024) +flix add tmdb movie 593643 # The Menu (2022) +flix add tmdb movie 940551 # Migration (2023) +flix add tmdb movie 188161 # A Million Ways to Die in the West (2014) +flix add tmdb movie 180 # Minority Report (2002) +flix add tmdb movie 9297 # Monster House (2006) +flix add tmdb movie 458576 # Monster Hunter (2020) +flix add tmdb movie 15512 # Monsters vs Aliens (2009) +flix add tmdb movie 428078 # Mortal Engines (2018) +flix add --fs-slug "mr and mrs smith (2005)" --web-slug "mr-and-mrs-smith-2005" tmdb movie 787 # Mr. & Mrs. Smith (2005) +flix add tmdb movie 9824 # Mystery Men (1999) +flix add tmdb movie 242582 # Nightcrawler (2014) +flix add tmdb movie 179826 # Odd Thomas (2013) +flix add tmdb movie 10796 # The One (2001) +flix add tmdb movie 51828 # One Day (2011) +flix add tmdb movie 872585 # Oppenheimer (2023) +flix add tmdb movie 1139829 # Orion and the Dark (2024) +flix add tmdb movie 7518 # Over the Hedge (2006) +flix add tmdb movie 10022 # The Pacifier (2005) +flix add tmdb movie 119283 # Parker (2013) +flix add --fs-slug "peter pan and wendy (2023)" --web-slug "peter-pan-and-wendy-2023" tmdb movie 420808 # Peter Pan & Wendy (2023) +flix add tmdb movie 1146058 # The Pout-Pout Fish (2026) +flix add tmdb movie 38321 # Priest (2011) +flix add tmdb movie 9543 # Prince of Persia: The Sands of Time (2010) +flix add tmdb movie 176241 # Prison Break: The Final Break (2009) +flix add tmdb movie 523638 # Prisoners of the Ghostland (2021) +flix add tmdb movie 427641 # Rampage (2018) +flix add tmdb movie 44896 # Rango (2011) +flix add tmdb movie 2062 # Ratatouille (2007) +flix add tmdb movie 333339 # Ready Player One (2018) +flix add tmdb movie 31867 # Repo Men (2010) +flix add tmdb movie 10851 # Revolver (2005) +flix add tmdb movie 1022690 # Ricky Stanicky (2024) +flix add tmdb movie 9346 # Risky Business (1983) +flix add tmdb movie 72387 # Safe (2012) +flix add tmdb movie 27576 # Salt (2010) +flix add tmdb movie 254128 # San Andreas (2015) +flix add tmdb movie 223702 # Sausage Party (2016) +flix add tmdb movie 11459 # Sky High (2005) +flix add tmdb movie 1084153 # Sneaks (2025) +flix add tmdb movie 110415 # Snowpiercer (2013) +flix add tmdb movie 27022 # The Sorcerer's Apprentice (2010) +flix add tmdb movie 592983 # Spellbound (2024) +flix add tmdb movie 238713 # Spy (2015) +flix add tmdb movie 53565 # Steamboat Willie (1928) +flix add tmdb movie 12133 # Step Brothers (2008) +flix add tmdb movie 9978 # Stormbreaker (2006) +flix add tmdb movie 11918 # Superhero Movie (2008) +flix add tmdb movie 9607 # Super Mario Bros. (1993) +flix add tmdb movie 1007757 # Swapped (2026) +flix add --title "Taylor Swift | The Eras Tour" tmdb movie 1160164 # Taylor Swift | The Eras Tour (2023) +flix add tmdb movie 597 # Titanic (1997) +flix add tmdb movie 158852 # Tomorrowland (2015) +flix add tmdb movie 157353 # Transcendence (2014) +flix add tmdb movie 1923 # Twin Peaks: Fire Walk with Me (1992) +flix add tmdb movie 473033 # Uncut Gems (2019) +flix add tmdb movie 609271 # Under the Boardwalk (2023) +flix add tmdb movie 748167 # Uglies (2024) +flix add tmdb movie 339964 # Valerian and the City of a Thousand Planets (2017) +flix add tmdb movie 177494 # Veronica Mars (2014) +flix add --sort-title "wall-e" --fs-slug "wall-e (2008)" --web-slug "wall-e-2008" tmdb movie 10681 # WALL·E (2008) +flix add tmdb movie 8909 # Wanted (2008) +flix add tmdb movie 10431 # War (2007) +flix add tmdb movie 894205 # Werewolf by Night (2022) +flix add tmdb movie 957258 # What Is a Woman? (2022) +flix add tmdb movie 265208 # Wild Card (2015) +flix add tmdb movie 1022796 # Wish (2023) +flix add tmdb movie 637649 # Wrath of Man (2021) +flix add tmdb movie 6795 # Zathura: A Space Adventure (2005) ######### # Shows # ######### -cargo run -- add tmdb show 62110 # Assassination Classroom (2015) -cargo run -- add tmdb show 1429 # Attack on Titan (2013) -cargo run -- add tmdb show 42009 # Black Mirror (2011) -cargo run -- add tmdb season 42009 0 # Black Mirror Specials -cargo run -- add tmdb show 1911 # Bones (2005) -cargo run -- add tmdb show 48891 # Brooklyn Nine-Nine (2013) -cargo run -- add flix episode "brooklyn-nine-nine-2013" 8 10 "The Last Day (Part 2)" "The squad takes stock of its eight years together and looks toward the future." "2021-09-16" -cargo run -- add tmdb show 3787 # Chaotic (2006) -cargo run -- add tmdb show 2557 # Class of the Titans (2006) -cargo run -- add tmdb show 13916 # Death Note (2006) -cargo run -- add tmdb show 1405 # Dexter (2006) -cargo run -- add tmdb show 1399 # Game of Thrones (2011) -cargo run -- add tmdb show 40075 # Gravity Falls (2012) -cargo run -- add tmdb show 1639 # Heroes (2006) -cargo run -- add tmdb show 60858 # Heroes Reborn (2015) -cargo run -- add tmdb show 71340 # Krypton (2018) -cargo run -- add tmdb show 62687 # Limitless (2015) -cargo run -- add tmdb show 60846 # Log Horizon (2013) -cargo run -- add tmdb show 64432 # The Magicians (2015) -cargo run -- add tmdb show 5920 # The Mentalist (2008) -cargo run -- add tmdb show 12786 # Murdoch Mysteries (2008) -cargo run -- add tmdb season 12786 0 # Murdoch Mysteries Specials -cargo run -- add tmdb show 65930 # My Hero Academia (2016) -cargo run -- add tmdb show 2288 # Prison Break (2005) -cargo run -- add tmdb show 95396 # Severance (2022) -cargo run -- add tmdb show 60573 # Silicon Valley (2014) -cargo run -- add tmdb show 37680 # Suits (2011) -cargo run -- add tmdb show 45782 # Sword Art Online (2012) -cargo run -- add tmdb show 48860 # The Tomorrow People (2013) -cargo run -- add tmdb show 46331 # Under the Dome (2013) -cargo run -- add tmdb show 1432 # Veronica Mars (2004) -cargo run -- add tmdb show 186 # Weeds (2005) -cargo run -- add tmdb show 63247 # Westworld (2016) -cargo run -- add tmdb show 71912 # The Witcher (2019) +flix add tmdb show 68421 # Altered Carbon (2018) +flix add tmdb show 62110 # Assassination Classroom (2015) +flix add tmdb show 1429 # Attack on Titan (2013) +flix add tmdb show 42009 # Black Mirror (2011) +flix add tmdb show 1911 # Bones (2005) +flix add tmdb show 48891 # Brooklyn Nine-Nine (2013) +flix add flix episode "brooklyn-nine-nine-2013" 8 10 "The Last Day (Part 2)" "The squad takes stock of its eight years together and looks toward the future." "2021-09-16" +flix add tmdb show 3787 # Chaotic (2006) +flix add tmdb show 2557 # Class of the Titans (2006) +flix add tmdb show 13916 # Death Note (2006) +flix add tmdb show 1405 # Dexter (2006) +flix add tmdb show 1399 # Game of Thrones (2011) +flix add tmdb show 40075 # Gravity Falls (2012) +flix add tmdb show 1639 # Heroes (2006) +flix add tmdb show 60858 # Heroes Reborn (2015) +flix add tmdb show 62687 # Limitless (2015) +flix add tmdb show 60846 # Log Horizon (2013) +flix add tmdb show 64432 # The Magicians (2015) +flix add tmdb show 5920 # The Mentalist (2008) +flix add tmdb show 12786 # Murdoch Mysteries (2008) +flix add tmdb season 12786 0 # Murdoch Mysteries Specials +flix add tmdb show 65930 # My Hero Academia (2016) +flix add tmdb show 2288 # Prison Break (2005) +flix add tmdb show 95396 # Severance (2022) +flix add tmdb show 60573 # Silicon Valley (2014) +flix add tmdb show 37680 # Suits (2011) +flix add tmdb show 45782 # Sword Art Online (2012) +flix add tmdb show 63404 # Taskmaster (2015) +flix add tmdb season 63404 0 # Taskmaster Specials +flix add tmdb show 48860 # The Tomorrow People (2013) +flix add tmdb show 46331 # Under the Dome (2013) +flix add tmdb show 1432 # Veronica Mars (2004) +flix add tmdb show 186 # Weeds (2005) +flix add tmdb show 63247 # Westworld (2016) +flix add tmdb show 71912 # The Witcher (2019) diff --git a/tombi.toml b/tombi.toml index 6ee615f..34aa2df 100644 --- a/tombi.toml +++ b/tombi.toml @@ -3,3 +3,9 @@ toml-version = "v1.0.0" [format.rules] indent-style = "tab" indent-width = 4 + +# Required for rust <1.94 +[[schemas]] +toml-version = "v1.0.0" +path = "tombi://www.schemastore.org/cargo.json" +include = ["Cargo.toml"]