commit 3cb82612beedbc1efd02de9d7c4091a3fe0e17be Author: uttarayan21 Date: Wed Oct 8 14:50:15 2025 +0530 feat: Initial commit diff --git a/.envrc b/.envrc new file mode 100644 index 0000000..3550a30 --- /dev/null +++ b/.envrc @@ -0,0 +1 @@ +use flake diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 0000000..d8894ee --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,62 @@ +name: build + +on: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +env: + CARGO_TERM_COLOR: always + +jobs: + checks-matrix: + runs-on: ubuntu-latest + outputs: + matrix: ${{ steps.set-matrix.outputs.matrix }} + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - id: set-matrix + name: Generate Nix Matrix + run: | + set -Eeu + matrix="$(nix eval --json '.#githubActions.matrix')" + echo "matrix=$matrix" >> "$GITHUB_OUTPUT" + + checks-build: + needs: checks-matrix + runs-on: ${{ matrix.os }} + strategy: + matrix: ${{fromJSON(needs.checks-matrix.outputs.matrix)}} + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - run: nix build -L '.#${{ matrix.attr }}' + + codecov: + runs-on: ubuntu-latest + permissions: + id-token: "write" + contents: "read" + + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + + - name: Run codecov + run: nix build .#checks.x86_64-linux.hello-llvm-cov + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v4.0.1 + with: + flags: unittests + name: codecov-hello + fail_ci_if_error: true + token: ${{ secrets.CODECOV_TOKEN }} + files: ./result + verbose: true + diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..c7048c4 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,38 @@ +name: docs + +on: + push: + branches: [ master ] + +env: + CARGO_TERM_COLOR: always + +jobs: + docs: + runs-on: ubuntu-latest + permissions: + id-token: "write" + contents: "read" + pages: "write" + + steps: + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + - uses: DeterminateSystems/flake-checker-action@main + + - name: Generate docs + run: nix build .#checks.x86_64-linux.hello-docs + + - name: Setup Pages + uses: actions/configure-pages@v5 + + - name: Upload artifact + uses: actions/upload-pages-artifact@v3 + with: + path: result/share/doc + + - name: Deploy to gh-pages + id: deployment + uses: actions/deploy-pages@v4 + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6210698 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/result +/target +.direnv diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..e4d82a8 --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,2370 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 4 + +[[package]] +name = "addr2line" +version = "0.24.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfbe277e56a376000877090da837660b4427aad530e3028d44e0bffe4f89a1c1" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler2" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627" + +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + +[[package]] +name = "anstream" +version = "0.6.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" +dependencies = [ + "anstyle", + "anstyle-parse", + "anstyle-query", + "anstyle-wincon", + "colorchoice", + "is_terminal_polyfill", + "utf8parse", +] + +[[package]] +name = "anstyle" +version = "1.0.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9" + +[[package]] +name = "anstyle-parse" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" +dependencies = [ + "utf8parse", +] + +[[package]] +name = "anstyle-query" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" +dependencies = [ + "windows-sys 0.59.0", +] + +[[package]] +name = "anstyle-wincon" +version = "3.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e" +dependencies = [ + "anstyle", + "once_cell", + "windows-sys 0.59.0", +] + +[[package]] +name = "anyhow" +version = "1.0.97" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f" + +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + +[[package]] +name = "autocfg" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" + +[[package]] +name = "backtrace" +version = "0.3.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d82cb332cdfaed17ae235a638438ac4d4839913cc2af585c3c6746e8f8bee1a" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", + "windows-targets", +] + +[[package]] +name = "base64" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" + +[[package]] +name = "bitflags" +version = "2.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2261d10cca569e4643e526d8dc2e62e433cc8aba21ab764233731f8d369bf394" + +[[package]] +name = "bumpalo" +version = "3.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" + +[[package]] +name = "bytes" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" + +[[package]] +name = "cassowary" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df8670b8c7b9dae1793364eafadf7239c40d669904660c5960d74cfd80b46a53" + +[[package]] +name = "castaway" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a" +dependencies = [ + "rustversion", +] + +[[package]] +name = "cc" +version = "1.2.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb" +dependencies = [ + "find-msvc-tools", + "shlex", +] + +[[package]] +name = "cfg-if" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" + +[[package]] +name = "chrono" +version = "0.4.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +dependencies = [ + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-link 0.2.1", +] + +[[package]] +name = "clap" +version = "4.5.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8aa86934b44c19c50f87cc2790e19f54f7a67aedb64101c2e1a2e5ecfb73944" +dependencies = [ + "clap_builder", + "clap_derive", +] + +[[package]] +name = "clap_builder" +version = "4.5.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2414dbb2dd0695280da6ea9261e327479e9d37b0630f6b53ba2a11c60c679fd9" +dependencies = [ + "anstream", + "anstyle", + "clap_lex", + "strsim", +] + +[[package]] +name = "clap_complete" +version = "4.5.47" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6" +dependencies = [ + "clap", +] + +[[package]] +name = "clap_derive" +version = "4.5.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09176aae279615badda0765c0c0b3f6ed53f4709118af73cf4655d85d1530cd7" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "clap_lex" +version = "0.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6" + +[[package]] +name = "colorchoice" +version = "1.0.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" + +[[package]] +name = "compact_str" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b79c4069c6cad78e2e0cdfcbd26275770669fb39fd308a752dc110e83b9af32" +dependencies = [ + "castaway", + "cfg-if", + "itoa", + "rustversion", + "ryu", + "static_assertions", +] + +[[package]] +name = "core-foundation" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "core-foundation-sys" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" + +[[package]] +name = "crossterm" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "829d955a0bb380ef178a640b91779e3987da38c9aea133b20614cfed8cdea9c6" +dependencies = [ + "bitflags", + "crossterm_winapi", + "mio", + "parking_lot", + "rustix 0.38.44", + "signal-hook", + "signal-hook-mio", + "winapi", +] + +[[package]] +name = "crossterm_winapi" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "acdd7c62a3665c7f6830a51635d9ac9b23ed385797f70a83bb8bafe9c572ab2b" +dependencies = [ + "winapi", +] + +[[package]] +name = "darling" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d00b9596d185e565c2207a0b01f8bd1a135483d02d9b7b0a54b11da8d53412e" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn", +] + +[[package]] +name = "darling_macro" +version = "0.20.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" +dependencies = [ + "darling_core", + "quote", + "syn", +] + +[[package]] +name = "displaydoc" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "either" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" + +[[package]] +name = "encoding_rs" +version = "0.8.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "equivalent" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f" + +[[package]] +name = "errno" +version = "0.3.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb" +dependencies = [ + "libc", + "windows-sys 0.61.2", +] + +[[package]] +name = "error-stack" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fe413319145d1063f080f27556fd30b1d70b01e2ba10c2a6e40d4be982ffc5d1" +dependencies = [ + "anyhow", + "rustc_version", +] + +[[package]] +name = "fastrand" +version = "2.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" + +[[package]] +name = "find-msvc-tools" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3" + +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + +[[package]] +name = "foldhash" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" + +[[package]] +name = "foreign-types" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1" +dependencies = [ + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-shared" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b" + +[[package]] +name = "form_urlencoded" +version = "1.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb4cb245038516f5f85277875cdaa4f7d2c9a0fa0468de06ed190163b1581fcf" +dependencies = [ + "percent-encoding", +] + +[[package]] +name = "futures" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" +dependencies = [ + "futures-channel", + "futures-core", + "futures-executor", + "futures-io", + "futures-sink", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-channel" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dff15bf788c671c1934e366d07e30c1814a8ef514e1af724a602e8a2fbe1b10" +dependencies = [ + "futures-core", + "futures-sink", +] + +[[package]] +name = "futures-core" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f29059c0c2090612e8d742178b0580d2dc940c837851ad723096f87af6663e" + +[[package]] +name = "futures-executor" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e28d1d997f585e54aebc3f97d39e72338912123a67330d723fdbb564d646c9f" +dependencies = [ + "futures-core", + "futures-task", + "futures-util", +] + +[[package]] +name = "futures-io" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e5c1b78ca4aae1ac06c48a526a655760685149f0d465d21f37abfe57ce075c6" + +[[package]] +name = "futures-macro" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "futures-sink" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e575fab7d1e0dcb8d0c7bcf9a63ee213816ab51902e6d244a95819acacf1d4f7" + +[[package]] +name = "futures-task" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f90f7dce0722e95104fcb095585910c0977252f286e354b5e3bd38902cd99988" + +[[package]] +name = "futures-util" +version = "0.3.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9fa08315bb612088cc391249efdc3bc77536f16c91f6cf495e6fbe85b20a4a81" +dependencies = [ + "futures-channel", + "futures-core", + "futures-io", + "futures-macro", + "futures-sink", + "futures-task", + "memchr", + "pin-project-lite", + "pin-utils", + "slab", +] + +[[package]] +name = "getrandom" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +dependencies = [ + "cfg-if", + "libc", + "wasi 0.11.1+wasi-snapshot-preview1", +] + +[[package]] +name = "getrandom" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" +dependencies = [ + "cfg-if", + "libc", + "r-efi", + "wasi 0.14.7+wasi-0.2.4", +] + +[[package]] +name = "gimli" +version = "0.31.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07e28edb80900c19c28f1072f2e8aeca7fa06b23cd4169cefe1af5aa3260783f" + +[[package]] +name = "h2" +version = "0.4.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f3c0b69cfcb4e1b9f1bf2f53f95f766e4661169728ec61cd3fe5a0166f2d1386" +dependencies = [ + "atomic-waker", + "bytes", + "fnv", + "futures-core", + "futures-sink", + "http", + "indexmap", + "slab", + "tokio", + "tokio-util", + "tracing", +] + +[[package]] +name = "hashbrown" +version = "0.15.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1" +dependencies = [ + "allocator-api2", + "equivalent", + "foldhash", +] + +[[package]] +name = "hashbrown" +version = "0.16.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d" + +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + +[[package]] +name = "http" +version = "1.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + +[[package]] +name = "http-body" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" +dependencies = [ + "bytes", + "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" +dependencies = [ + "bytes", + "futures-core", + "http", + "http-body", + "pin-project-lite", +] + +[[package]] +name = "httparse" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87" + +[[package]] +name = "hyper" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb3aa54a13a0dfe7fbe3a59e0c76093041720fdc77b110cc0fc260fafb4dc51e" +dependencies = [ + "atomic-waker", + "bytes", + "futures-channel", + "futures-core", + "h2", + "http", + "http-body", + "httparse", + "itoa", + "pin-project-lite", + "pin-utils", + "smallvec", + "tokio", + "want", +] + +[[package]] +name = "hyper-rustls" +version = "0.27.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" +dependencies = [ + "http", + "hyper", + "hyper-util", + "rustls", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower-service", +] + +[[package]] +name = "hyper-tls" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0" +dependencies = [ + "bytes", + "http-body-util", + "hyper", + "hyper-util", + "native-tls", + "tokio", + "tokio-native-tls", + "tower-service", +] + +[[package]] +name = "hyper-util" +version = "0.1.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c6995591a8f1380fcb4ba966a252a4b29188d51d2b89e3a252f5305be65aea8" +dependencies = [ + "base64", + "bytes", + "futures-channel", + "futures-core", + "futures-util", + "http", + "http-body", + "hyper", + "ipnet", + "libc", + "percent-encoding", + "pin-project-lite", + "socket2", + "system-configuration", + "tokio", + "tower-service", + "tracing", + "windows-registry", +] + +[[package]] +name = "iana-time-zone" +version = "0.1.64" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33e57f83510bb73707521ebaffa789ec8caf86f9657cad665b092b581d40e9fb" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "log", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "icu_collections" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "200072f5d0e3614556f94a9930d5dc3e0662a652823904c3a75dc3b0af7fee47" +dependencies = [ + "displaydoc", + "potential_utf", + "yoke", + "zerofrom", + "zerovec", +] + +[[package]] +name = "icu_locale_core" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0cde2700ccaed3872079a65fb1a78f6c0a36c91570f28755dda67bc8f7d9f00a" +dependencies = [ + "displaydoc", + "litemap", + "tinystr", + "writeable", + "zerovec", +] + +[[package]] +name = "icu_normalizer" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "436880e8e18df4d7bbc06d58432329d6458cc84531f7ac5f024e93deadb37979" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_normalizer_data", + "icu_properties", + "icu_provider", + "smallvec", + "zerovec", +] + +[[package]] +name = "icu_normalizer_data" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "00210d6893afc98edb752b664b8890f0ef174c8adbb8d0be9710fa66fbbf72d3" + +[[package]] +name = "icu_properties" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "016c619c1eeb94efb86809b015c58f479963de65bdb6253345c1a1276f22e32b" +dependencies = [ + "displaydoc", + "icu_collections", + "icu_locale_core", + "icu_properties_data", + "icu_provider", + "potential_utf", + "zerotrie", + "zerovec", +] + +[[package]] +name = "icu_properties_data" +version = "2.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "298459143998310acd25ffe6810ed544932242d3f07083eee1084d83a71bd632" + +[[package]] +name = "icu_provider" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "03c80da27b5f4187909049ee2d72f276f0d9f99a42c306bd0131ecfe04d8e5af" +dependencies = [ + "displaydoc", + "icu_locale_core", + "stable_deref_trait", + "tinystr", + "writeable", + "yoke", + "zerofrom", + "zerotrie", + "zerovec", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + +[[package]] +name = "idna" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b0875f23caa03898994f6ddc501886a45c7d3d62d04d2d90788d47be1b1e4de" +dependencies = [ + "idna_adapter", + "smallvec", + "utf8_iter", +] + +[[package]] +name = "idna_adapter" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344" +dependencies = [ + "icu_normalizer", + "icu_properties", +] + +[[package]] +name = "indexmap" +version = "2.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4b0f83760fb341a774ed326568e19f5a863af4a952def8c39f9ab92fd95b88e5" +dependencies = [ + "equivalent", + "hashbrown 0.16.0", +] + +[[package]] +name = "indoc" +version = "2.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f4c7245a08504955605670dbf141fceab975f15ca21570696aebe9d2e71576bd" + +[[package]] +name = "instability" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "435d80800b936787d62688c927b6490e887c7ef5ff9ce922c6c6050fca75eb9a" +dependencies = [ + "darling", + "indoc", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ipnet" +version = "2.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "469fb0b9cefa57e3ef31275ee7cacb78f2fdca44e4765491884a2b119d4eb130" + +[[package]] +name = "iri-string" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dbc5ebe9c3a1a7a5127f920a418f7585e9e758e911d0466ed004f393b0e380b2" +dependencies = [ + "memchr", + "serde", +] + +[[package]] +name = "is_terminal_polyfill" +version = "1.70.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf" + +[[package]] +name = "itertools" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186" +dependencies = [ + "either", +] + +[[package]] +name = "itoa" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" + +[[package]] +name = "js-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec48937a97411dcb524a265206ccd4c90bb711fca92b2792c407f268825b9305" +dependencies = [ + "once_cell", + "wasm-bindgen", +] + +[[package]] +name = "lazy_static" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" + +[[package]] +name = "libc" +version = "0.2.171" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" + +[[package]] +name = "linux-raw-sys" +version = "0.4.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" + +[[package]] +name = "linux-raw-sys" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "df1d3c3b53da64cf5760482273a98e575c651a67eec7f77df96b5b642de8f039" + +[[package]] +name = "litemap" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "241eaef5fd12c88705a01fc1066c48c4b36e0dd4377dcdc7ec3942cea7a69956" + +[[package]] +name = "lock_api" +version = "0.4.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" +dependencies = [ + "scopeguard", +] + +[[package]] +name = "log" +version = "0.4.27" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" + +[[package]] +name = "lru" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "234cf4f4a04dc1f57e24b96cc0cd600cf2af460d4161ac5ecdd0af8e1f3b2a38" +dependencies = [ + "hashbrown 0.15.5", +] + +[[package]] +name = "memchr" +version = "2.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" + +[[package]] +name = "mime" +version = "0.3.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a" + +[[package]] +name = "miniz_oxide" +version = "0.8.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ff70ce3e48ae43fa075863cef62e8b43b71a4f2382229920e0df362592919430" +dependencies = [ + "adler2", +] + +[[package]] +name = "mio" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c" +dependencies = [ + "libc", + "log", + "wasi 0.11.1+wasi-snapshot-preview1", + "windows-sys 0.59.0", +] + +[[package]] +name = "native-tls" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e" +dependencies = [ + "libc", + "log", + "openssl", + "openssl-probe", + "openssl-sys", + "schannel", + "security-framework", + "security-framework-sys", + "tempfile", +] + +[[package]] +name = "nu-ansi-term" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84" +dependencies = [ + "overload", + "winapi", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + +[[package]] +name = "object" +version = "0.36.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87" +dependencies = [ + "memchr", +] + +[[package]] +name = "once_cell" +version = "1.21.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d" + +[[package]] +name = "openssl" +version = "0.10.73" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8505734d46c8ab1e19a1dce3aef597ad87dcb4c37e7188231769bd6bd51cebf8" +dependencies = [ + "bitflags", + "cfg-if", + "foreign-types", + "libc", + "once_cell", + "openssl-macros", + "openssl-sys", +] + +[[package]] +name = "openssl-macros" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "openssl-probe" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e" + +[[package]] +name = "openssl-sys" +version = "0.9.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90096e2e47630d78b7d1c20952dc621f957103f8bc2c8359ec81290d75238571" +dependencies = [ + "cc", + "libc", + "pkg-config", + "vcpkg", +] + +[[package]] +name = "overload" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" + +[[package]] +name = "parking_lot" +version = "0.12.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "93857453250e3077bd71ff98b6a65ea6621a19bb0f559a85248955ac12c45a1a" +dependencies = [ + "lock_api", + "parking_lot_core", +] + +[[package]] +name = "parking_lot_core" +version = "0.9.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-link 0.2.1", +] + +[[package]] +name = "paste" +version = "1.0.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a" + +[[package]] +name = "percent-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" + +[[package]] +name = "pin-project-lite" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" + +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + +[[package]] +name = "pkg-config" +version = "0.3.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" + +[[package]] +name = "potential_utf" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "84df19adbe5b5a0782edcab45899906947ab039ccf4573713735ee7de1e6b08a" +dependencies = [ + "zerovec", +] + +[[package]] +name = "proc-macro2" +version = "1.0.94" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a31971752e70b8b2686d7e46ec17fb38dad4051d94024c88df49b667caea9c84" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "quote" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "r-efi" +version = "5.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f" + +[[package]] +name = "ratatui" +version = "0.28.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdef7f9be5c0122f890d58bdf4d964349ba6a6161f705907526d891efabba57d" +dependencies = [ + "bitflags", + "cassowary", + "compact_str", + "crossterm", + "instability", + "itertools", + "lru", + "paste", + "strum", + "strum_macros", + "unicode-segmentation", + "unicode-truncate", + "unicode-width", +] + +[[package]] +name = "redox_syscall" +version = "0.5.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d" +dependencies = [ + "bitflags", +] + +[[package]] +name = "reqwest" +version = "0.12.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d429f34c8092b2d42c7c93cec323bb4adeb7c67698f70839adec842ec10c7ceb" +dependencies = [ + "base64", + "bytes", + "encoding_rs", + "futures-core", + "h2", + "http", + "http-body", + "http-body-util", + "hyper", + "hyper-rustls", + "hyper-tls", + "hyper-util", + "js-sys", + "log", + "mime", + "native-tls", + "percent-encoding", + "pin-project-lite", + "rustls-pki-types", + "serde", + "serde_json", + "serde_urlencoded", + "sync_wrapper", + "tokio", + "tokio-native-tls", + "tower", + "tower-http", + "tower-service", + "url", + "wasm-bindgen", + "wasm-bindgen-futures", + "web-sys", +] + +[[package]] +name = "ring" +version = "0.17.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" +dependencies = [ + "cc", + "cfg-if", + "getrandom 0.2.16", + "libc", + "untrusted", + "windows-sys 0.52.0", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" + +[[package]] +name = "rustc_version" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" +dependencies = [ + "semver", +] + +[[package]] +name = "rustix" +version = "0.38.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.4.15", + "windows-sys 0.59.0", +] + +[[package]] +name = "rustix" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd15f8a2c5551a84d56efdc1cd049089e409ac19a3072d5037a17fd70719ff3e" +dependencies = [ + "bitflags", + "errno", + "libc", + "linux-raw-sys 0.11.0", + "windows-sys 0.61.2", +] + +[[package]] +name = "rustls" +version = "0.23.32" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cd3c25631629d034ce7cd9940adc9d45762d46de2b0f57193c4443b92c6d4d40" +dependencies = [ + "once_cell", + "rustls-pki-types", + "rustls-webpki", + "subtle", + "zeroize", +] + +[[package]] +name = "rustls-pki-types" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229a4a4c221013e7e1f1a043678c5cc39fe5171437c88fb47151a21e6f5b5c79" +dependencies = [ + "zeroize", +] + +[[package]] +name = "rustls-webpki" +version = "0.103.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e10b3f4191e8a80e6b43eebabfac91e5dcecebb27a71f04e820c47ec41d314bf" +dependencies = [ + "ring", + "rustls-pki-types", + "untrusted", +] + +[[package]] +name = "rustversion" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" + +[[package]] +name = "ryu" +version = "1.0.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28d3b2b1366ec20994f1fd18c3c594f05c5dd4bc44d8bb0c1c632c8d6829481f" + +[[package]] +name = "schannel" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "891d81b926048e76efe18581bf793546b4c0eaf8448d72be8de2bbee5fd166e1" +dependencies = [ + "windows-sys 0.61.2", +] + +[[package]] +name = "scopeguard" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" + +[[package]] +name = "security-framework" +version = "2.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" +dependencies = [ + "bitflags", + "core-foundation", + "core-foundation-sys", + "libc", + "security-framework-sys", +] + +[[package]] +name = "security-framework-sys" +version = "2.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc1f0cbffaac4852523ce30d8bd3c5cdc873501d96ff467ca09b6767bb8cd5c0" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "semver" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6fa9c48d24d85fb3de5ad847117517440f6beceb7798af16b4a87d616b8d0" + +[[package]] +name = "serde" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e" +dependencies = [ + "serde_core", + "serde_derive", +] + +[[package]] +name = "serde_core" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.228" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.145" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c" +dependencies = [ + "itoa", + "memchr", + "ryu", + "serde", + "serde_core", +] + +[[package]] +name = "serde_urlencoded" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3491c14715ca2294c4d6a88f15e84739788c1d030eed8c110436aafdaa2f3fd" +dependencies = [ + "form_urlencoded", + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "sharded-slab" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "shlex" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64" + +[[package]] +name = "signal-hook" +version = "0.3.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d881a16cf4426aa584979d30bd82cb33429027e42122b169753d6ef1085ed6e2" +dependencies = [ + "libc", + "signal-hook-registry", +] + +[[package]] +name = "signal-hook-mio" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34db1a06d485c9142248b7a054f034b349b212551f3dfd19c94d45a754a217cd" +dependencies = [ + "libc", + "mio", + "signal-hook", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2a4719bff48cee6b39d12c020eeb490953ad2443b7055bd0b21fca26bd8c28b" +dependencies = [ + "libc", +] + +[[package]] +name = "slab" +version = "0.4.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a2ae44ef20feb57a68b23d846850f861394c2e02dc425a50098ae8c90267589" + +[[package]] +name = "smallvec" +version = "1.15.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8917285742e9f3e1683f0a9c4e6b57960b7314d0b08d30d1ecd426713ee2eee9" + +[[package]] +name = "socket2" +version = "0.5.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e22376abed350d73dd1cd119b57ffccad95b4e585a7cda43e286245ce23c0678" +dependencies = [ + "libc", + "windows-sys 0.52.0", +] + +[[package]] +name = "stable_deref_trait" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3" + +[[package]] +name = "static_assertions" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" + +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "strum" +version = "0.26.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fec0f0aef304996cf250b31b5a10dee7980c85da9d759361292b8bca5a18f06" +dependencies = [ + "strum_macros", +] + +[[package]] +name = "strum_macros" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c6bee85a5a24955dc440386795aa378cd9cf82acd5f764469152d2270e581be" +dependencies = [ + "heck", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "subtle" +version = "2.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" + +[[package]] +name = "syn" +version = "2.0.100" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" +dependencies = [ + "proc-macro2", + "quote", + "unicode-ident", +] + +[[package]] +name = "sync_wrapper" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0bf256ce5efdfa370213c1dabab5935a12e49f2c58d15e9eac2870d3b4f27263" +dependencies = [ + "futures-core", +] + +[[package]] +name = "synstructure" +version = "0.13.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "system-configuration" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b" +dependencies = [ + "bitflags", + "core-foundation", + "system-configuration-sys", +] + +[[package]] +name = "system-configuration-sys" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4" +dependencies = [ + "core-foundation-sys", + "libc", +] + +[[package]] +name = "tempfile" +version = "3.23.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2d31c77bdf42a745371d260a26ca7163f1e0924b64afa0b688e61b5a9fa02f16" +dependencies = [ + "fastrand", + "getrandom 0.3.3", + "once_cell", + "rustix 1.1.2", + "windows-sys 0.61.2", +] + +[[package]] +name = "thiserror" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "567b8a2dae586314f7be2a752ec7474332959c6460e02bde30d702a66d488708" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "2.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "thread_local" +version = "1.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" +dependencies = [ + "cfg-if", + "once_cell", +] + +[[package]] +name = "tinystr" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d4f6d1145dcb577acf783d4e601bc1d76a13337bb54e6233add580b07344c8b" +dependencies = [ + "displaydoc", + "zerovec", +] + +[[package]] +name = "tokio" +version = "1.44.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6b88822cbe49de4185e3a4cbf8321dd487cf5fe0c5c65695fef6346371e9c48" +dependencies = [ + "backtrace", + "bytes", + "libc", + "mio", + "parking_lot", + "pin-project-lite", + "signal-hook-registry", + "socket2", + "tokio-macros", + "windows-sys 0.52.0", +] + +[[package]] +name = "tokio-macros" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tokio-native-tls" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2" +dependencies = [ + "native-tls", + "tokio", +] + +[[package]] +name = "tokio-rustls" +version = "0.26.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1729aa945f29d91ba541258c8df89027d5792d85a8841fb65e8bf0f4ede4ef61" +dependencies = [ + "rustls", + "tokio", +] + +[[package]] +name = "tokio-util" +version = "0.7.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14307c986784f72ef81c89db7d9e28d6ac26d16213b109ea501696195e6e3ce5" +dependencies = [ + "bytes", + "futures-core", + "futures-sink", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "tower" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +dependencies = [ + "futures-core", + "futures-util", + "pin-project-lite", + "sync_wrapper", + "tokio", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-http" +version = "0.6.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adc82fd73de2a9722ac5da747f12383d2bfdb93591ee6c58486e0097890f05f2" +dependencies = [ + "bitflags", + "bytes", + "futures-util", + "http", + "http-body", + "iri-string", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", +] + +[[package]] +name = "tower-layer" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "121c2a6cda46980bb0fcd1647ffaf6cd3fc79a013de288782836f6df9c48780e" + +[[package]] +name = "tower-service" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" + +[[package]] +name = "tracing" +version = "0.1.41" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" +dependencies = [ + "pin-project-lite", + "tracing-attributes", + "tracing-core", +] + +[[package]] +name = "tracing-attributes" +version = "0.1.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "tracing-core" +version = "0.1.33" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" +dependencies = [ + "once_cell", + "valuable", +] + +[[package]] +name = "tracing-log" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3" +dependencies = [ + "log", + "once_cell", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.3.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" +dependencies = [ + "nu-ansi-term", + "sharded-slab", + "smallvec", + "thread_local", + "tracing-core", + "tracing-log", +] + +[[package]] +name = "try-lock" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e421abadd41a4225275504ea4d6566923418b7f05506fbc9c0fe86ba7396114b" + +[[package]] +name = "unicode-ident" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512" + +[[package]] +name = "unicode-segmentation" +version = "1.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" + +[[package]] +name = "unicode-truncate" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3644627a5af5fa321c95b9b235a72fd24cd29c648c2c379431e6628655627bf" +dependencies = [ + "itertools", + "unicode-segmentation", + "unicode-width", +] + +[[package]] +name = "unicode-width" +version = "0.1.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dd6e30e90baa6f72411720665d41d89b9a3d039dc45b8faea1ddd07f617f6af" + +[[package]] +name = "untrusted" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" + +[[package]] +name = "url" +version = "2.5.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08bc136a29a3d1758e07a9cca267be308aeebf5cfd5a10f3f67ab2097683ef5b" +dependencies = [ + "form_urlencoded", + "idna", + "percent-encoding", + "serde", +] + +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + +[[package]] +name = "utf8_iter" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be" + +[[package]] +name = "utf8parse" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" + +[[package]] +name = "valuable" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65" + +[[package]] +name = "vcpkg" +version = "0.2.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" + +[[package]] +name = "want" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa7760aed19e106de2c7c0b581b509f2f25d3dacaf737cb82ac61bc6d760b0e" +dependencies = [ + "try-lock", +] + +[[package]] +name = "wasi" +version = "0.11.1+wasi-snapshot-preview1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" + +[[package]] +name = "wasi" +version = "0.14.7+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "883478de20367e224c0090af9cf5f9fa85bed63a95c1abf3afc5c083ebc06e8c" +dependencies = [ + "wasip2", +] + +[[package]] +name = "wasip2" +version = "1.0.1+wasi-0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +dependencies = [ + "wit-bindgen", +] + +[[package]] +name = "wasm-bindgen" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c1da10c01ae9f1ae40cbfac0bac3b1e724b320abfcf52229f80b547c0d250e2d" +dependencies = [ + "cfg-if", + "once_cell", + "rustversion", + "wasm-bindgen-macro", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-backend" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "671c9a5a66f49d8a47345ab942e2cb93c7d1d0339065d4f8139c486121b43b19" +dependencies = [ + "bumpalo", + "log", + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-futures" +version = "0.4.54" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e038d41e478cc73bae0ff9b36c60cff1c98b8f38f8d7e8061e79ee63608ac5c" +dependencies = [ + "cfg-if", + "js-sys", + "once_cell", + "wasm-bindgen", + "web-sys", +] + +[[package]] +name = "wasm-bindgen-macro" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ca60477e4c59f5f2986c50191cd972e3a50d8a95603bc9434501cf156a9a119" +dependencies = [ + "quote", + "wasm-bindgen-macro-support", +] + +[[package]] +name = "wasm-bindgen-macro-support" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f07d2f20d4da7b26400c9f4a0511e6e0345b040694e8a75bd41d578fa4421d7" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "wasm-bindgen-backend", + "wasm-bindgen-shared", +] + +[[package]] +name = "wasm-bindgen-shared" +version = "0.2.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bad67dc8b2a1a6e5448428adec4c3e84c43e561d8c9ee8a9e5aabeb193ec41d1" +dependencies = [ + "unicode-ident", +] + +[[package]] +name = "web-sys" +version = "0.3.81" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9367c417a924a74cae129e6a2ae3b47fabb1f8995595ab474029da749a8be120" +dependencies = [ + "js-sys", + "wasm-bindgen", +] + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" + +[[package]] +name = "windows-core" +version = "0.62.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e83a14d34d0623b51dce9581199302a221863196a1dde71a7663a4c2be9deb" +dependencies = [ + "windows-implement", + "windows-interface", + "windows-link 0.2.1", + "windows-result 0.4.1", + "windows-strings 0.5.1", +] + +[[package]] +name = "windows-implement" +version = "0.60.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053e2e040ab57b9dc951b72c264860db7eb3b0200ba345b4e4c3b14f67855ddf" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-interface" +version = "0.59.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f316c4a2570ba26bbec722032c4099d8c8bc095efccdc15688708623367e358" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "windows-link" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e6ad25900d524eaabdbbb96d20b4311e1e7ae1699af4fb28c17ae66c80d798a" + +[[package]] +name = "windows-link" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0805222e57f7521d6a62e36fa9163bc891acd422f971defe97d64e70d0a4fe5" + +[[package]] +name = "windows-registry" +version = "0.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e" +dependencies = [ + "windows-link 0.1.3", + "windows-result 0.3.4", + "windows-strings 0.4.2", +] + +[[package]] +name = "windows-result" +version = "0.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56f42bd332cc6c8eac5af113fc0c1fd6a8fd2aa08a0119358686e5160d0586c6" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-result" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7781fa89eaf60850ac3d2da7af8e5242a5ea78d1a11c49bf2910bb5a73853eb5" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-strings" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56e6c93f3a0c3b36176cb1327a4958a0353d5d166c2a35cb268ace15e91d3b57" +dependencies = [ + "windows-link 0.1.3", +] + +[[package]] +name = "windows-strings" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7837d08f69c77cf6b07689544538e017c1bfcf57e34b4c0ff58e6c2cd3b37091" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-sys" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.59.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b" +dependencies = [ + "windows-targets", +] + +[[package]] +name = "windows-sys" +version = "0.61.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ae137229bcbd6cdf0f7b80a31df61766145077ddf49416a728b02cb3921ff3fc" +dependencies = [ + "windows-link 0.2.1", +] + +[[package]] +name = "windows-targets" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" +dependencies = [ + "windows_aarch64_gnullvm", + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_gnullvm", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_gnullvm", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" + +[[package]] +name = "windows_aarch64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" + +[[package]] +name = "windows_i686_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" + +[[package]] +name = "windows_i686_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" + +[[package]] +name = "windows_x86_64_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wit-bindgen" +version = "0.46.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" + +[[package]] +name = "writeable" +version = "0.6.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" + +[[package]] +name = "yarr" +version = "0.1.0" +dependencies = [ + "chrono", + "clap", + "clap_complete", + "crossterm", + "error-stack", + "futures", + "ratatui", + "reqwest", + "serde", + "serde_json", + "thiserror", + "tokio", + "tracing", + "tracing-subscriber", + "urlencoding", +] + +[[package]] +name = "yoke" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f41bb01b8226ef4bfd589436a297c53d118f65921786300e427be8d487695cc" +dependencies = [ + "serde", + "stable_deref_trait", + "yoke-derive", + "zerofrom", +] + +[[package]] +name = "yoke-derive" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zerofrom" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +dependencies = [ + "zerofrom-derive", +] + +[[package]] +name = "zerofrom-derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "synstructure", +] + +[[package]] +name = "zeroize" +version = "1.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" + +[[package]] +name = "zerotrie" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "36f0bbd478583f79edad978b407914f61b2972f5af6fa089686016be8f9af595" +dependencies = [ + "displaydoc", + "yoke", + "zerofrom", +] + +[[package]] +name = "zerovec" +version = "0.11.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7aa2bd55086f1ab526693ecbe444205da57e25f4489879da80635a46d90e73b" +dependencies = [ + "yoke", + "zerofrom", + "zerovec-derive", +] + +[[package]] +name = "zerovec-derive" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..dced7d6 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,34 @@ +[package] +name = "yarr" +version = "0.1.0" +edition = "2021" +license = "MIT" + +[[bin]] +name = "yarr" +path = "src/main.rs" + +[dependencies] +clap = { version = "4.5", features = ["derive"] } +clap_complete = "4.5" +error-stack = "0.5" +thiserror = "2.0" +tokio = { version = "1.43.1", features = ["full"] } +tracing = "0.1" +tracing-subscriber = "0.3" + +# TUI dependencies +ratatui = { version = "0.28", features = ["crossterm"] } +crossterm = "0.28" + +# HTTP client and serialization +reqwest = { version = "0.12", features = ["json"] } +serde = { version = "1.0", features = ["derive"] } +serde_json = "1.0" + +# Date/time handling +chrono = { version = "0.4", features = ["serde"] } + +# Async utilities +futures = "0.3" +urlencoding = "2.1.3" diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..5578e66 --- /dev/null +++ b/deny.toml @@ -0,0 +1,236 @@ +# This template contains all of the possible sections and their default values + +# Note that all fields that take a lint level have these possible values: +# * deny - An error will be produced and the check will fail +# * warn - A warning will be produced, but the check will not fail +# * allow - No warning or error will be produced, though in some cases a note +# will be + +# The values provided in this template are the default values that will be used +# when any section or field is not specified in your own configuration + +# Root options + +# The graph table configures how the dependency graph is constructed and thus +# which crates the checks are performed against +[graph] +# If 1 or more target triples (and optionally, target_features) are specified, +# only the specified targets will be checked when running `cargo deny check`. +# This means, if a particular package is only ever used as a target specific +# dependency, such as, for example, the `nix` crate only being used via the +# `target_family = "unix"` configuration, that only having windows targets in +# this list would mean the nix crate, as well as any of its exclusive +# dependencies not shared by any other crates, would be ignored, as the target +# list here is effectively saying which targets you are building for. +targets = [ + # The triple can be any string, but only the target triples built in to + # rustc (as of 1.40) can be checked against actual config expressions + #"x86_64-unknown-linux-musl", + # You can also specify which target_features you promise are enabled for a + # particular target. target_features are currently not validated against + # the actual valid features supported by the target architecture. + #{ triple = "wasm32-unknown-unknown", features = ["atomics"] }, +] +# When creating the dependency graph used as the source of truth when checks are +# executed, this field can be used to prune crates from the graph, removing them +# from the view of cargo-deny. This is an extremely heavy hammer, as if a crate +# is pruned from the graph, all of its dependencies will also be pruned unless +# they are connected to another crate in the graph that hasn't been pruned, +# so it should be used with care. The identifiers are [Package ID Specifications] +# (https://doc.rust-lang.org/cargo/reference/pkgid-spec.html) +#exclude = [] +# If true, metadata will be collected with `--all-features`. Note that this can't +# be toggled off if true, if you want to conditionally enable `--all-features` it +# is recommended to pass `--all-features` on the cmd line instead +all-features = false +# If true, metadata will be collected with `--no-default-features`. The same +# caveat with `all-features` applies +no-default-features = false +# If set, these feature will be enabled when collecting metadata. If `--features` +# is specified on the cmd line they will take precedence over this option. +#features = [] + +# The output table provides options for how/if diagnostics are outputted +[output] +# When outputting inclusion graphs in diagnostics that include features, this +# option can be used to specify the depth at which feature edges will be added. +# This option is included since the graphs can be quite large and the addition +# of features from the crate(s) to all of the graph roots can be far too verbose. +# This option can be overridden via `--feature-depth` on the cmd line +feature-depth = 1 + +# This section is considered when running `cargo deny check advisories` +# More documentation for the advisories section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/advisories/cfg.html +[advisories] +# The path where the advisory databases are cloned/fetched into +#db-path = "$CARGO_HOME/advisory-dbs" +# The url(s) of the advisory databases to use +#db-urls = ["https://github.com/rustsec/advisory-db"] +# A list of advisory IDs to ignore. Note that ignored advisories will still +# output a note when they are encountered. +ignore = [ + #"RUSTSEC-0000-0000", + #{ id = "RUSTSEC-0000-0000", reason = "you can specify a reason the advisory is ignored" }, + #"a-crate-that-is-yanked@0.1.1", # you can also ignore yanked crate versions if you wish + #{ crate = "a-crate-that-is-yanked@0.1.1", reason = "you can specify why you are ignoring the yanked crate" }, +] +# If this is true, then cargo deny will use the git executable to fetch advisory database. +# If this is false, then it uses a built-in git library. +# Setting this to true can be helpful if you have special authentication requirements that cargo-deny does not support. +# See Git Authentication for more information about setting up git authentication. +#git-fetch-with-cli = true + +# This section is considered when running `cargo deny check licenses` +# More documentation for the licenses section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/licenses/cfg.html +[licenses] +# List of explicitly allowed licenses +# See https://spdx.org/licenses/ for list of possible licenses +# [possible values: any SPDX 3.11 short identifier (+ optional exception)]. +allow = [ + "MIT", + "Apache-2.0", + "Unicode-3.0", + #"Apache-2.0 WITH LLVM-exception", +] +# The confidence threshold for detecting a license from license text. +# The higher the value, the more closely the license text must be to the +# canonical license text of a valid SPDX license file. +# [possible values: any between 0.0 and 1.0]. +confidence-threshold = 0.8 +# Allow 1 or more licenses on a per-crate basis, so that particular licenses +# aren't accepted for every possible crate as with the normal allow list +exceptions = [ + # Each entry is the crate and version constraint, and its specific allow + # list + #{ allow = ["Zlib"], crate = "adler32" }, +] + +# Some crates don't have (easily) machine readable licensing information, +# adding a clarification entry for it allows you to manually specify the +# licensing information +#[[licenses.clarify]] +# The package spec the clarification applies to +#crate = "ring" +# The SPDX expression for the license requirements of the crate +#expression = "MIT AND ISC AND OpenSSL" +# One or more files in the crate's source used as the "source of truth" for +# the license expression. If the contents match, the clarification will be used +# when running the license check, otherwise the clarification will be ignored +# and the crate will be checked normally, which may produce warnings or errors +# depending on the rest of your configuration +#license-files = [ +# Each entry is a crate relative path, and the (opaque) hash of its contents +#{ path = "LICENSE", hash = 0xbd0eed23 } +#] + +[licenses.private] +# If true, ignores workspace crates that aren't published, or are only +# published to private registries. +# To see how to mark a crate as unpublished (to the official registry), +# visit https://doc.rust-lang.org/cargo/reference/manifest.html#the-publish-field. +ignore = false +# One or more private registries that you might publish crates to, if a crate +# is only published to private registries, and ignore is true, the crate will +# not have its license(s) checked +registries = [ + #"https://sekretz.com/registry +] + +# This section is considered when running `cargo deny check bans`. +# More documentation about the 'bans' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/bans/cfg.html +[bans] +# Lint level for when multiple versions of the same crate are detected +multiple-versions = "warn" +# Lint level for when a crate version requirement is `*` +wildcards = "allow" +# The graph highlighting used when creating dotgraphs for crates +# with multiple versions +# * lowest-version - The path to the lowest versioned duplicate is highlighted +# * simplest-path - The path to the version with the fewest edges is highlighted +# * all - Both lowest-version and simplest-path are used +highlight = "all" +# The default lint level for `default` features for crates that are members of +# the workspace that is being checked. This can be overridden by allowing/denying +# `default` on a crate-by-crate basis if desired. +workspace-default-features = "allow" +# The default lint level for `default` features for external crates that are not +# members of the workspace. This can be overridden by allowing/denying `default` +# on a crate-by-crate basis if desired. +external-default-features = "allow" +# List of crates that are allowed. Use with care! +allow = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is allowed" }, +] +# List of crates to deny +deny = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason it is banned" }, + # Wrapper crates can optionally be specified to allow the crate when it + # is a direct dependency of the otherwise banned crate + #{ crate = "ansi_term@0.11.0", wrappers = ["this-crate-directly-depends-on-ansi_term"] }, +] + +# List of features to allow/deny +# Each entry the name of a crate and a version range. If version is +# not specified, all versions will be matched. +#[[bans.features]] +#crate = "reqwest" +# Features to not allow +#deny = ["json"] +# Features to allow +#allow = [ +# "rustls", +# "__rustls", +# "__tls", +# "hyper-rustls", +# "rustls", +# "rustls-pemfile", +# "rustls-tls-webpki-roots", +# "tokio-rustls", +# "webpki-roots", +#] +# If true, the allowed features must exactly match the enabled feature set. If +# this is set there is no point setting `deny` +#exact = true + +# Certain crates/versions that will be skipped when doing duplicate detection. +skip = [ + #"ansi_term@0.11.0", + #{ crate = "ansi_term@0.11.0", reason = "you can specify a reason why it can't be updated/removed" }, +] +# Similarly to `skip` allows you to skip certain crates during duplicate +# detection. Unlike skip, it also includes the entire tree of transitive +# dependencies starting at the specified crate, up to a certain depth, which is +# by default infinite. +skip-tree = [ + #"ansi_term@0.11.0", # will be skipped along with _all_ of its direct and transitive dependencies + #{ crate = "ansi_term@0.11.0", depth = 20 }, +] + +# This section is considered when running `cargo deny check sources`. +# More documentation about the 'sources' section can be found here: +# https://embarkstudios.github.io/cargo-deny/checks/sources/cfg.html +[sources] +# Lint level for what to happen when a crate from a crate registry that is not +# in the allow list is encountered +unknown-registry = "warn" +# Lint level for what to happen when a crate from a git repository that is not +# in the allow list is encountered +unknown-git = "warn" +# List of URLs for allowed crate registries. Defaults to the crates.io index +# if not specified. If it is specified but empty, no registries are allowed. +allow-registry = ["https://github.com/rust-lang/crates.io-index"] +# List of URLs for allowed Git repositories +allow-git = [] + +[sources.allow-org] +# github.com organizations to allow git sources for +github = [] +# gitlab.com organizations to allow git sources for +gitlab = [] +# bitbucket.org organizations to allow git sources for +bitbucket = [] diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..4e9e507 --- /dev/null +++ b/flake.lock @@ -0,0 +1,136 @@ +{ + "nodes": { + "advisory-db": { + "flake": false, + "locked": { + "lastModified": 1750151065, + "narHash": "sha256-il+CAqChFIB82xP6bO43dWlUVs+NlG7a4g8liIP5HcI=", + "owner": "rustsec", + "repo": "advisory-db", + "rev": "7573f55ba337263f61167dbb0ea926cdc7c8eb5d", + "type": "github" + }, + "original": { + "owner": "rustsec", + "repo": "advisory-db", + "type": "github" + } + }, + "crane": { + "locked": { + "lastModified": 1750266157, + "narHash": "sha256-tL42YoNg9y30u7zAqtoGDNdTyXTi8EALDeCB13FtbQA=", + "owner": "ipetkov", + "repo": "crane", + "rev": "e37c943371b73ed87faf33f7583860f81f1d5a48", + "type": "github" + }, + "original": { + "owner": "ipetkov", + "repo": "crane", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nix-github-actions": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1737420293, + "narHash": "sha256-F1G5ifvqTpJq7fdkT34e/Jy9VCyzd5XfJ9TO8fHhJWE=", + "owner": "nix-community", + "repo": "nix-github-actions", + "rev": "f4158fa080ef4503c8f4c820967d946c2af31ec9", + "type": "github" + }, + "original": { + "owner": "nix-community", + "repo": "nix-github-actions", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1750506804, + "narHash": "sha256-VLFNc4egNjovYVxDGyBYTrvVCgDYgENp5bVi9fPTDYc=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "4206c4cb56751df534751b058295ea61357bbbaa", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "nixos-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "advisory-db": "advisory-db", + "crane": "crane", + "flake-utils": "flake-utils", + "nix-github-actions": "nix-github-actions", + "nixpkgs": "nixpkgs", + "rust-overlay": "rust-overlay" + } + }, + "rust-overlay": { + "inputs": { + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1750732748, + "narHash": "sha256-HR2b3RHsPeJm+Fb+1ui8nXibgniVj7hBNvUbXEyz0DU=", + "owner": "oxalica", + "repo": "rust-overlay", + "rev": "4b4494b2ba7e8a8041b2e28320b2ee02c115c75f", + "type": "github" + }, + "original": { + "owner": "oxalica", + "repo": "rust-overlay", + "type": "github" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..94fab68 --- /dev/null +++ b/flake.nix @@ -0,0 +1,160 @@ +{ + description = "A simple rust flake using rust-overlay and craneLib"; + + inputs = { + nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + crane.url = "github:ipetkov/crane"; + nix-github-actions = { + url = "github:nix-community/nix-github-actions"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + rust-overlay = { + url = "github:oxalica/rust-overlay"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + advisory-db = { + url = "github:rustsec/advisory-db"; + flake = false; + }; + }; + + outputs = { + self, + crane, + flake-utils, + nixpkgs, + rust-overlay, + advisory-db, + nix-github-actions, + ... + }: + flake-utils.lib.eachDefaultSystem ( + system: let + pkgs = import nixpkgs { + inherit system; + overlays = [ + rust-overlay.overlays.default + ]; + }; + inherit (pkgs) lib; + cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); + name = cargoToml.package.name; + + stableToolchain = pkgs.rust-bin.stable.latest.default; + stableToolchainWithLLvmTools = stableToolchain.override { + extensions = ["rust-src" "llvm-tools"]; + }; + stableToolchainWithRustAnalyzer = stableToolchain.override { + extensions = ["rust-src" "rust-analyzer"]; + }; + craneLib = (crane.mkLib pkgs).overrideToolchain stableToolchain; + craneLibLLvmTools = (crane.mkLib pkgs).overrideToolchain stableToolchainWithLLvmTools; + + src = let + filterBySuffix = path: exts: lib.any (ext: lib.hasSuffix ext path) exts; + sourceFilters = path: type: (craneLib.filterCargoSources path type) || filterBySuffix path [".c" ".h" ".hpp" ".cpp" ".cc"]; + in + lib.cleanSourceWith { + filter = sourceFilters; + src = ./.; + }; + commonArgs = + { + inherit src; + pname = name; + stdenv = p: p.clangStdenv; + doCheck = false; + # LIBCLANG_PATH = "${pkgs.llvmPackages.libclang.lib}/lib"; + nativeBuildInputs = with pkgs; [ + pkg-config + # cmake + # llvmPackages.libclang.lib + ]; + buildInputs = with pkgs; + [ + openssl + ] + ++ (lib.optionals pkgs.stdenv.isDarwin [ + libiconv + apple-sdk_13 + ]); + } + // (lib.optionalAttrs pkgs.stdenv.isLinux { + # BINDGEN_EXTRA_CLANG_ARGS = "-I${pkgs.llvmPackages.libclang.lib}/lib/clang/18/include"; + }); + cargoArtifacts = craneLib.buildPackage commonArgs; + in { + checks = + { + "${name}-clippy" = craneLib.cargoClippy (commonArgs + // { + inherit cargoArtifacts; + cargoClippyExtraArgs = "--all-targets -- --deny warnings"; + }); + "${name}-docs" = craneLib.cargoDoc (commonArgs // {inherit cargoArtifacts;}); + "${name}-fmt" = craneLib.cargoFmt {inherit src;}; + "${name}-toml-fmt" = craneLib.taploFmt { + src = pkgs.lib.sources.sourceFilesBySuffices src [".toml"]; + }; + # Audit dependencies + "${name}-audit" = craneLib.cargoAudit { + inherit src advisory-db; + }; + + # Audit licenses + "${name}-deny" = craneLib.cargoDeny { + inherit src; + }; + "${name}-nextest" = craneLib.cargoNextest (commonArgs + // { + inherit cargoArtifacts; + partitions = 1; + partitionType = "count"; + }); + } + // lib.optionalAttrs (!pkgs.stdenv.isDarwin) { + "${name}-llvm-cov" = craneLibLLvmTools.cargoLlvmCov (commonArgs // {inherit cargoArtifacts;}); + }; + + packages = let + pkg = craneLib.buildPackage (commonArgs + // {inherit cargoArtifacts;} + // { + nativeBuildInputs = with pkgs; [ + installShellFiles + ]; + postInstall = '' + installShellCompletion --cmd ${name} \ + --bash <($out/bin/${name} completions bash) \ + --fish <($out/bin/${name} completions fish) \ + --zsh <($out/bin/${name} completions zsh) + ''; + }); + in { + "${name}" = pkg; + default = pkg; + }; + + devShells = { + default = pkgs.mkShell.override {stdenv = pkgs.clangStdenv;} (commonArgs + // { + packages = with pkgs; + [ + stableToolchainWithRustAnalyzer + cargo-nextest + cargo-deny + ] + ++ (lib.optionals pkgs.stdenv.isDarwin [ + apple-sdk_13 + ]); + }); + }; + } + ) + // { + githubActions = nix-github-actions.lib.mkGithubMatrix { + checks = nixpkgs.lib.getAttrs ["x86_64-linux"] self.checks; + }; + }; +} diff --git a/sonarr.json b/sonarr.json new file mode 100644 index 0000000..1aa84c0 --- /dev/null +++ b/sonarr.json @@ -0,0 +1 @@ +{"openapi":"3.1.1","info":{"title":"Sonarr","description":"Sonarr API docs - The v3 API docs apply to both v3 and v4 versions of Sonarr. Some functionality may only be available in v4 of the Sonarr application.","license":{"name":"GPL-3.0","url":"https://github.com/Sonarr/Sonarr/blob/develop/LICENSE"},"version":"3.0.0"},"servers":[{"url":"{protocol}://{hostpath}","variables":{"protocol":{"default":"http","enum":["http","https"]},"hostpath":{"default":"localhost:8989"}}}],"paths":{"/api":{"get":{"tags":["ApiInfo"],"responses":{"200":{"description":"OK"}}}},"/login":{"post":{"tags":["Authentication"],"parameters":[{"name":"returnUrl","in":"query","schema":{"type":"string"}}],"requestBody":{"content":{"multipart/form-data":{"schema":{"type":"object","properties":{"username":{"type":"string"},"password":{"type":"string"},"rememberMe":{"type":"string"}}},"encoding":{"username":{"style":"form"},"password":{"style":"form"},"rememberMe":{"style":"form"}}}}},"responses":{"200":{"description":"OK"}}},"get":{"tags":["StaticResource"],"responses":{"200":{"description":"OK"}}}},"/logout":{"get":{"tags":["Authentication"],"responses":{"200":{"description":"OK"}}}},"/api/v3/autotagging":{"post":{"tags":["AutoTagging"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}}}}}},"get":{"tags":["AutoTagging"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/AutoTaggingResource"}}}}}}}},"/api/v3/autotagging/{id}":{"put":{"tags":["AutoTagging"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}}}}}},"delete":{"tags":["AutoTagging"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["AutoTagging"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AutoTaggingResource"}}}}}}},"/api/v3/autotagging/schema":{"get":{"tags":["AutoTagging"],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/backup":{"get":{"tags":["Backup"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BackupResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BackupResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/BackupResource"}}}}}}}},"/api/v3/system/backup/{id}":{"delete":{"tags":["Backup"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/backup/restore/{id}":{"post":{"tags":["Backup"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/backup/restore/upload":{"post":{"tags":["Backup"],"responses":{"200":{"description":"OK"}}}},"/api/v3/blocklist":{"get":{"tags":["Blocklist"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"seriesIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"protocols","in":"query","schema":{"type":"array","items":{"$ref":"#/components/schemas/DownloadProtocol"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlocklistResourcePagingResource"}}}}}}},"/api/v3/blocklist/{id}":{"delete":{"tags":["Blocklist"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/blocklist/bulk":{"delete":{"tags":["Blocklist"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BlocklistBulkResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/BlocklistBulkResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/BlocklistBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/calendar":{"get":{"tags":["Calendar"],"parameters":[{"name":"start","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"end","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"unmonitored","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisodeFile","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisodeImages","in":"query","schema":{"type":"boolean","default":false}},{"name":"tags","in":"query","schema":{"type":"string","default":""}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}}},"/api/v3/calendar/{id}":{"get":{"tags":["Calendar"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}},"/feed/v3/calendar/sonarr.ics":{"get":{"tags":["CalendarFeed"],"parameters":[{"name":"pastDays","in":"query","schema":{"type":"integer","format":"int32","default":7}},{"name":"futureDays","in":"query","schema":{"type":"integer","format":"int32","default":28}},{"name":"tags","in":"query","schema":{"type":"string","default":""}},{"name":"unmonitored","in":"query","schema":{"type":"boolean","default":false}},{"name":"premieresOnly","in":"query","schema":{"type":"boolean","default":false}},{"name":"asAllDay","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/command":{"post":{"tags":["Command"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResource"}}}}}},"get":{"tags":["Command"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CommandResource"}}}}}}}},"/api/v3/command/{id}":{"delete":{"tags":["Command"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["Command"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CommandResource"}}}}}}},"/api/v3/customfilter":{"get":{"tags":["CustomFilter"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CustomFilterResource"}}}}}}},"post":{"tags":["CustomFilter"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}}}}}}},"/api/v3/customfilter/{id}":{"put":{"tags":["CustomFilter"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}}}}}},"delete":{"tags":["CustomFilter"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["CustomFilter"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFilterResource"}}}}}}},"/api/v3/customformat":{"get":{"tags":["CustomFormat"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/CustomFormatResource"}}}}}}},"post":{"tags":["CustomFormat"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}}}}},"/api/v3/customformat/{id}":{"put":{"tags":["CustomFormat"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}}}},"delete":{"tags":["CustomFormat"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["CustomFormat"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}}}}},"/api/v3/customformat/bulk":{"put":{"tags":["CustomFormat"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatBulkResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatResource"}}}}}},"delete":{"tags":["CustomFormat"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CustomFormatBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/customformat/schema":{"get":{"tags":["CustomFormat"],"responses":{"200":{"description":"OK"}}}},"/api/v3/wanted/cutoff":{"get":{"tags":["Cutoff"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisodeFile","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeImages","in":"query","schema":{"type":"boolean","default":false}},{"name":"monitored","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResourcePagingResource"}}}}}}},"/api/v3/wanted/cutoff/{id}":{"get":{"tags":["Cutoff"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}},"/api/v3/delayprofile":{"post":{"tags":["DelayProfile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}}}}}},"get":{"tags":["DelayProfile"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DelayProfileResource"}}}}}}}},"/api/v3/delayprofile/{id}":{"delete":{"tags":["DelayProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"put":{"tags":["DelayProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}}}}}},"get":{"tags":["DelayProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DelayProfileResource"}}}}}}},"/api/v3/delayprofile/reorder/{id}":{"put":{"tags":["DelayProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"after","in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DelayProfileResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DelayProfileResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DelayProfileResource"}}}}}}}},"/api/v3/diskspace":{"get":{"tags":["DiskSpace"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DiskSpaceResource"}}}}}}}},"/api/v3/downloadclient":{"get":{"tags":["DownloadClient"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}}},"post":{"tags":["DownloadClient"],"parameters":[{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}}},"/api/v3/downloadclient/{id}":{"put":{"tags":["DownloadClient"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}},"delete":{"tags":["DownloadClient"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["DownloadClient"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}}},"/api/v3/downloadclient/bulk":{"put":{"tags":["DownloadClient"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientBulkResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}},"delete":{"tags":["DownloadClient"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/downloadclient/schema":{"get":{"tags":["DownloadClient"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/DownloadClientResource"}}}}}}}},"/api/v3/downloadclient/test":{"post":{"tags":["DownloadClient"],"parameters":[{"name":"forceTest","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/downloadclient/testall":{"post":{"tags":["DownloadClient"],"responses":{"200":{"description":"OK"}}}},"/api/v3/downloadclient/action/{name}":{"post":{"tags":["DownloadClient"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/config/downloadclient":{"get":{"tags":["DownloadClientConfig"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}}}}}}},"/api/v3/config/downloadclient/{id}":{"put":{"tags":["DownloadClientConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}}}}}},"get":{"tags":["DownloadClientConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DownloadClientConfigResource"}}}}}}},"/api/v3/episode":{"get":{"tags":["Episode"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"seasonNumber","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"episodeIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"episodeFileId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisodeFile","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeImages","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}}},"/api/v3/episode/{id}":{"put":{"tags":["Episode"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}}}},"get":{"tags":["Episode"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}},"/api/v3/episode/monitor":{"put":{"tags":["Episode"],"parameters":[{"name":"includeImages","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodesMonitoredResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/episodefile":{"get":{"tags":["EpisodeFile"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"episodeFileIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EpisodeFileResource"}}}}}}}},"/api/v3/episodefile/{id}":{"put":{"tags":["EpisodeFile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/EpisodeFileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileResource"}}}}}},"delete":{"tags":["EpisodeFile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["EpisodeFile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileResource"}}}}}}},"/api/v3/episodefile/editor":{"put":{"tags":["EpisodeFile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileListResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/episodefile/bulk":{"delete":{"tags":["EpisodeFile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeFileListResource"}}}},"responses":{"200":{"description":"OK"}}},"put":{"tags":["EpisodeFile"],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/EpisodeFileResource"}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/filesystem":{"get":{"tags":["FileSystem"],"parameters":[{"name":"path","in":"query","schema":{"type":"string"}},{"name":"includeFiles","in":"query","schema":{"type":"boolean","default":false}},{"name":"allowFoldersWithoutTrailingSlashes","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/filesystem/type":{"get":{"tags":["FileSystem"],"parameters":[{"name":"path","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/filesystem/mediafiles":{"get":{"tags":["FileSystem"],"parameters":[{"name":"path","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/health":{"get":{"tags":["Health"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HealthResource"}}}}}}}},"/api/v3/history":{"get":{"tags":["History"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean"}},{"name":"includeEpisode","in":"query","schema":{"type":"boolean"}},{"name":"eventType","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"episodeId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"downloadId","in":"query","schema":{"type":"string"}},{"name":"seriesIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"languages","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"quality","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HistoryResourcePagingResource"}}}}}}},"/api/v3/history/since":{"get":{"tags":["History"],"parameters":[{"name":"date","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"eventType","in":"query","schema":{"$ref":"#/components/schemas/EpisodeHistoryEventType"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisode","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HistoryResource"}}}}}}}},"/api/v3/history/series":{"get":{"tags":["History"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"seasonNumber","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"eventType","in":"query","schema":{"$ref":"#/components/schemas/EpisodeHistoryEventType"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisode","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/HistoryResource"}}}}}}}},"/api/v3/history/failed/{id}":{"post":{"tags":["History"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/config/host":{"get":{"tags":["HostConfig"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}}}}}}},"/api/v3/config/host/{id}":{"put":{"tags":["HostConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}}}}}},"get":{"tags":["HostConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HostConfigResource"}}}}}}},"/api/v3/importlist":{"get":{"tags":["ImportList"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ImportListResource"}}}}}}},"post":{"tags":["ImportList"],"parameters":[{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}}}}},"/api/v3/importlist/{id}":{"put":{"tags":["ImportList"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}}}},"delete":{"tags":["ImportList"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["ImportList"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}}}}},"/api/v3/importlist/bulk":{"put":{"tags":["ImportList"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListBulkResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}}}},"delete":{"tags":["ImportList"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/importlist/schema":{"get":{"tags":["ImportList"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ImportListResource"}}}}}}}},"/api/v3/importlist/test":{"post":{"tags":["ImportList"],"parameters":[{"name":"forceTest","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/importlist/testall":{"post":{"tags":["ImportList"],"responses":{"200":{"description":"OK"}}}},"/api/v3/importlist/action/{name}":{"post":{"tags":["ImportList"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/config/importlist":{"get":{"tags":["ImportListConfig"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}}}}}}},"/api/v3/config/importlist/{id}":{"put":{"tags":["ImportListConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}}}}}},"get":{"tags":["ImportListConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListConfigResource"}}}}}}},"/api/v3/importlistexclusion":{"get":{"tags":["ImportListExclusion"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}}}},"deprecated":true},"post":{"tags":["ImportListExclusion"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}}}}},"/api/v3/importlistexclusion/paged":{"get":{"tags":["ImportListExclusion"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResourcePagingResource"}}}}}}},"/api/v3/importlistexclusion/{id}":{"put":{"tags":["ImportListExclusion"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}}}},"delete":{"tags":["ImportListExclusion"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["ImportListExclusion"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionResource"}}}}}}},"/api/v3/importlistexclusion/bulk":{"delete":{"tags":["ImportListExclusion"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionBulkResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionBulkResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/ImportListExclusionBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/indexer":{"get":{"tags":["Indexer"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndexerResource"}}}}}}},"post":{"tags":["Indexer"],"parameters":[{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}}}}},"/api/v3/indexer/{id}":{"put":{"tags":["Indexer"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}}}},"delete":{"tags":["Indexer"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["Indexer"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}}}}},"/api/v3/indexer/bulk":{"put":{"tags":["Indexer"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerBulkResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}}}},"delete":{"tags":["Indexer"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/indexer/schema":{"get":{"tags":["Indexer"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndexerResource"}}}}}}}},"/api/v3/indexer/test":{"post":{"tags":["Indexer"],"parameters":[{"name":"forceTest","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/indexer/testall":{"post":{"tags":["Indexer"],"responses":{"200":{"description":"OK"}}}},"/api/v3/indexer/action/{name}":{"post":{"tags":["Indexer"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/config/indexer":{"get":{"tags":["IndexerConfig"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}}}}}}},"/api/v3/config/indexer/{id}":{"put":{"tags":["IndexerConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}}}}}},"get":{"tags":["IndexerConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/IndexerConfigResource"}}}}}}},"/api/v3/indexerflag":{"get":{"tags":["IndexerFlag"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndexerFlagResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndexerFlagResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/IndexerFlagResource"}}}}}}}},"/api/v3/language":{"get":{"tags":["Language"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LanguageResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LanguageResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LanguageResource"}}}}}}}},"/api/v3/language/{id}":{"get":{"tags":["Language"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageResource"}}}}}}},"/api/v3/languageprofile":{"post":{"tags":["LanguageProfile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}}},"deprecated":true},"get":{"tags":["LanguageProfile"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LanguageProfileResource"}}}}}},"deprecated":true}},"/api/v3/languageprofile/{id}":{"delete":{"tags":["LanguageProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}},"deprecated":true},"put":{"tags":["LanguageProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}}},"deprecated":true},"get":{"tags":["LanguageProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}}}}},"/api/v3/languageprofile/schema":{"get":{"tags":["LanguageProfileSchema"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LanguageProfileResource"}}}}},"deprecated":true}},"/api/v3/localization":{"get":{"tags":["Localization"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalizationResource"}}}}}}},"/api/v3/localization/language":{"get":{"tags":["Localization"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalizationLanguageResource"}}}}}}},"/api/v3/localization/{id}":{"get":{"tags":["Localization"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LocalizationResource"}}}}}}},"/api/v3/log":{"get":{"tags":["Log"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"level","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LogResourcePagingResource"}}}}}}},"/api/v3/log/file":{"get":{"tags":["LogFile"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LogFileResource"}}}}}}}},"/api/v3/log/file/{filename}":{"get":{"tags":["LogFile"],"parameters":[{"name":"filename","in":"path","required":true,"schema":{"pattern":"[-.a-zA-Z0-9]+?\\.txt","type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/manualimport":{"get":{"tags":["ManualImport"],"parameters":[{"name":"folder","in":"query","schema":{"type":"string"}},{"name":"downloadId","in":"query","schema":{"type":"string"}},{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"seasonNumber","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"filterExistingFiles","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ManualImportResource"}}}}}}},"post":{"tags":["ManualImport"],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ManualImportReprocessResource"}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/mediacover/{seriesId}/{filename}":{"get":{"tags":["MediaCover"],"parameters":[{"name":"seriesId","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"filename","in":"path","required":true,"schema":{"pattern":"(.+)\\.(jpg|png|gif)","type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/config/mediamanagement":{"get":{"tags":["MediaManagementConfig"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}}}}}}},"/api/v3/config/mediamanagement/{id}":{"put":{"tags":["MediaManagementConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}}}}}},"get":{"tags":["MediaManagementConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MediaManagementConfigResource"}}}}}}},"/api/v3/metadata":{"get":{"tags":["Metadata"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MetadataResource"}}}}}}},"post":{"tags":["Metadata"],"parameters":[{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}}}}},"/api/v3/metadata/{id}":{"put":{"tags":["Metadata"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}}}},"delete":{"tags":["Metadata"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["Metadata"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}}}}},"/api/v3/metadata/schema":{"get":{"tags":["Metadata"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/MetadataResource"}}}}}}}},"/api/v3/metadata/test":{"post":{"tags":["Metadata"],"parameters":[{"name":"forceTest","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/metadata/testall":{"post":{"tags":["Metadata"],"responses":{"200":{"description":"OK"}}}},"/api/v3/metadata/action/{name}":{"post":{"tags":["Metadata"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MetadataResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/wanted/missing":{"get":{"tags":["Missing"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeImages","in":"query","schema":{"type":"boolean","default":false}},{"name":"monitored","in":"query","schema":{"type":"boolean","default":true}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResourcePagingResource"}}}}}}},"/api/v3/wanted/missing/{id}":{"get":{"tags":["Missing"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EpisodeResource"}}}}}}},"/api/v3/config/naming":{"get":{"tags":["NamingConfig"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}}}}}}},"/api/v3/config/naming/{id}":{"put":{"tags":["NamingConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}}}}}},"get":{"tags":["NamingConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NamingConfigResource"}}}}}}},"/api/v3/config/naming/examples":{"get":{"tags":["NamingConfig"],"parameters":[{"name":"renameEpisodes","in":"query","schema":{"type":"boolean"}},{"name":"replaceIllegalCharacters","in":"query","schema":{"type":"boolean"}},{"name":"colonReplacementFormat","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"customColonReplacementFormat","in":"query","schema":{"type":"string"}},{"name":"multiEpisodeStyle","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"standardEpisodeFormat","in":"query","schema":{"type":"string"}},{"name":"dailyEpisodeFormat","in":"query","schema":{"type":"string"}},{"name":"animeEpisodeFormat","in":"query","schema":{"type":"string"}},{"name":"seriesFolderFormat","in":"query","schema":{"type":"string"}},{"name":"seasonFolderFormat","in":"query","schema":{"type":"string"}},{"name":"specialsFolderFormat","in":"query","schema":{"type":"string"}},{"name":"id","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"resourceName","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/notification":{"get":{"tags":["Notification"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NotificationResource"}}}}}}},"post":{"tags":["Notification"],"parameters":[{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}}}}},"/api/v3/notification/{id}":{"put":{"tags":["Notification"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"forceSave","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}}}},"delete":{"tags":["Notification"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["Notification"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}}}}},"/api/v3/notification/schema":{"get":{"tags":["Notification"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/NotificationResource"}}}}}}}},"/api/v3/notification/test":{"post":{"tags":["Notification"],"parameters":[{"name":"forceTest","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/notification/testall":{"post":{"tags":["Notification"],"responses":{"200":{"description":"OK"}}}},"/api/v3/notification/action/{name}":{"post":{"tags":["Notification"],"parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/parse":{"get":{"tags":["Parse"],"parameters":[{"name":"title","in":"query","schema":{"type":"string"}},{"name":"path","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ParseResource"}}}}}}},"/ping":{"get":{"tags":["Ping"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PingResource"}}}}}},"head":{"tags":["Ping"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PingResource"}}}}}}},"/api/v3/qualitydefinition/{id}":{"put":{"tags":["QualityDefinition"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}}}}}},"get":{"tags":["QualityDefinition"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionResource"}}}}}}},"/api/v3/qualitydefinition":{"get":{"tags":["QualityDefinition"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}}}}}}},"/api/v3/qualitydefinition/update":{"put":{"tags":["QualityDefinition"],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}},"application/*+json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityDefinitionResource"}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/qualitydefinition/limits":{"get":{"tags":["QualityDefinition"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QualityDefinitionLimitsResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionLimitsResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityDefinitionLimitsResource"}}}}}}},"/api/v3/qualityprofile":{"post":{"tags":["QualityProfile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}}}},"get":{"tags":["QualityProfile"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QualityProfileResource"}}}}}}}},"/api/v3/qualityprofile/{id}":{"delete":{"tags":["QualityProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"put":{"tags":["QualityProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}}}},"get":{"tags":["QualityProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}}}}},"/api/v3/qualityprofile/schema":{"get":{"tags":["QualityProfileSchema"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QualityProfileResource"}}}}}}},"/api/v3/queue/{id}":{"delete":{"tags":["Queue"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"removeFromClient","in":"query","schema":{"type":"boolean","default":true}},{"name":"blocklist","in":"query","schema":{"type":"boolean","default":false}},{"name":"skipRedownload","in":"query","schema":{"type":"boolean","default":false}},{"name":"changeCategory","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/queue/bulk":{"delete":{"tags":["Queue"],"parameters":[{"name":"removeFromClient","in":"query","schema":{"type":"boolean","default":true}},{"name":"blocklist","in":"query","schema":{"type":"boolean","default":false}},{"name":"skipRedownload","in":"query","schema":{"type":"boolean","default":false}},{"name":"changeCategory","in":"query","schema":{"type":"boolean","default":false}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueBulkResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/QueueBulkResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/QueueBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/queue":{"get":{"tags":["Queue"],"parameters":[{"name":"page","in":"query","schema":{"type":"integer","format":"int32","default":1}},{"name":"pageSize","in":"query","schema":{"type":"integer","format":"int32","default":10}},{"name":"sortKey","in":"query","schema":{"type":"string"}},{"name":"sortDirection","in":"query","schema":{"$ref":"#/components/schemas/SortDirection"}},{"name":"includeUnknownSeriesItems","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisode","in":"query","schema":{"type":"boolean","default":false}},{"name":"seriesIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"protocol","in":"query","schema":{"$ref":"#/components/schemas/DownloadProtocol"}},{"name":"languages","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"quality","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"status","in":"query","schema":{"type":"array","items":{"$ref":"#/components/schemas/QueueStatus"}}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueResourcePagingResource"}}}}}}},"/api/v3/queue/grab/{id}":{"post":{"tags":["QueueAction"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/queue/grab/bulk":{"post":{"tags":["QueueAction"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueBulkResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/queue/details":{"get":{"tags":["QueueDetails"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"episodeIds","in":"query","schema":{"type":"array","items":{"type":"integer","format":"int32"}}},{"name":"includeSeries","in":"query","schema":{"type":"boolean","default":false}},{"name":"includeEpisode","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/QueueResource"}}}}}}}},"/api/v3/queue/status":{"get":{"tags":["QueueStatus"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/QueueStatusResource"}}}}}}},"/api/v3/release":{"post":{"tags":["Release"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResource"}}}},"responses":{"200":{"description":"OK"}}},"get":{"tags":["Release"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"episodeId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"seasonNumber","in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseResource"}}}}}}}},"/api/v3/releaseprofile":{"post":{"tags":["ReleaseProfile"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}}}},"get":{"tags":["ReleaseProfile"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseProfileResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseProfileResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}}}}}},"/api/v3/releaseprofile/{id}":{"delete":{"tags":["ReleaseProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"put":{"tags":["ReleaseProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}}}},"get":{"tags":["ReleaseProfile"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseProfileResource"}}}}}}},"/api/v3/release/push":{"post":{"tags":["ReleasePush"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ReleaseResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/ReleaseResource"}}}}}}}},"/api/v3/remotepathmapping":{"post":{"tags":["RemotePathMapping"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}}}},"get":{"tags":["RemotePathMapping"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}}}}}},"/api/v3/remotepathmapping/{id}":{"delete":{"tags":["RemotePathMapping"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"put":{"tags":["RemotePathMapping"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}}}},"get":{"tags":["RemotePathMapping"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RemotePathMappingResource"}}}}}}},"/api/v3/rename":{"get":{"tags":["RenameEpisode"],"parameters":[{"name":"seriesId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"seasonNumber","in":"query","schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RenameEpisodeResource"}}}}}}}},"/api/v3/rootfolder":{"post":{"tags":["RootFolder"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RootFolderResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/RootFolderResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/RootFolderResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/RootFolderResource"}}}}}},"get":{"tags":["RootFolder"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/RootFolderResource"}}}}}}}},"/api/v3/rootfolder/{id}":{"delete":{"tags":["RootFolder"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["RootFolder"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RootFolderResource"}}}}}}},"/api/v3/seasonpass":{"post":{"tags":["SeasonPass"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeasonPassResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/series":{"get":{"tags":["Series"],"parameters":[{"name":"tvdbId","in":"query","schema":{"type":"integer","format":"int32"}},{"name":"includeSeasonImages","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}}}}}},"post":{"tags":["Series"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResource"}}}}}}},"/api/v3/series/{id}":{"get":{"tags":["Series"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"includeSeasonImages","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResource"}}}}}},"put":{"tags":["Series"],"parameters":[{"name":"moveFiles","in":"query","schema":{"type":"boolean","default":false}},{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResource"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesResource"}}}}}},"delete":{"tags":["Series"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}},{"name":"deleteFiles","in":"query","schema":{"type":"boolean","default":false}},{"name":"addImportListExclusion","in":"query","schema":{"type":"boolean","default":false}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/series/editor":{"put":{"tags":["SeriesEditor"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}}}},"responses":{"200":{"description":"OK"}}},"delete":{"tags":["SeriesEditor"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}},"application/*+json":{"schema":{"$ref":"#/components/schemas/SeriesEditorResource"}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/series/{id}/folder":{"get":{"tags":["SeriesFolder"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/series/import":{"post":{"tags":["SeriesImport"],"requestBody":{"content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}},"application/*+json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}}}},"responses":{"200":{"description":"OK"}}}},"/api/v3/series/lookup":{"get":{"tags":["SeriesLookup"],"parameters":[{"name":"term","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/SeriesResource"}}}}}}}},"/content/{path}":{"get":{"tags":["StaticResource"],"parameters":[{"name":"path","in":"path","required":true,"schema":{"pattern":"^(?!api/).*","type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/":{"get":{"tags":["StaticResource"],"parameters":[{"name":"path","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/{path}":{"get":{"tags":["StaticResource"],"parameters":[{"name":"path","in":"path","required":true,"schema":{"pattern":"^(?!(api|feed)/).*","type":"string"}}],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/status":{"get":{"tags":["System"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SystemResource"}}}}}}},"/api/v3/system/routes":{"get":{"tags":["System"],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/routes/duplicate":{"get":{"tags":["System"],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/shutdown":{"post":{"tags":["System"],"responses":{"200":{"description":"OK"}}}},"/api/v3/system/restart":{"post":{"tags":["System"],"responses":{"200":{"description":"OK"}}}},"/api/v3/tag":{"get":{"tags":["Tag"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TagResource"}}}}}}},"post":{"tags":["Tag"],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/TagResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/TagResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/TagResource"}}}}}}},"/api/v3/tag/{id}":{"put":{"tags":["Tag"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/TagResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/TagResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/TagResource"}}}}}},"delete":{"tags":["Tag"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK"}}},"get":{"tags":["Tag"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagResource"}}}}}}},"/api/v3/tag/detail":{"get":{"tags":["TagDetails"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TagDetailsResource"}}}}}}}},"/api/v3/tag/detail/{id}":{"get":{"tags":["TagDetails"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TagDetailsResource"}}}}}}},"/api/v3/system/task":{"get":{"tags":["Task"],"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskResource"}}},"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskResource"}}},"text/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/TaskResource"}}}}}}}},"/api/v3/system/task/{id}":{"get":{"tags":["Task"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskResource"}}}}}}},"/api/v3/config/ui/{id}":{"put":{"tags":["UiConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}}}},"responses":{"200":{"description":"OK","content":{"text/plain":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}},"application/json":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}},"text/json":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}}}}}},"get":{"tags":["UiConfig"],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"integer","format":"int32"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}}}}}}},"/api/v3/config/ui":{"get":{"tags":["UiConfig"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UiConfigResource"}}}}}}},"/api/v3/update":{"get":{"tags":["Update"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/UpdateResource"}}}}}}}},"/api/v3/log/file/update":{"get":{"tags":["UpdateLogFile"],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"array","items":{"$ref":"#/components/schemas/LogFileResource"}}}}}}}},"/api/v3/log/file/update/{filename}":{"get":{"tags":["UpdateLogFile"],"parameters":[{"name":"filename","in":"path","required":true,"schema":{"pattern":"[-.a-zA-Z0-9]+?\\.txt","type":"string"}}],"responses":{"200":{"description":"OK"}}}}},"components":{"schemas":{"AddSeriesOptions":{"type":"object","properties":{"ignoreEpisodesWithFiles":{"type":"boolean"},"ignoreEpisodesWithoutFiles":{"type":"boolean"},"monitor":{"$ref":"#/components/schemas/MonitorTypes"},"searchForMissingEpisodes":{"type":"boolean"},"searchForCutoffUnmetEpisodes":{"type":"boolean"}},"additionalProperties":false},"AlternateTitleResource":{"type":"object","properties":{"title":{"type":["string","null"]},"seasonNumber":{"type":["integer","null"],"format":"int32"},"sceneSeasonNumber":{"type":["integer","null"],"format":"int32"},"sceneOrigin":{"type":["string","null"]},"comment":{"type":["string","null"]}},"additionalProperties":false},"ApplyTags":{"enum":["add","remove","replace"],"type":"string"},"AuthenticationRequiredType":{"enum":["enabled","disabledForLocalAddresses"],"type":"string"},"AuthenticationType":{"enum":["none","basic","forms","external"],"type":"string"},"AutoTaggingResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"removeTagsAutomatically":{"type":"boolean"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"specifications":{"type":["array","null"],"items":{"$ref":"#/components/schemas/AutoTaggingSpecificationSchema"}}},"additionalProperties":false},"AutoTaggingSpecificationSchema":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"implementation":{"type":["string","null"]},"implementationName":{"type":["string","null"]},"negate":{"type":"boolean"},"required":{"type":"boolean"},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}}},"additionalProperties":false},"BackupResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"path":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/BackupType"},"size":{"type":"integer","format":"int64"},"time":{"type":"string","format":"date-time"}},"additionalProperties":false},"BackupType":{"enum":["scheduled","manual","update"],"type":"string"},"BlocklistBulkResource":{"type":"object","properties":{"ids":{"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"BlocklistResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seriesId":{"type":"integer","format":"int32"},"episodeIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"sourceTitle":{"type":["string","null"]},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"date":{"type":"string","format":"date-time"},"protocol":{"$ref":"#/components/schemas/DownloadProtocol"},"indexer":{"type":["string","null"]},"message":{"type":["string","null"]},"series":{"$ref":"#/components/schemas/SeriesResource"}},"additionalProperties":false},"BlocklistResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/BlocklistResource"}}},"additionalProperties":false},"CertificateValidationType":{"enum":["enabled","disabledForLocalAddresses","disabled"],"type":"string"},"Command":{"type":"object","properties":{"sendUpdatesToClient":{"type":"boolean"},"updateScheduledTask":{"type":"boolean","readOnly":true},"completionMessage":{"type":["string","null"],"readOnly":true},"requiresDiskAccess":{"type":"boolean","readOnly":true},"isExclusive":{"type":"boolean","readOnly":true},"isLongRunning":{"type":"boolean","readOnly":true},"name":{"type":["string","null"],"readOnly":true},"lastExecutionTime":{"type":["string","null"],"format":"date-time"},"lastStartTime":{"type":["string","null"],"format":"date-time"},"trigger":{"$ref":"#/components/schemas/CommandTrigger"},"suppressMessages":{"type":"boolean"},"clientUserAgent":{"type":["string","null"]}},"additionalProperties":false},"CommandPriority":{"enum":["normal","high","low"],"type":"string"},"CommandResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"commandName":{"type":["string","null"]},"message":{"type":["string","null"]},"body":{"$ref":"#/components/schemas/Command"},"priority":{"$ref":"#/components/schemas/CommandPriority"},"status":{"$ref":"#/components/schemas/CommandStatus"},"result":{"$ref":"#/components/schemas/CommandResult"},"queued":{"type":"string","format":"date-time"},"started":{"type":["string","null"],"format":"date-time"},"ended":{"type":["string","null"],"format":"date-time"},"duration":{"type":["string","null"],"format":"date-span"},"exception":{"type":["string","null"]},"trigger":{"$ref":"#/components/schemas/CommandTrigger"},"clientUserAgent":{"type":["string","null"]},"stateChangeTime":{"type":["string","null"],"format":"date-time"},"sendUpdatesToClient":{"type":"boolean"},"updateScheduledTask":{"type":"boolean"},"lastExecutionTime":{"type":["string","null"],"format":"date-time"}},"additionalProperties":false},"CommandResult":{"enum":["unknown","successful","unsuccessful"],"type":"string"},"CommandStatus":{"enum":["queued","started","completed","failed","aborted","cancelled","orphaned"],"type":"string"},"CommandTrigger":{"enum":["unspecified","manual","scheduled"],"type":"string"},"CustomFilterResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"type":{"type":["string","null"]},"label":{"type":["string","null"]},"filters":{"type":["array","null"],"items":{"type":"object","additionalProperties":{}}}},"additionalProperties":false},"CustomFormatBulkResource":{"type":"object","properties":{"ids":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"includeCustomFormatWhenRenaming":{"type":["boolean","null"]}},"additionalProperties":false},"CustomFormatResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"includeCustomFormatWhenRenaming":{"type":["boolean","null"]},"specifications":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatSpecificationSchema"}}},"additionalProperties":false},"CustomFormatSpecificationSchema":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"implementation":{"type":["string","null"]},"implementationName":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"negate":{"type":"boolean"},"required":{"type":"boolean"},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatSpecificationSchema"}}},"additionalProperties":false},"DatabaseType":{"enum":["sqLite","postgreSQL"],"type":"string"},"DelayProfileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"enableUsenet":{"type":"boolean"},"enableTorrent":{"type":"boolean"},"preferredProtocol":{"$ref":"#/components/schemas/DownloadProtocol"},"usenetDelay":{"type":"integer","format":"int32"},"torrentDelay":{"type":"integer","format":"int32"},"bypassIfHighestQuality":{"type":"boolean"},"bypassIfAboveCustomFormatScore":{"type":"boolean"},"minimumCustomFormatScore":{"type":"integer","format":"int32"},"order":{"type":"integer","format":"int32"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"DiskSpaceResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"path":{"type":["string","null"]},"label":{"type":["string","null"]},"freeSpace":{"type":"integer","format":"int64"},"totalSpace":{"type":"integer","format":"int64"}},"additionalProperties":false},"DownloadClientBulkResource":{"type":"object","properties":{"ids":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"tags":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"applyTags":{"$ref":"#/components/schemas/ApplyTags"},"enable":{"type":["boolean","null"]},"priority":{"type":["integer","null"],"format":"int32"},"removeCompletedDownloads":{"type":["boolean","null"]},"removeFailedDownloads":{"type":["boolean","null"]}},"additionalProperties":false},"DownloadClientConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"downloadClientWorkingFolders":{"type":["string","null"]},"enableCompletedDownloadHandling":{"type":"boolean"},"autoRedownloadFailed":{"type":"boolean"},"autoRedownloadFailedFromInteractiveSearch":{"type":"boolean"}},"additionalProperties":false},"DownloadClientResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"implementationName":{"type":["string","null"]},"implementation":{"type":["string","null"]},"configContract":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/ProviderMessage"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/DownloadClientResource"}},"enable":{"type":"boolean"},"protocol":{"$ref":"#/components/schemas/DownloadProtocol"},"priority":{"type":"integer","format":"int32"},"removeCompletedDownloads":{"type":"boolean"},"removeFailedDownloads":{"type":"boolean"}},"additionalProperties":false},"DownloadProtocol":{"enum":["unknown","usenet","torrent"],"type":"string"},"EpisodeFileListResource":{"type":"object","properties":{"episodeFileIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"sceneName":{"type":["string","null"]},"releaseGroup":{"type":["string","null"]}},"additionalProperties":false},"EpisodeFileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seriesId":{"type":"integer","format":"int32"},"seasonNumber":{"type":"integer","format":"int32"},"relativePath":{"type":["string","null"]},"path":{"type":["string","null"]},"size":{"type":"integer","format":"int64"},"dateAdded":{"type":"string","format":"date-time"},"sceneName":{"type":["string","null"]},"releaseGroup":{"type":["string","null"]},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"indexerFlags":{"type":["integer","null"],"format":"int32"},"releaseType":{"$ref":"#/components/schemas/ReleaseType"},"mediaInfo":{"$ref":"#/components/schemas/MediaInfoResource"},"qualityCutoffNotMet":{"type":"boolean"}},"additionalProperties":false},"EpisodeHistoryEventType":{"enum":["unknown","grabbed","seriesFolderImported","downloadFolderImported","downloadFailed","episodeFileDeleted","episodeFileRenamed","downloadIgnored"],"type":"string"},"EpisodeResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seriesId":{"type":"integer","format":"int32"},"tvdbId":{"type":"integer","format":"int32"},"episodeFileId":{"type":"integer","format":"int32"},"seasonNumber":{"type":"integer","format":"int32"},"episodeNumber":{"type":"integer","format":"int32"},"title":{"type":["string","null"]},"airDate":{"type":["string","null"]},"airDateUtc":{"type":["string","null"],"format":"date-time"},"lastSearchTime":{"type":["string","null"],"format":"date-time"},"runtime":{"type":"integer","format":"int32"},"finaleType":{"type":["string","null"]},"overview":{"type":["string","null"]},"episodeFile":{"$ref":"#/components/schemas/EpisodeFileResource"},"hasFile":{"type":"boolean"},"monitored":{"type":"boolean"},"absoluteEpisodeNumber":{"type":["integer","null"],"format":"int32"},"sceneAbsoluteEpisodeNumber":{"type":["integer","null"],"format":"int32"},"sceneEpisodeNumber":{"type":["integer","null"],"format":"int32"},"sceneSeasonNumber":{"type":["integer","null"],"format":"int32"},"unverifiedSceneNumbering":{"type":"boolean"},"endTime":{"type":["string","null"],"format":"date-time"},"grabDate":{"type":["string","null"],"format":"date-time"},"series":{"$ref":"#/components/schemas/SeriesResource"},"images":{"type":["array","null"],"items":{"$ref":"#/components/schemas/MediaCover"}}},"additionalProperties":false},"EpisodeResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EpisodeResource"}}},"additionalProperties":false},"EpisodeTitleRequiredType":{"enum":["always","bulkSeasonReleases","never"],"type":"string"},"EpisodesMonitoredResource":{"type":"object","properties":{"episodeIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"monitored":{"type":"boolean"}},"additionalProperties":false},"Field":{"type":"object","properties":{"order":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"label":{"type":["string","null"]},"unit":{"type":["string","null"]},"helpText":{"type":["string","null"]},"helpTextWarning":{"type":["string","null"]},"helpLink":{"type":["string","null"]},"value":{"nullable":true},"type":{"type":["string","null"]},"advanced":{"type":"boolean"},"selectOptions":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SelectOption"}},"selectOptionsProviderAction":{"type":["string","null"]},"section":{"type":["string","null"]},"hidden":{"type":["string","null"]},"privacy":{"$ref":"#/components/schemas/PrivacyLevel"},"placeholder":{"type":["string","null"]},"isFloat":{"type":"boolean"}},"additionalProperties":false},"FileDateType":{"enum":["none","localAirDate","utcAirDate"],"type":"string"},"HealthCheckResult":{"enum":["ok","notice","warning","error"],"type":"string"},"HealthResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"source":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/HealthCheckResult"},"message":{"type":["string","null"]},"wikiUrl":{"$ref":"#/components/schemas/HttpUri"}},"additionalProperties":false},"HistoryResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"episodeId":{"type":"integer","format":"int32"},"seriesId":{"type":"integer","format":"int32"},"sourceTitle":{"type":["string","null"]},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"qualityCutoffNotMet":{"type":"boolean"},"date":{"type":"string","format":"date-time"},"downloadId":{"type":["string","null"]},"eventType":{"$ref":"#/components/schemas/EpisodeHistoryEventType"},"data":{"type":["object","null"],"additionalProperties":{"type":["string","null"]}},"episode":{"$ref":"#/components/schemas/EpisodeResource"},"series":{"$ref":"#/components/schemas/SeriesResource"}},"additionalProperties":false},"HistoryResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/HistoryResource"}}},"additionalProperties":false},"HostConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"bindAddress":{"type":["string","null"]},"port":{"type":"integer","format":"int32"},"sslPort":{"type":"integer","format":"int32"},"enableSsl":{"type":"boolean"},"launchBrowser":{"type":"boolean"},"authenticationMethod":{"$ref":"#/components/schemas/AuthenticationType"},"authenticationRequired":{"$ref":"#/components/schemas/AuthenticationRequiredType"},"analyticsEnabled":{"type":"boolean"},"username":{"type":["string","null"]},"password":{"type":["string","null"]},"passwordConfirmation":{"type":["string","null"]},"logLevel":{"type":["string","null"]},"logSizeLimit":{"type":"integer","format":"int32"},"consoleLogLevel":{"type":["string","null"]},"branch":{"type":["string","null"]},"apiKey":{"type":["string","null"]},"sslCertPath":{"type":["string","null"]},"sslCertPassword":{"type":["string","null"]},"urlBase":{"type":["string","null"]},"instanceName":{"type":["string","null"]},"applicationUrl":{"type":["string","null"]},"updateAutomatically":{"type":"boolean"},"updateMechanism":{"$ref":"#/components/schemas/UpdateMechanism"},"updateScriptPath":{"type":["string","null"]},"proxyEnabled":{"type":"boolean"},"proxyType":{"$ref":"#/components/schemas/ProxyType"},"proxyHostname":{"type":["string","null"]},"proxyPort":{"type":"integer","format":"int32"},"proxyUsername":{"type":["string","null"]},"proxyPassword":{"type":["string","null"]},"proxyBypassFilter":{"type":["string","null"]},"proxyBypassLocalAddresses":{"type":"boolean"},"certificateValidation":{"$ref":"#/components/schemas/CertificateValidationType"},"backupFolder":{"type":["string","null"]},"backupInterval":{"type":"integer","format":"int32"},"backupRetention":{"type":"integer","format":"int32"},"trustCgnatIpAddresses":{"type":"boolean"}},"additionalProperties":false},"HttpUri":{"type":"object","properties":{"fullUri":{"type":["string","null"],"readOnly":true},"scheme":{"type":["string","null"],"readOnly":true},"host":{"type":["string","null"],"readOnly":true},"port":{"type":["integer","null"],"format":"int32","readOnly":true},"path":{"type":["string","null"],"readOnly":true},"query":{"type":["string","null"],"readOnly":true},"fragment":{"type":["string","null"],"readOnly":true}},"additionalProperties":false},"ImportListBulkResource":{"type":"object","properties":{"ids":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"tags":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"applyTags":{"$ref":"#/components/schemas/ApplyTags"},"enableAutomaticAdd":{"type":["boolean","null"]},"rootFolderPath":{"type":["string","null"]},"qualityProfileId":{"type":["integer","null"],"format":"int32"}},"additionalProperties":false},"ImportListConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"listSyncLevel":{"$ref":"#/components/schemas/ListSyncLevelType"},"listSyncTag":{"type":"integer","format":"int32"}},"additionalProperties":false},"ImportListExclusionBulkResource":{"type":"object","properties":{"ids":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"ImportListExclusionResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"tvdbId":{"type":"integer","format":"int32"},"title":{"type":["string","null"]}},"additionalProperties":false},"ImportListExclusionResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ImportListExclusionResource"}}},"additionalProperties":false},"ImportListResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"implementationName":{"type":["string","null"]},"implementation":{"type":["string","null"]},"configContract":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/ProviderMessage"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ImportListResource"}},"enableAutomaticAdd":{"type":"boolean"},"searchForMissingEpisodes":{"type":"boolean"},"shouldMonitor":{"$ref":"#/components/schemas/MonitorTypes"},"monitorNewItems":{"$ref":"#/components/schemas/NewItemMonitorTypes"},"rootFolderPath":{"type":["string","null"]},"qualityProfileId":{"type":"integer","format":"int32"},"seriesType":{"$ref":"#/components/schemas/SeriesTypes"},"seasonFolder":{"type":"boolean"},"listType":{"$ref":"#/components/schemas/ImportListType"},"listOrder":{"type":"integer","format":"int32"},"minRefreshInterval":{"type":"string","format":"date-span"}},"additionalProperties":false},"ImportListType":{"enum":["program","plex","trakt","simkl","other","advanced"],"type":"string"},"ImportRejectionResource":{"type":"object","properties":{"reason":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/RejectionType"}},"additionalProperties":false},"IndexerBulkResource":{"type":"object","properties":{"ids":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"tags":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"applyTags":{"$ref":"#/components/schemas/ApplyTags"},"enableRss":{"type":["boolean","null"]},"enableAutomaticSearch":{"type":["boolean","null"]},"enableInteractiveSearch":{"type":["boolean","null"]},"priority":{"type":["integer","null"],"format":"int32"}},"additionalProperties":false},"IndexerConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"minimumAge":{"type":"integer","format":"int32"},"retention":{"type":"integer","format":"int32"},"maximumSize":{"type":"integer","format":"int32"},"rssSyncInterval":{"type":"integer","format":"int32"}},"additionalProperties":false},"IndexerFlagResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"nameLower":{"type":["string","null"],"readOnly":true}},"additionalProperties":false},"IndexerResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"implementationName":{"type":["string","null"]},"implementation":{"type":["string","null"]},"configContract":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/ProviderMessage"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/IndexerResource"}},"enableRss":{"type":"boolean"},"enableAutomaticSearch":{"type":"boolean"},"enableInteractiveSearch":{"type":"boolean"},"supportsRss":{"type":"boolean"},"supportsSearch":{"type":"boolean"},"protocol":{"$ref":"#/components/schemas/DownloadProtocol"},"priority":{"type":"integer","format":"int32"},"seasonSearchMaximumSingleEpisodeAge":{"type":"integer","format":"int32"},"downloadClientId":{"type":"integer","format":"int32"}},"additionalProperties":false},"Language":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]}},"additionalProperties":false},"LanguageProfileItemResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"language":{"$ref":"#/components/schemas/Language"},"allowed":{"type":"boolean"}},"additionalProperties":false},"LanguageProfileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"upgradeAllowed":{"type":"boolean"},"cutoff":{"$ref":"#/components/schemas/Language"},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/LanguageProfileItemResource"}}},"additionalProperties":false},"LanguageResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"nameLower":{"type":["string","null"],"readOnly":true}},"additionalProperties":false},"ListSyncLevelType":{"enum":["disabled","logOnly","keepAndUnmonitor","keepAndTag"],"type":"string"},"LocalizationLanguageResource":{"type":"object","properties":{"identifier":{"type":["string","null"]}},"additionalProperties":false},"LocalizationResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"strings":{"type":["object","null"],"additionalProperties":{"type":["string","null"]}}},"additionalProperties":false},"LogFileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"filename":{"type":["string","null"]},"lastWriteTime":{"type":"string","format":"date-time"},"contentsUrl":{"type":["string","null"]},"downloadUrl":{"type":["string","null"]}},"additionalProperties":false},"LogResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"time":{"type":"string","format":"date-time"},"exception":{"type":["string","null"]},"exceptionType":{"type":["string","null"]},"level":{"type":["string","null"]},"logger":{"type":["string","null"]},"message":{"type":["string","null"]},"method":{"type":["string","null"]}},"additionalProperties":false},"LogResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/LogResource"}}},"additionalProperties":false},"ManualImportReprocessResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"path":{"type":["string","null"]},"seriesId":{"type":"integer","format":"int32"},"seasonNumber":{"type":["integer","null"],"format":"int32"},"episodes":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EpisodeResource"}},"episodeIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"releaseGroup":{"type":["string","null"]},"downloadId":{"type":["string","null"]},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"indexerFlags":{"type":"integer","format":"int32"},"releaseType":{"$ref":"#/components/schemas/ReleaseType"},"rejections":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ImportRejectionResource"}}},"additionalProperties":false},"ManualImportResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"path":{"type":["string","null"]},"relativePath":{"type":["string","null"]},"folderName":{"type":["string","null"]},"name":{"type":["string","null"]},"size":{"type":"integer","format":"int64"},"series":{"$ref":"#/components/schemas/SeriesResource"},"seasonNumber":{"type":["integer","null"],"format":"int32"},"episodes":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EpisodeResource"}},"episodeFileId":{"type":["integer","null"],"format":"int32"},"releaseGroup":{"type":["string","null"]},"quality":{"$ref":"#/components/schemas/QualityModel"},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"qualityWeight":{"type":"integer","format":"int32"},"downloadId":{"type":["string","null"]},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"indexerFlags":{"type":"integer","format":"int32"},"releaseType":{"$ref":"#/components/schemas/ReleaseType"},"rejections":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ImportRejectionResource"}}},"additionalProperties":false},"MediaCover":{"type":"object","properties":{"coverType":{"$ref":"#/components/schemas/MediaCoverTypes"},"url":{"type":["string","null"]},"remoteUrl":{"type":["string","null"]}},"additionalProperties":false},"MediaCoverTypes":{"enum":["unknown","poster","banner","fanart","screenshot","headshot","clearlogo"],"type":"string"},"MediaInfoResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"audioBitrate":{"type":"integer","format":"int64"},"audioChannels":{"type":"number","format":"double"},"audioCodec":{"type":["string","null"]},"audioLanguages":{"type":["string","null"]},"audioStreamCount":{"type":"integer","format":"int32"},"videoBitDepth":{"type":"integer","format":"int32"},"videoBitrate":{"type":"integer","format":"int64"},"videoCodec":{"type":["string","null"]},"videoFps":{"type":"number","format":"double"},"videoDynamicRange":{"type":["string","null"]},"videoDynamicRangeType":{"type":["string","null"]},"resolution":{"type":["string","null"]},"runTime":{"type":["string","null"]},"scanType":{"type":["string","null"]},"subtitles":{"type":["string","null"]}},"additionalProperties":false},"MediaManagementConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"autoUnmonitorPreviouslyDownloadedEpisodes":{"type":"boolean"},"recycleBin":{"type":["string","null"]},"recycleBinCleanupDays":{"type":"integer","format":"int32"},"downloadPropersAndRepacks":{"$ref":"#/components/schemas/ProperDownloadTypes"},"createEmptySeriesFolders":{"type":"boolean"},"deleteEmptyFolders":{"type":"boolean"},"fileDate":{"$ref":"#/components/schemas/FileDateType"},"rescanAfterRefresh":{"$ref":"#/components/schemas/RescanAfterRefreshType"},"setPermissionsLinux":{"type":"boolean"},"chmodFolder":{"type":["string","null"]},"chownGroup":{"type":["string","null"]},"episodeTitleRequired":{"$ref":"#/components/schemas/EpisodeTitleRequiredType"},"skipFreeSpaceCheckWhenImporting":{"type":"boolean"},"minimumFreeSpaceWhenImporting":{"type":"integer","format":"int32"},"copyUsingHardlinks":{"type":"boolean"},"useScriptImport":{"type":"boolean"},"scriptImportPath":{"type":["string","null"]},"importExtraFiles":{"type":"boolean"},"extraFileExtensions":{"type":["string","null"]},"enableMediaInfo":{"type":"boolean"}},"additionalProperties":false},"MetadataResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"implementationName":{"type":["string","null"]},"implementation":{"type":["string","null"]},"configContract":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/ProviderMessage"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/MetadataResource"}},"enable":{"type":"boolean"}},"additionalProperties":false},"MonitorTypes":{"enum":["unknown","all","future","missing","existing","firstSeason","lastSeason","latestSeason","pilot","recent","monitorSpecials","unmonitorSpecials","none","skip"],"type":"string"},"MonitoringOptions":{"type":"object","properties":{"ignoreEpisodesWithFiles":{"type":"boolean"},"ignoreEpisodesWithoutFiles":{"type":"boolean"},"monitor":{"$ref":"#/components/schemas/MonitorTypes"}},"additionalProperties":false},"NamingConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"renameEpisodes":{"type":"boolean"},"replaceIllegalCharacters":{"type":"boolean"},"colonReplacementFormat":{"type":"integer","format":"int32"},"customColonReplacementFormat":{"type":["string","null"]},"multiEpisodeStyle":{"type":"integer","format":"int32"},"standardEpisodeFormat":{"type":["string","null"]},"dailyEpisodeFormat":{"type":["string","null"]},"animeEpisodeFormat":{"type":["string","null"]},"seriesFolderFormat":{"type":["string","null"]},"seasonFolderFormat":{"type":["string","null"]},"specialsFolderFormat":{"type":["string","null"]}},"additionalProperties":false},"NewItemMonitorTypes":{"enum":["all","none"],"type":"string"},"NotificationResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"fields":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Field"}},"implementationName":{"type":["string","null"]},"implementation":{"type":["string","null"]},"configContract":{"type":["string","null"]},"infoLink":{"type":["string","null"]},"message":{"$ref":"#/components/schemas/ProviderMessage"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"presets":{"type":["array","null"],"items":{"$ref":"#/components/schemas/NotificationResource"}},"link":{"type":["string","null"]},"onGrab":{"type":"boolean"},"onDownload":{"type":"boolean"},"onUpgrade":{"type":"boolean"},"onImportComplete":{"type":"boolean"},"onRename":{"type":"boolean"},"onSeriesAdd":{"type":"boolean"},"onSeriesDelete":{"type":"boolean"},"onEpisodeFileDelete":{"type":"boolean"},"onEpisodeFileDeleteForUpgrade":{"type":"boolean"},"onHealthIssue":{"type":"boolean"},"includeHealthWarnings":{"type":"boolean"},"onHealthRestored":{"type":"boolean"},"onApplicationUpdate":{"type":"boolean"},"onManualInteractionRequired":{"type":"boolean"},"supportsOnGrab":{"type":"boolean"},"supportsOnDownload":{"type":"boolean"},"supportsOnUpgrade":{"type":"boolean"},"supportsOnImportComplete":{"type":"boolean"},"supportsOnRename":{"type":"boolean"},"supportsOnSeriesAdd":{"type":"boolean"},"supportsOnSeriesDelete":{"type":"boolean"},"supportsOnEpisodeFileDelete":{"type":"boolean"},"supportsOnEpisodeFileDeleteForUpgrade":{"type":"boolean"},"supportsOnHealthIssue":{"type":"boolean"},"supportsOnHealthRestored":{"type":"boolean"},"supportsOnApplicationUpdate":{"type":"boolean"},"supportsOnManualInteractionRequired":{"type":"boolean"},"testCommand":{"type":["string","null"]}},"additionalProperties":false},"ParseResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"title":{"type":["string","null"]},"parsedEpisodeInfo":{"$ref":"#/components/schemas/ParsedEpisodeInfo"},"series":{"$ref":"#/components/schemas/SeriesResource"},"episodes":{"type":["array","null"],"items":{"$ref":"#/components/schemas/EpisodeResource"}},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"}},"additionalProperties":false},"ParsedEpisodeInfo":{"type":"object","properties":{"releaseTitle":{"type":["string","null"]},"seriesTitle":{"type":["string","null"]},"seriesTitleInfo":{"$ref":"#/components/schemas/SeriesTitleInfo"},"quality":{"$ref":"#/components/schemas/QualityModel"},"seasonNumber":{"type":"integer","format":"int32"},"episodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"absoluteEpisodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"specialAbsoluteEpisodeNumbers":{"type":["array","null"],"items":{"type":"number","format":"double"}},"airDate":{"type":["string","null"]},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"fullSeason":{"type":"boolean"},"isPartialSeason":{"type":"boolean"},"isMultiSeason":{"type":"boolean"},"isSeasonExtra":{"type":"boolean"},"isSplitEpisode":{"type":"boolean"},"isMiniSeries":{"type":"boolean"},"special":{"type":"boolean"},"releaseGroup":{"type":["string","null"]},"releaseHash":{"type":["string","null"]},"seasonPart":{"type":"integer","format":"int32"},"releaseTokens":{"type":["string","null"]},"dailyPart":{"type":["integer","null"],"format":"int32"},"isDaily":{"type":"boolean","readOnly":true},"isAbsoluteNumbering":{"type":"boolean","readOnly":true},"isPossibleSpecialEpisode":{"type":"boolean","readOnly":true},"isPossibleSceneSeasonSpecial":{"type":"boolean","readOnly":true},"releaseType":{"$ref":"#/components/schemas/ReleaseType"}},"additionalProperties":false},"PingResource":{"type":"object","properties":{"status":{"type":["string","null"]}},"additionalProperties":false},"PrivacyLevel":{"enum":["normal","password","apiKey","userName"],"type":"string"},"ProfileFormatItemResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"format":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"score":{"type":"integer","format":"int32"}},"additionalProperties":false},"ProperDownloadTypes":{"enum":["preferAndUpgrade","doNotUpgrade","doNotPrefer"],"type":"string"},"ProviderMessage":{"type":"object","properties":{"message":{"type":["string","null"]},"type":{"$ref":"#/components/schemas/ProviderMessageType"}},"additionalProperties":false},"ProviderMessageType":{"enum":["info","warning","error"],"type":"string"},"ProxyType":{"enum":["http","socks4","socks5"],"type":"string"},"Quality":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"source":{"$ref":"#/components/schemas/QualitySource"},"resolution":{"type":"integer","format":"int32"}},"additionalProperties":false},"QualityDefinitionLimitsResource":{"type":"object","properties":{"min":{"type":"integer","format":"int32"},"max":{"type":"integer","format":"int32"}},"additionalProperties":false},"QualityDefinitionResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"quality":{"$ref":"#/components/schemas/Quality"},"title":{"type":["string","null"]},"weight":{"type":"integer","format":"int32"},"minSize":{"type":["number","null"],"format":"double"},"maxSize":{"type":["number","null"],"format":"double"},"preferredSize":{"type":["number","null"],"format":"double"}},"additionalProperties":false},"QualityModel":{"type":"object","properties":{"quality":{"$ref":"#/components/schemas/Quality"},"revision":{"$ref":"#/components/schemas/Revision"}},"additionalProperties":false},"QualityProfileQualityItemResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"quality":{"$ref":"#/components/schemas/Quality"},"items":{"type":["array","null"],"items":{"$ref":"#/components/schemas/QualityProfileQualityItemResource"}},"allowed":{"type":"boolean"}},"additionalProperties":false},"QualityProfileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"upgradeAllowed":{"type":"boolean"},"cutoff":{"type":"integer","format":"int32"},"items":{"type":["array","null"],"items":{"$ref":"#/components/schemas/QualityProfileQualityItemResource"}},"minFormatScore":{"type":"integer","format":"int32"},"cutoffFormatScore":{"type":"integer","format":"int32"},"minUpgradeFormatScore":{"type":"integer","format":"int32"},"formatItems":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ProfileFormatItemResource"}}},"additionalProperties":false},"QualitySource":{"enum":["unknown","television","televisionRaw","web","webRip","dvd","bluray","blurayRaw"],"type":"string"},"QueueBulkResource":{"type":"object","properties":{"ids":{"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"QueueResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seriesId":{"type":["integer","null"],"format":"int32"},"episodeId":{"type":["integer","null"],"format":"int32"},"seasonNumber":{"type":["integer","null"],"format":"int32"},"series":{"$ref":"#/components/schemas/SeriesResource"},"episode":{"$ref":"#/components/schemas/EpisodeResource"},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"quality":{"$ref":"#/components/schemas/QualityModel"},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"size":{"type":"number","format":"double"},"title":{"type":["string","null"]},"estimatedCompletionTime":{"type":["string","null"],"format":"date-time"},"added":{"type":["string","null"],"format":"date-time"},"status":{"$ref":"#/components/schemas/QueueStatus"},"trackedDownloadStatus":{"$ref":"#/components/schemas/TrackedDownloadStatus"},"trackedDownloadState":{"$ref":"#/components/schemas/TrackedDownloadState"},"statusMessages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/TrackedDownloadStatusMessage"}},"errorMessage":{"type":["string","null"]},"downloadId":{"type":["string","null"]},"protocol":{"$ref":"#/components/schemas/DownloadProtocol"},"downloadClient":{"type":["string","null"]},"downloadClientHasPostImportCategory":{"type":"boolean"},"indexer":{"type":["string","null"]},"outputPath":{"type":["string","null"]},"episodeHasFile":{"type":"boolean"},"sizeleft":{"type":"number","format":"double","deprecated":true},"timeleft":{"type":["string","null"],"format":"date-span","deprecated":true}},"additionalProperties":false},"QueueResourcePagingResource":{"type":"object","properties":{"page":{"type":"integer","format":"int32"},"pageSize":{"type":"integer","format":"int32"},"sortKey":{"type":["string","null"]},"sortDirection":{"$ref":"#/components/schemas/SortDirection"},"totalRecords":{"type":"integer","format":"int32"},"records":{"type":["array","null"],"items":{"$ref":"#/components/schemas/QueueResource"}}},"additionalProperties":false},"QueueStatus":{"enum":["unknown","queued","paused","downloading","completed","failed","warning","delay","downloadClientUnavailable","fallback"],"type":"string"},"QueueStatusResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"totalCount":{"type":"integer","format":"int32"},"count":{"type":"integer","format":"int32"},"unknownCount":{"type":"integer","format":"int32"},"errors":{"type":"boolean"},"warnings":{"type":"boolean"},"unknownErrors":{"type":"boolean"},"unknownWarnings":{"type":"boolean"}},"additionalProperties":false},"Ratings":{"type":"object","properties":{"votes":{"type":"integer","format":"int32"},"value":{"type":"number","format":"double"}},"additionalProperties":false},"RejectionType":{"enum":["permanent","temporary"],"type":"string"},"ReleaseEpisodeResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seasonNumber":{"type":"integer","format":"int32"},"episodeNumber":{"type":"integer","format":"int32"},"absoluteEpisodeNumber":{"type":["integer","null"],"format":"int32"},"title":{"type":["string","null"]}},"additionalProperties":false},"ReleaseProfileResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"enabled":{"type":"boolean"},"required":{"nullable":true},"ignored":{"nullable":true},"indexerId":{"type":"integer","format":"int32"},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"ReleaseResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"guid":{"type":["string","null"]},"quality":{"$ref":"#/components/schemas/QualityModel"},"qualityWeight":{"type":"integer","format":"int32"},"age":{"type":"integer","format":"int32"},"ageHours":{"type":"number","format":"double"},"ageMinutes":{"type":"number","format":"double"},"size":{"type":"integer","format":"int64"},"indexerId":{"type":"integer","format":"int32"},"indexer":{"type":["string","null"]},"releaseGroup":{"type":["string","null"]},"subGroup":{"type":["string","null"]},"releaseHash":{"type":["string","null"]},"title":{"type":["string","null"]},"fullSeason":{"type":"boolean"},"sceneSource":{"type":"boolean"},"seasonNumber":{"type":"integer","format":"int32"},"languages":{"type":["array","null"],"items":{"$ref":"#/components/schemas/Language"}},"languageWeight":{"type":"integer","format":"int32"},"airDate":{"type":["string","null"]},"seriesTitle":{"type":["string","null"]},"episodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"absoluteEpisodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"mappedSeasonNumber":{"type":["integer","null"],"format":"int32"},"mappedEpisodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"mappedAbsoluteEpisodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"mappedSeriesId":{"type":["integer","null"],"format":"int32"},"mappedEpisodeInfo":{"type":["array","null"],"items":{"$ref":"#/components/schemas/ReleaseEpisodeResource"}},"approved":{"type":"boolean"},"temporarilyRejected":{"type":"boolean"},"rejected":{"type":"boolean"},"tvdbId":{"type":"integer","format":"int32"},"tvRageId":{"type":"integer","format":"int32"},"imdbId":{"type":["string","null"]},"rejections":{"type":["array","null"],"items":{"type":"string"}},"publishDate":{"type":"string","format":"date-time"},"commentUrl":{"type":["string","null"]},"downloadUrl":{"type":["string","null"]},"infoUrl":{"type":["string","null"]},"episodeRequested":{"type":"boolean"},"downloadAllowed":{"type":"boolean"},"releaseWeight":{"type":"integer","format":"int32"},"customFormats":{"type":["array","null"],"items":{"$ref":"#/components/schemas/CustomFormatResource"}},"customFormatScore":{"type":"integer","format":"int32"},"sceneMapping":{"$ref":"#/components/schemas/AlternateTitleResource"},"magnetUrl":{"type":["string","null"]},"infoHash":{"type":["string","null"]},"seeders":{"type":["integer","null"],"format":"int32"},"leechers":{"type":["integer","null"],"format":"int32"},"protocol":{"$ref":"#/components/schemas/DownloadProtocol"},"indexerFlags":{"type":"integer","format":"int32"},"isDaily":{"type":"boolean"},"isAbsoluteNumbering":{"type":"boolean"},"isPossibleSpecialEpisode":{"type":"boolean"},"special":{"type":"boolean"},"seriesId":{"type":["integer","null"],"format":"int32"},"episodeId":{"type":["integer","null"],"format":"int32"},"episodeIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"downloadClientId":{"type":["integer","null"],"format":"int32"},"downloadClient":{"type":["string","null"]},"shouldOverride":{"type":["boolean","null"]}},"additionalProperties":false},"ReleaseType":{"enum":["unknown","singleEpisode","multiEpisode","seasonPack"],"type":"string"},"RemotePathMappingResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"host":{"type":["string","null"]},"remotePath":{"type":["string","null"]},"localPath":{"type":["string","null"]}},"additionalProperties":false},"RenameEpisodeResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"seriesId":{"type":"integer","format":"int32"},"seasonNumber":{"type":"integer","format":"int32"},"episodeNumbers":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"episodeFileId":{"type":"integer","format":"int32"},"existingPath":{"type":["string","null"]},"newPath":{"type":["string","null"]}},"additionalProperties":false},"RescanAfterRefreshType":{"enum":["always","afterManual","never"],"type":"string"},"Revision":{"type":"object","properties":{"version":{"type":"integer","format":"int32"},"real":{"type":"integer","format":"int32"},"isRepack":{"type":"boolean"}},"additionalProperties":false},"RootFolderResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"path":{"type":["string","null"]},"accessible":{"type":"boolean"},"freeSpace":{"type":["integer","null"],"format":"int64"},"unmappedFolders":{"type":["array","null"],"items":{"$ref":"#/components/schemas/UnmappedFolder"}}},"additionalProperties":false},"RuntimeMode":{"enum":["console","service","tray"],"type":"string"},"SeasonPassResource":{"type":"object","properties":{"series":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SeasonPassSeriesResource"}},"monitoringOptions":{"$ref":"#/components/schemas/MonitoringOptions"}},"additionalProperties":false},"SeasonPassSeriesResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"monitored":{"type":["boolean","null"]},"seasons":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SeasonResource"}}},"additionalProperties":false},"SeasonResource":{"type":"object","properties":{"seasonNumber":{"type":"integer","format":"int32"},"monitored":{"type":"boolean"},"statistics":{"$ref":"#/components/schemas/SeasonStatisticsResource"},"images":{"type":["array","null"],"items":{"$ref":"#/components/schemas/MediaCover"}}},"additionalProperties":false},"SeasonStatisticsResource":{"type":"object","properties":{"nextAiring":{"type":["string","null"],"format":"date-time"},"previousAiring":{"type":["string","null"],"format":"date-time"},"episodeFileCount":{"type":"integer","format":"int32"},"episodeCount":{"type":"integer","format":"int32"},"totalEpisodeCount":{"type":"integer","format":"int32"},"sizeOnDisk":{"type":"integer","format":"int64"},"releaseGroups":{"type":["array","null"],"items":{"type":"string"}},"percentOfEpisodes":{"type":"number","format":"double","readOnly":true}},"additionalProperties":false},"SelectOption":{"type":"object","properties":{"value":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"order":{"type":"integer","format":"int32"},"hint":{"type":["string","null"]}},"additionalProperties":false},"SeriesEditorResource":{"type":"object","properties":{"seriesIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"monitored":{"type":["boolean","null"]},"monitorNewItems":{"$ref":"#/components/schemas/NewItemMonitorTypes"},"qualityProfileId":{"type":["integer","null"],"format":"int32"},"seriesType":{"$ref":"#/components/schemas/SeriesTypes"},"seasonFolder":{"type":["boolean","null"]},"rootFolderPath":{"type":["string","null"]},"tags":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"applyTags":{"$ref":"#/components/schemas/ApplyTags"},"moveFiles":{"type":"boolean"},"deleteFiles":{"type":"boolean"},"addImportListExclusion":{"type":"boolean"}},"additionalProperties":false},"SeriesResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"title":{"type":["string","null"]},"alternateTitles":{"type":["array","null"],"items":{"$ref":"#/components/schemas/AlternateTitleResource"}},"sortTitle":{"type":["string","null"]},"status":{"$ref":"#/components/schemas/SeriesStatusType"},"ended":{"type":"boolean","readOnly":true},"profileName":{"type":["string","null"]},"overview":{"type":["string","null"]},"nextAiring":{"type":["string","null"],"format":"date-time"},"previousAiring":{"type":["string","null"],"format":"date-time"},"network":{"type":["string","null"]},"airTime":{"type":["string","null"]},"images":{"type":["array","null"],"items":{"$ref":"#/components/schemas/MediaCover"}},"originalLanguage":{"$ref":"#/components/schemas/Language"},"remotePoster":{"type":["string","null"]},"seasons":{"type":["array","null"],"items":{"$ref":"#/components/schemas/SeasonResource"}},"year":{"type":"integer","format":"int32"},"path":{"type":["string","null"]},"qualityProfileId":{"type":"integer","format":"int32"},"seasonFolder":{"type":"boolean"},"monitored":{"type":"boolean"},"monitorNewItems":{"$ref":"#/components/schemas/NewItemMonitorTypes"},"useSceneNumbering":{"type":"boolean"},"runtime":{"type":"integer","format":"int32"},"tvdbId":{"type":"integer","format":"int32"},"tvRageId":{"type":"integer","format":"int32"},"tvMazeId":{"type":"integer","format":"int32"},"tmdbId":{"type":"integer","format":"int32"},"firstAired":{"type":["string","null"],"format":"date-time"},"lastAired":{"type":["string","null"],"format":"date-time"},"seriesType":{"$ref":"#/components/schemas/SeriesTypes"},"cleanTitle":{"type":["string","null"]},"imdbId":{"type":["string","null"]},"titleSlug":{"type":["string","null"]},"rootFolderPath":{"type":["string","null"]},"folder":{"type":["string","null"]},"certification":{"type":["string","null"]},"genres":{"type":["array","null"],"items":{"type":"string"}},"tags":{"uniqueItems":true,"type":["array","null"],"items":{"type":"integer","format":"int32"}},"added":{"type":"string","format":"date-time"},"addOptions":{"$ref":"#/components/schemas/AddSeriesOptions"},"ratings":{"$ref":"#/components/schemas/Ratings"},"statistics":{"$ref":"#/components/schemas/SeriesStatisticsResource"},"episodesChanged":{"type":["boolean","null"]},"languageProfileId":{"type":"integer","format":"int32","readOnly":true,"deprecated":true}},"additionalProperties":false},"SeriesStatisticsResource":{"type":"object","properties":{"seasonCount":{"type":"integer","format":"int32"},"episodeFileCount":{"type":"integer","format":"int32"},"episodeCount":{"type":"integer","format":"int32"},"totalEpisodeCount":{"type":"integer","format":"int32"},"sizeOnDisk":{"type":"integer","format":"int64"},"releaseGroups":{"type":["array","null"],"items":{"type":"string"}},"percentOfEpisodes":{"type":"number","format":"double","readOnly":true}},"additionalProperties":false},"SeriesStatusType":{"enum":["continuing","ended","upcoming","deleted"],"type":"string"},"SeriesTitleInfo":{"type":"object","properties":{"title":{"type":["string","null"]},"titleWithoutYear":{"type":["string","null"]},"year":{"type":"integer","format":"int32"},"allTitles":{"type":["array","null"],"items":{"type":"string"}}},"additionalProperties":false},"SeriesTypes":{"enum":["standard","daily","anime"],"type":"string"},"SortDirection":{"enum":["default","ascending","descending"],"type":"string"},"SystemResource":{"type":"object","properties":{"appName":{"type":["string","null"]},"instanceName":{"type":["string","null"]},"version":{"type":["string","null"]},"buildTime":{"type":"string","format":"date-time"},"isDebug":{"type":"boolean"},"isProduction":{"type":"boolean"},"isAdmin":{"type":"boolean"},"isUserInteractive":{"type":"boolean"},"startupPath":{"type":["string","null"]},"appData":{"type":["string","null"]},"osName":{"type":["string","null"]},"osVersion":{"type":["string","null"]},"isNetCore":{"type":"boolean"},"isLinux":{"type":"boolean"},"isOsx":{"type":"boolean"},"isWindows":{"type":"boolean"},"isDocker":{"type":"boolean"},"mode":{"$ref":"#/components/schemas/RuntimeMode"},"branch":{"type":["string","null"]},"authentication":{"$ref":"#/components/schemas/AuthenticationType"},"sqliteVersion":{"type":["string","null"]},"migrationVersion":{"type":"integer","format":"int32"},"urlBase":{"type":["string","null"]},"runtimeVersion":{"type":["string","null"]},"runtimeName":{"type":["string","null"]},"startTime":{"type":"string","format":"date-time"},"packageVersion":{"type":["string","null"]},"packageAuthor":{"type":["string","null"]},"packageUpdateMechanism":{"$ref":"#/components/schemas/UpdateMechanism"},"packageUpdateMechanismMessage":{"type":["string","null"]},"databaseVersion":{"type":["string","null"]},"databaseType":{"$ref":"#/components/schemas/DatabaseType"}},"additionalProperties":false},"TagDetailsResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"label":{"type":["string","null"]},"delayProfileIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"importListIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"notificationIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"restrictionIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"indexerIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"downloadClientIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"autoTagIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}},"seriesIds":{"type":["array","null"],"items":{"type":"integer","format":"int32"}}},"additionalProperties":false},"TagResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"label":{"type":["string","null"]}},"additionalProperties":false},"TaskResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"name":{"type":["string","null"]},"taskName":{"type":["string","null"]},"interval":{"type":"integer","format":"int32"},"lastExecution":{"type":"string","format":"date-time"},"lastStartTime":{"type":"string","format":"date-time"},"nextExecution":{"type":"string","format":"date-time"},"lastDuration":{"type":"string","format":"date-span","readOnly":true}},"additionalProperties":false},"TrackedDownloadState":{"enum":["downloading","importBlocked","importPending","importing","imported","failedPending","failed","ignored"],"type":"string"},"TrackedDownloadStatus":{"enum":["ok","warning","error"],"type":"string"},"TrackedDownloadStatusMessage":{"type":"object","properties":{"title":{"type":["string","null"]},"messages":{"type":["array","null"],"items":{"type":"string"}}},"additionalProperties":false},"UiConfigResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"firstDayOfWeek":{"type":"integer","format":"int32"},"calendarWeekColumnHeader":{"type":["string","null"]},"shortDateFormat":{"type":["string","null"]},"longDateFormat":{"type":["string","null"]},"timeFormat":{"type":["string","null"]},"showRelativeDates":{"type":"boolean"},"enableColorImpairedMode":{"type":"boolean"},"theme":{"type":["string","null"]},"uiLanguage":{"type":"integer","format":"int32"}},"additionalProperties":false},"UnmappedFolder":{"type":"object","properties":{"name":{"type":["string","null"]},"path":{"type":["string","null"]},"relativePath":{"type":["string","null"]}},"additionalProperties":false},"UpdateChanges":{"type":"object","properties":{"new":{"type":["array","null"],"items":{"type":"string"}},"fixed":{"type":["array","null"],"items":{"type":"string"}}},"additionalProperties":false},"UpdateMechanism":{"enum":["builtIn","script","external","apt","docker"],"type":"string"},"UpdateResource":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"version":{"type":["string","null"]},"branch":{"type":["string","null"]},"releaseDate":{"type":"string","format":"date-time"},"fileName":{"type":["string","null"]},"url":{"type":["string","null"]},"installed":{"type":"boolean"},"installedOn":{"type":["string","null"],"format":"date-time"},"installable":{"type":"boolean"},"latest":{"type":"boolean"},"changes":{"$ref":"#/components/schemas/UpdateChanges"},"hash":{"type":["string","null"]}},"additionalProperties":false}},"securitySchemes":{"X-Api-Key":{"type":"apiKey","description":"Apikey passed as header","name":"X-Api-Key","in":"header"},"apikey":{"type":"apiKey","description":"Apikey passed as query parameter","name":"apikey","in":"query"}}},"security":[{"X-Api-Key":[]},{"apikey":[]}]} \ No newline at end of file diff --git a/src/api.rs b/src/api.rs new file mode 100644 index 0000000..4345ad8 --- /dev/null +++ b/src/api.rs @@ -0,0 +1,530 @@ +use reqwest::Client; +use serde::{Deserialize, Serialize}; +use std::collections::HashMap; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum ApiError { + #[error("HTTP request failed: {0}")] + Request(#[from] reqwest::Error), + #[error("Serialization error: {0}")] + Serialization(#[from] serde_json::Error), + #[error("API error: {message}")] + Api { message: String }, +} + +pub type Result = std::result::Result; + +#[derive(Clone)] +pub struct SonarrClient { + client: Client, + base_url: String, + api_key: String, +} + +impl SonarrClient { + pub fn new(base_url: String, api_key: String) -> Self { + Self { + client: Client::new(), + base_url: base_url.trim_end_matches('/').to_string(), + api_key, + } + } + + async fn get Deserialize<'de>>(&self, endpoint: &str) -> Result { + let url = format!("{}/api/v3{}", self.base_url, endpoint); + let response = self + .client + .get(&url) + .header("X-Api-Key", &self.api_key) + .send() + .await?; + + if !response.status().is_success() { + return Err(ApiError::Api { + message: format!("HTTP {}: {}", response.status(), response.text().await?), + }); + } + + let text = response.text().await?; + serde_json::from_str(&text).map_err(ApiError::from) + } + + async fn post Deserialize<'de>>( + &self, + endpoint: &str, + data: &T, + ) -> Result { + let url = format!("{}/api/v3{}", self.base_url, endpoint); + let response = self + .client + .post(&url) + .header("X-Api-Key", &self.api_key) + .json(data) + .send() + .await?; + + if !response.status().is_success() { + return Err(ApiError::Api { + message: format!("HTTP {}: {}", response.status(), response.text().await?), + }); + } + + let text = response.text().await?; + serde_json::from_str(&text).map_err(ApiError::from) + } + + pub async fn get_system_status(&self) -> Result { + self.get("/system/status").await + } + + pub async fn get_series(&self) -> Result> { + self.get("/series").await + } + + pub async fn get_series_by_id(&self, id: u32) -> Result { + self.get(&format!("/series/{}", id)).await + } + + pub async fn get_episodes( + &self, + series_id: Option, + season_number: Option, + ) -> Result> { + let mut query = Vec::new(); + if let Some(id) = series_id { + query.push(format!("seriesId={}", id)); + } + if let Some(season) = season_number { + query.push(format!("seasonNumber={}", season)); + } + + let query_string = if query.is_empty() { + String::new() + } else { + format!("?{}", query.join("&")) + }; + + self.get(&format!("/episode{}", query_string)).await + } + + pub async fn get_calendar( + &self, + start: Option<&str>, + end: Option<&str>, + ) -> Result> { + let mut query = Vec::new(); + if let Some(start_date) = start { + query.push(format!("start={}", start_date)); + } + if let Some(end_date) = end { + query.push(format!("end={}", end_date)); + } + + let query_string = if query.is_empty() { + String::new() + } else { + format!("?{}", query.join("&")) + }; + + self.get(&format!("/calendar{}", query_string)).await + } + + pub async fn get_queue(&self) -> Result { + self.get("/queue").await + } + + pub async fn get_history(&self) -> Result { + self.get("/history").await + } + + pub async fn get_missing_episodes(&self) -> Result { + self.get("/wanted/missing").await + } + + pub async fn get_health(&self) -> Result> { + self.get("/health").await + } + + pub async fn search_series(&self, term: &str) -> Result> { + self.get(&format!( + "/series/lookup?term={}", + urlencoding::encode(term) + )) + .await + } + + pub async fn add_series(&self, series: &Series) -> Result { + self.post("/series", series).await + } +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SystemStatus { + pub app_name: Option, + pub instance_name: Option, + pub version: Option, + pub build_time: chrono::DateTime, + pub is_debug: bool, + pub is_production: bool, + pub is_admin: bool, + pub is_user_interactive: bool, + pub startup_path: Option, + pub app_data: Option, + pub os_name: Option, + pub os_version: Option, + pub is_net_core: bool, + pub is_linux: bool, + pub is_osx: bool, + pub is_windows: bool, + pub is_docker: bool, + pub mode: String, + pub branch: Option, + pub authentication: String, + pub sqlite_version: Option, + pub migration_version: i32, + pub url_base: Option, + pub runtime_version: Option, + pub runtime_name: Option, + pub start_time: chrono::DateTime, + pub package_version: Option, + pub package_author: Option, + pub package_update_mechanism: String, + pub package_update_mechanism_message: Option, + pub database_version: Option, + pub database_type: String, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Series { + pub id: u32, + pub title: Option, + pub alternate_titles: Option>, + pub sort_title: Option, + pub status: String, + pub ended: Option, + pub profile_name: Option, + pub overview: Option, + pub next_airing: Option>, + pub previous_airing: Option>, + pub network: Option, + pub air_time: Option, + pub images: Option>, + pub original_language: Option, + pub remote_poster: Option, + pub seasons: Option>, + pub year: i32, + pub path: Option, + pub quality_profile_id: u32, + pub season_folder: bool, + pub monitored: bool, + pub monitor_new_items: String, + pub use_scene_numbering: bool, + pub runtime: i32, + pub tvdb_id: u32, + pub tv_rage_id: u32, + pub tv_maze_id: u32, + pub tmdb_id: u32, + pub first_aired: Option>, + pub last_aired: Option>, + pub series_type: String, + pub clean_title: Option, + pub imdb_id: Option, + pub title_slug: Option, + pub root_folder_path: Option, + pub folder: Option, + pub certification: Option, + pub genres: Option>, + pub tags: Option>, + pub added: chrono::DateTime, + pub add_options: Option, + pub ratings: Option, + pub statistics: Option, + pub episodes_changed: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AlternateTitle { + pub title: Option, + pub season_number: Option, + pub scene_season_number: Option, + pub scene_origin: Option, + pub comment: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct MediaCover { + pub cover_type: String, + pub url: Option, + pub remote_url: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Language { + pub id: u32, + pub name: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Season { + pub season_number: i32, + pub monitored: bool, + pub statistics: Option, + pub images: Option>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct AddSeriesOptions { + pub ignore_episodes_with_files: bool, + pub ignore_episodes_without_files: bool, + pub monitor: String, + pub search_for_missing_episodes: bool, + pub search_for_cutoff_unmet_episodes: bool, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Ratings { + pub votes: i32, + pub value: f64, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SeriesStatistics { + pub season_count: i32, + pub episode_file_count: i32, + pub episode_count: i32, + pub total_episode_count: i32, + pub size_on_disk: i64, + pub release_groups: Option>, + pub percent_of_episodes: f64, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct SeasonStatistics { + pub next_airing: Option>, + pub previous_airing: Option>, + pub episode_file_count: i32, + pub episode_count: i32, + pub total_episode_count: i32, + pub size_on_disk: i64, + pub release_groups: Option>, + pub percent_of_episodes: f64, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Episode { + pub id: u32, + pub series_id: u32, + pub tvdb_id: u32, + pub episode_file_id: u32, + pub season_number: i32, + pub episode_number: i32, + pub title: Option, + pub air_date: Option, + pub air_date_utc: Option>, + pub last_search_time: Option>, + pub runtime: i32, + pub finale_type: Option, + pub overview: Option, + pub episode_file: Option, + pub has_file: bool, + pub monitored: bool, + pub absolute_episode_number: Option, + pub scene_absolute_episode_number: Option, + pub scene_episode_number: Option, + pub scene_season_number: Option, + pub unverified_scene_numbering: bool, + pub end_time: Option>, + pub grab_date: Option>, + pub series: Option, + pub images: Option>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct EpisodeFile { + pub id: u32, + pub series_id: u32, + pub season_number: i32, + pub relative_path: Option, + pub path: Option, + pub size: i64, + pub date_added: chrono::DateTime, + pub scene_name: Option, + pub release_group: Option, + pub languages: Option>, + pub quality: Option, + pub custom_formats: Option>, + pub custom_format_score: i32, + pub indexer_flags: Option, + pub release_type: Option, + pub media_info: Option, + pub quality_cutoff_not_met: bool, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Quality { + pub quality: QualityDefinition, + pub revision: Revision, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct QualityDefinition { + pub id: u32, + pub name: Option, + pub source: String, + pub resolution: i32, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct Revision { + pub version: i32, + pub real: i32, + pub is_repack: bool, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct CustomFormat { + pub id: u32, + pub name: Option, + pub include_custom_format_when_renaming: Option, + pub specifications: Option>>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct MediaInfo { + pub id: u32, + pub audio_bitrate: i64, + pub audio_channels: f64, + pub audio_codec: Option, + pub audio_languages: Option, + pub audio_stream_count: i32, + pub video_bit_depth: i32, + pub video_bitrate: i64, + pub video_codec: Option, + pub video_fps: f64, + pub video_dynamic_range: Option, + pub video_dynamic_range_type: Option, + pub resolution: Option, + pub run_time: Option, + pub scan_type: Option, + pub subtitles: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct QueuePagingResource { + pub page: i32, + pub page_size: i32, + pub sort_key: Option, + pub sort_direction: String, + pub total_records: i32, + pub records: Vec, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct QueueItem { + pub id: u32, + pub series_id: Option, + pub episode_id: Option, + pub season_number: Option, + pub series: Option, + pub episode: Option, + pub languages: Option>, + pub quality: Option, + pub custom_formats: Option>, + pub custom_format_score: i32, + pub size: f64, + pub title: Option, + pub estimated_completion_time: Option>, + pub added: Option>, + pub status: String, + pub tracked_download_status: Option, + pub tracked_download_state: Option, + pub status_messages: Option>, + pub error_message: Option, + pub download_id: Option, + pub protocol: String, + pub download_client: Option, + pub download_client_has_post_import_category: bool, + pub indexer: Option, + pub output_path: Option, + pub episode_has_file: bool, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct StatusMessage { + pub title: Option, + pub messages: Option>, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct HistoryPagingResource { + pub page: i32, + pub page_size: i32, + pub sort_key: Option, + pub sort_direction: String, + pub total_records: i32, + pub records: Vec, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct HistoryItem { + pub id: u32, + pub episode_id: u32, + pub series_id: u32, + pub source_title: Option, + pub languages: Option>, + pub quality: Option, + pub custom_formats: Option>, + pub custom_format_score: i32, + pub quality_cutoff_not_met: bool, + pub date: chrono::DateTime, + pub download_id: Option, + pub event_type: String, + pub data: Option>, + pub episode: Option, + pub series: Option, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct EpisodePagingResource { + pub page: i32, + pub page_size: i32, + pub sort_key: Option, + pub sort_direction: String, + pub total_records: i32, + pub records: Vec, +} + +#[derive(Debug, Clone, Deserialize, Serialize)] +#[serde(rename_all = "camelCase")] +pub struct HealthResource { + pub id: u32, + pub source: Option, + #[serde(rename = "type")] + pub health_type: String, + pub message: Option, + pub wiki_url: Option, +} diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..eaa3f04 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,36 @@ +#[derive(Debug, clap::Parser)] +pub struct Cli { + #[clap(subcommand)] + pub cmd: SubCommand, +} + +#[derive(Debug, clap::Subcommand)] +pub enum SubCommand { + #[clap(name = "add")] + Add(Add), + #[clap(name = "list")] + List(List), + #[clap(name = "completions")] + Completions { shell: clap_complete::Shell }, +} + +#[derive(Debug, clap::Args)] +pub struct Add { + #[clap(short, long)] + pub name: String, +} + +#[derive(Debug, clap::Args)] +pub struct List {} + +impl Cli { + pub fn completions(shell: clap_complete::Shell) { + let mut command = ::command(); + clap_complete::generate( + shell, + &mut command, + env!("CARGO_BIN_NAME"), + &mut std::io::stdout(), + ); + } +} diff --git a/src/errors.rs b/src/errors.rs new file mode 100644 index 0000000..149f933 --- /dev/null +++ b/src/errors.rs @@ -0,0 +1,6 @@ +pub use error_stack::{Report, ResultExt}; +#[derive(Debug, thiserror::Error)] +#[error("An error occurred")] +pub struct Error; + +pub type Result> = core::result::Result; diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..97cf2ba --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,3 @@ +pub mod errors; +use errors::*; +mod api; diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..f47d767 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,28 @@ +mod api; +mod cli; +mod errors; +mod tui; +use errors::*; + +use crate::api::SonarrClient; +pub fn main() -> Result<()> { + // let args = ::parse(); + // match args.cmd { + // cli::SubCommand::Add(add) => { + // println!("Add: {:?}", add); + // } + // cli::SubCommand::List(list) => { + // println!("List: {:?}", list); + // } + // cli::SubCommand::Completions { shell } => { + // cli::Cli::completions(shell); + // } + // } + + let client = SonarrClient::new( + "https://sonarr.tsuba.darksailor.dev".into(), + "1a47401731bf44ae9787dfcd4bab402f".into(), + ); + tui::run_app(client); + Ok(()) +} diff --git a/src/tui.rs b/src/tui.rs new file mode 100644 index 0000000..74ff5d5 --- /dev/null +++ b/src/tui.rs @@ -0,0 +1,1141 @@ +use crossterm::{ + event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode, KeyEventKind}, + execute, + terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen}, +}; +use ratatui::{ + backend::{Backend, CrosstermBackend}, + layout::{Alignment, Constraint, Direction, Layout, Rect}, + style::{Color, Modifier, Style}, + text::{Line, Span, Text}, + widgets::{ + Block, Borders, Cell, Clear, Gauge, List, ListItem, ListState, Paragraph, Row, Table, + TableState, Tabs, Wrap, + }, + Frame, Terminal, +}; +use std::{ + io, + time::{Duration, Instant}, +}; +use tokio::sync::mpsc; + +use crate::api::{ + Episode, HealthResource, HistoryItem, QueueItem, Series, SonarrClient, SystemStatus, +}; + +#[derive(Debug)] +pub enum AppEvent { + Tick, + Key(crossterm::event::KeyEvent), + Error(String), + SeriesLoaded(Vec), + EpisodesLoaded(Vec), + QueueLoaded(Vec), + HistoryLoaded(Vec), + SystemStatusLoaded(SystemStatus), + HealthLoaded(Vec), + CalendarLoaded(Vec), + SearchResults(Vec), +} + +#[derive(Debug, Clone, Copy, PartialEq)] +pub enum TabIndex { + Series, + Calendar, + Queue, + History, + Health, + Search, +} + +impl TabIndex { + fn titles() -> Vec<&'static str> { + vec!["Series", "Calendar", "Queue", "History", "Health", "Search"] + } + + fn from_index(index: usize) -> Self { + match index { + 0 => TabIndex::Series, + 1 => TabIndex::Calendar, + 2 => TabIndex::Queue, + 3 => TabIndex::History, + 4 => TabIndex::Health, + 5 => TabIndex::Search, + _ => TabIndex::Series, + } + } + + fn to_index(self) -> usize { + match self { + TabIndex::Series => 0, + TabIndex::Calendar => 1, + TabIndex::Queue => 2, + TabIndex::History => 3, + TabIndex::Health => 4, + TabIndex::Search => 5, + } + } +} + +pub struct App { + pub should_quit: bool, + pub current_tab: TabIndex, + pub series_list_state: ListState, + pub episodes_list_state: ListState, + pub queue_table_state: TableState, + pub history_table_state: TableState, + pub health_list_state: ListState, + pub search_list_state: ListState, + pub series: Vec, + pub episodes: Vec, + pub queue: Vec, + pub history: Vec, + pub health: Vec, + pub calendar: Vec, + pub system_status: Option, + pub selected_series: Option, + pub loading: bool, + pub error_message: Option, + pub search_input: String, + pub search_results: Vec, + pub search_mode: bool, + pub show_details: bool, + pub input_mode: bool, +} + +impl Default for App { + fn default() -> Self { + let mut app = Self { + should_quit: false, + current_tab: TabIndex::Series, + series_list_state: ListState::default(), + episodes_list_state: ListState::default(), + queue_table_state: TableState::default(), + history_table_state: TableState::default(), + health_list_state: ListState::default(), + search_list_state: ListState::default(), + series: Vec::new(), + episodes: Vec::new(), + queue: Vec::new(), + history: Vec::new(), + health: Vec::new(), + calendar: Vec::new(), + system_status: None, + selected_series: None, + loading: false, + error_message: None, + search_input: String::new(), + search_results: Vec::new(), + search_mode: false, + show_details: false, + input_mode: false, + }; + app.series_list_state.select(Some(0)); + app + } +} + +impl App { + pub fn next_tab(&mut self) { + let current_index = self.current_tab.to_index(); + let next_index = (current_index + 1) % TabIndex::titles().len(); + self.current_tab = TabIndex::from_index(next_index); + } + + pub fn previous_tab(&mut self) { + let current_index = self.current_tab.to_index(); + let prev_index = if current_index == 0 { + TabIndex::titles().len() - 1 + } else { + current_index - 1 + }; + self.current_tab = TabIndex::from_index(prev_index); + } + + pub fn next_item(&mut self) { + match self.current_tab { + TabIndex::Series => { + let len = self.series.len(); + if len > 0 { + let i = match self.series_list_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.series_list_state.select(Some(i)); + } + } + TabIndex::Calendar => { + let len = self.calendar.len(); + if len > 0 { + let i = match self.episodes_list_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.episodes_list_state.select(Some(i)); + } + } + TabIndex::Queue => { + let len = self.queue.len(); + if len > 0 { + let i = match self.queue_table_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.queue_table_state.select(Some(i)); + } + } + TabIndex::History => { + let len = self.history.len(); + if len > 0 { + let i = match self.history_table_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.history_table_state.select(Some(i)); + } + } + TabIndex::Health => { + let len = self.health.len(); + if len > 0 { + let i = match self.health_list_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.health_list_state.select(Some(i)); + } + } + TabIndex::Search => { + let len = self.search_results.len(); + if len > 0 { + let i = match self.search_list_state.selected() { + Some(i) => (i + 1) % len, + None => 0, + }; + self.search_list_state.select(Some(i)); + } + } + } + } + + pub fn previous_item(&mut self) { + match self.current_tab { + TabIndex::Series => { + let len = self.series.len(); + if len > 0 { + let i = match self.series_list_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.series_list_state.select(Some(i)); + } + } + TabIndex::Calendar => { + let len = self.calendar.len(); + if len > 0 { + let i = match self.episodes_list_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.episodes_list_state.select(Some(i)); + } + } + TabIndex::Queue => { + let len = self.queue.len(); + if len > 0 { + let i = match self.queue_table_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.queue_table_state.select(Some(i)); + } + } + TabIndex::History => { + let len = self.history.len(); + if len > 0 { + let i = match self.history_table_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.history_table_state.select(Some(i)); + } + } + TabIndex::Health => { + let len = self.health.len(); + if len > 0 { + let i = match self.health_list_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.health_list_state.select(Some(i)); + } + } + TabIndex::Search => { + let len = self.search_results.len(); + if len > 0 { + let i = match self.search_list_state.selected() { + Some(i) => { + if i == 0 { + len - 1 + } else { + i - 1 + } + } + None => 0, + }; + self.search_list_state.select(Some(i)); + } + } + } + } + + pub fn get_selected_series(&self) -> Option<&Series> { + if let Some(index) = self.series_list_state.selected() { + self.series.get(index) + } else { + None + } + } + + pub fn get_selected_search_result(&self) -> Option<&Series> { + if let Some(index) = self.search_list_state.selected() { + self.search_results.get(index) + } else { + None + } + } + + pub fn enter_search_mode(&mut self) { + self.search_mode = true; + self.input_mode = true; + self.search_input.clear(); + self.search_results.clear(); + self.search_list_state.select(None); + } + + pub fn exit_search_mode(&mut self) { + self.search_mode = false; + self.input_mode = false; + self.search_input.clear(); + self.search_results.clear(); + } + + pub fn toggle_details(&mut self) { + self.show_details = !self.show_details; + } + + pub fn clear_error(&mut self) { + self.error_message = None; + } + + pub fn set_error(&mut self, error: String) { + self.error_message = Some(error); + } +} + +pub async fn run_app(client: SonarrClient) -> Result<(), Box> { + // Setup terminal + enable_raw_mode()?; + let mut stdout = io::stdout(); + execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?; + let backend = CrosstermBackend::new(stdout); + let mut terminal = Terminal::new(backend)?; + + // Create app and run it + let mut app = App::default(); + let res = run_tui(&mut terminal, &mut app, client).await; + + // Restore terminal + disable_raw_mode()?; + execute!( + terminal.backend_mut(), + LeaveAlternateScreen, + DisableMouseCapture + )?; + terminal.show_cursor()?; + + res +} + +async fn run_tui( + terminal: &mut Terminal, + app: &mut App, + client: SonarrClient, +) -> Result<(), Box> { + let (tx, mut rx) = mpsc::unbounded_channel(); + + // Spawn task to handle keyboard input + let tx_input = tx.clone(); + tokio::spawn(async move { + let mut last_tick = Instant::now(); + let tick_rate = Duration::from_millis(250); + + loop { + let timeout = tick_rate + .checked_sub(last_tick.elapsed()) + .unwrap_or_else(|| Duration::from_secs(0)); + + if event::poll(timeout).unwrap() { + if let Event::Key(key) = event::read().unwrap() { + if key.kind == KeyEventKind::Press { + if tx_input.send(AppEvent::Key(key)).is_err() { + return; + } + } + } + } + + if last_tick.elapsed() >= tick_rate { + if tx_input.send(AppEvent::Tick).is_err() { + return; + } + last_tick = Instant::now(); + } + } + }); + + // Load initial data + load_all_data(client.clone(), tx.clone()).await; + + // Main event loop + while !app.should_quit { + terminal.draw(|f| ui(f, app))?; + + if let Some(event) = rx.recv().await { + match event { + AppEvent::Key(key) => { + handle_input(app, key, client.clone(), tx.clone()).await; + } + AppEvent::Tick => { + // Handle periodic updates if needed + } + AppEvent::Error(err) => { + app.set_error(err); + app.loading = false; + } + AppEvent::SeriesLoaded(series) => { + app.series = series; + app.loading = false; + if !app.series.is_empty() && app.series_list_state.selected().is_none() { + app.series_list_state.select(Some(0)); + } + } + AppEvent::EpisodesLoaded(episodes) => { + app.episodes = episodes; + app.loading = false; + } + AppEvent::QueueLoaded(queue) => { + app.queue = queue; + app.loading = false; + } + AppEvent::HistoryLoaded(history) => { + app.history = history; + app.loading = false; + } + AppEvent::SystemStatusLoaded(status) => { + app.system_status = Some(status); + app.loading = false; + } + AppEvent::HealthLoaded(health) => { + app.health = health; + app.loading = false; + } + AppEvent::CalendarLoaded(calendar) => { + app.calendar = calendar; + app.loading = false; + } + AppEvent::SearchResults(results) => { + app.search_results = results; + app.loading = false; + if !app.search_results.is_empty() { + app.search_list_state.select(Some(0)); + } + } + } + } + } + + Ok(()) +} + +async fn load_all_data(client: SonarrClient, tx: mpsc::UnboundedSender) { + // Load system status + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.get_system_status().await { + Ok(status) => { + let _ = tx_clone.send(AppEvent::SystemStatusLoaded(status)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!( + "Failed to load system status: {}", + e + ))); + } + } + }); + + // Load series + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.get_series().await { + Ok(series) => { + let _ = tx_clone.send(AppEvent::SeriesLoaded(series)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!("Failed to load series: {}", e))); + } + } + }); + + // Load queue + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.get_queue().await { + Ok(queue_data) => { + let _ = tx_clone.send(AppEvent::QueueLoaded(queue_data.records)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!("Failed to load queue: {}", e))); + } + } + }); + + // Load history + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.get_history().await { + Ok(history_data) => { + let _ = tx_clone.send(AppEvent::HistoryLoaded(history_data.records)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!("Failed to load history: {}", e))); + } + } + }); + + // Load health + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.get_health().await { + Ok(health) => { + let _ = tx_clone.send(AppEvent::HealthLoaded(health)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!("Failed to load health: {}", e))); + } + } + }); + + // Load calendar (upcoming episodes) + let tx_clone = tx; + tokio::spawn(async move { + let start = chrono::Utc::now().format("%Y-%m-%d").to_string(); + let end = (chrono::Utc::now() + chrono::Duration::days(7)) + .format("%Y-%m-%d") + .to_string(); + + match client.get_calendar(Some(&start), Some(&end)).await { + Ok(calendar) => { + let _ = tx_clone.send(AppEvent::CalendarLoaded(calendar)); + } + Err(e) => { + let _ = tx_clone.send(AppEvent::Error(format!("Failed to load calendar: {}", e))); + } + } + }); +} + +async fn handle_input( + app: &mut App, + key: crossterm::event::KeyEvent, + client: SonarrClient, + tx: mpsc::UnboundedSender, +) { + if app.input_mode { + match key.code { + KeyCode::Enter => { + if !app.search_input.is_empty() { + app.loading = true; + let search_term = app.search_input.clone(); + let client_clone = client.clone(); + let tx_clone = tx.clone(); + tokio::spawn(async move { + match client_clone.search_series(&search_term).await { + Ok(results) => { + let _ = tx_clone.send(AppEvent::SearchResults(results)); + } + Err(e) => { + let _ = + tx_clone.send(AppEvent::Error(format!("Search failed: {}", e))); + } + } + }); + } + app.input_mode = false; + } + KeyCode::Esc => { + app.exit_search_mode(); + } + KeyCode::Char(c) => { + app.search_input.push(c); + } + KeyCode::Backspace => { + app.search_input.pop(); + } + _ => {} + } + } else { + match key.code { + KeyCode::Char('q') => app.should_quit = true, + KeyCode::Tab => app.next_tab(), + KeyCode::BackTab => app.previous_tab(), + KeyCode::Down | KeyCode::Char('j') => app.next_item(), + KeyCode::Up | KeyCode::Char('k') => app.previous_item(), + KeyCode::Char('d') => app.toggle_details(), + KeyCode::Char('r') => { + app.loading = true; + app.clear_error(); + load_all_data(client, tx); + } + KeyCode::Char('/') => { + if app.current_tab == TabIndex::Search { + app.enter_search_mode(); + } + } + KeyCode::Esc => { + app.clear_error(); + if app.search_mode { + app.exit_search_mode(); + } + } + _ => {} + } + } +} + +fn ui(f: &mut Frame, app: &App) { + let size = f.size(); + + // Create main layout + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Length(3), // Header + Constraint::Min(0), // Main content + Constraint::Length(3), // Footer + ]) + .split(size); + + // Render header + render_header(f, chunks[0], app); + + // Render main content based on current tab + match app.current_tab { + TabIndex::Series => render_series_tab(f, chunks[1], app), + TabIndex::Calendar => render_calendar_tab(f, chunks[1], app), + TabIndex::Queue => render_queue_tab(f, chunks[1], app), + TabIndex::History => render_history_tab(f, chunks[1], app), + TabIndex::Health => render_health_tab(f, chunks[1], app), + TabIndex::Search => render_search_tab(f, chunks[1], app), + } + + // Render footer + render_footer(f, chunks[2], app); + + // Render error popup if there's an error + if app.error_message.is_some() { + render_error_popup(f, size, app); + } +} + +fn render_header(f: &mut Frame, area: Rect, app: &App) { + let tabs = Tabs::new(TabIndex::titles()) + .block( + Block::default() + .borders(Borders::ALL) + .title("Yarr - Sonarr TUI"), + ) + .style(Style::default().fg(Color::White)) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ) + .select(app.current_tab.to_index()); + + f.render_widget(tabs, area); +} + +fn render_series_tab(f: &mut Frame, area: Rect, app: &App) { + if app.series.is_empty() { + let loading_text = if app.loading { + "Loading series..." + } else { + "No series found" + }; + let paragraph = Paragraph::new(loading_text) + .block(Block::default().borders(Borders::ALL).title("Series")) + .alignment(Alignment::Center); + f.render_widget(paragraph, area); + return; + } + + let items: Vec = app + .series + .iter() + .map(|s| { + let title = s.title.as_deref().unwrap_or("Unknown"); + let status = &s.status; + let monitored = if s.monitored { "✓" } else { "✗" }; + + let stats = s + .statistics + .as_ref() + .map(|stats| format!(" ({}/{})", stats.episode_file_count, stats.episode_count)) + .unwrap_or_default(); + + ListItem::new(format!("{} {} [{}]{}", monitored, title, status, stats)) + }) + .collect(); + + let list = List::new(items) + .block(Block::default().borders(Borders::ALL).title("Series")) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ); + + f.render_stateful_widget(list, area, &mut app.series_list_state.clone()); +} + +fn render_calendar_tab(f: &mut Frame, area: Rect, app: &App) { + if app.calendar.is_empty() { + let loading_text = if app.loading { + "Loading calendar..." + } else { + "No upcoming episodes" + }; + let paragraph = Paragraph::new(loading_text) + .block( + Block::default() + .borders(Borders::ALL) + .title("Upcoming Episodes"), + ) + .alignment(Alignment::Center); + f.render_widget(paragraph, area); + return; + } + + let items: Vec = app + .calendar + .iter() + .map(|e| { + let title = e.title.as_deref().unwrap_or("Unknown Episode"); + let series_title = e + .series + .as_ref() + .and_then(|s| s.title.as_deref()) + .unwrap_or("Unknown Series"); + let air_date = e + .air_date_utc + .map(|dt| dt.format("%Y-%m-%d %H:%M").to_string()) + .or_else(|| e.air_date.clone()) + .unwrap_or_default(); + + ListItem::new(format!( + "S{:02}E{:02} {} - {} [{}]", + e.season_number, e.episode_number, series_title, title, air_date + )) + }) + .collect(); + + let list = List::new(items) + .block( + Block::default() + .borders(Borders::ALL) + .title("Upcoming Episodes (Next 7 Days)"), + ) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ); + + f.render_stateful_widget(list, area, &mut app.episodes_list_state.clone()); +} + +fn render_queue_tab(f: &mut Frame, area: Rect, app: &App) { + if app.queue.is_empty() { + let loading_text = if app.loading { + "Loading queue..." + } else { + "Queue is empty" + }; + let paragraph = Paragraph::new(loading_text) + .block( + Block::default() + .borders(Borders::ALL) + .title("Download Queue"), + ) + .alignment(Alignment::Center); + f.render_widget(paragraph, area); + return; + } + + let header = Row::new(vec!["Title", "Status", "Progress", "Quality", "Size"]); + let rows: Vec = app + .queue + .iter() + .map(|q| { + let title = q.title.as_deref().unwrap_or("Unknown"); + let status = &q.status; + let quality = q + .quality + .as_ref() + .and_then(|qual| qual.quality.name.as_deref()) + .unwrap_or("Unknown"); + let size = format!("{:.1} GB", q.size / 1_000_000_000.0); + + // Simple progress calculation (this would need more sophisticated logic in real implementation) + let progress = "50%"; // Placeholder + + Row::new(vec![ + Cell::from(title), + Cell::from(status), + Cell::from(progress), + Cell::from(quality), + Cell::from(size), + ]) + }) + .collect(); + + let table = Table::new(rows) + .header(header.style(Style::default().fg(Color::Yellow))) + .block( + Block::default() + .borders(Borders::ALL) + .title("Download Queue"), + ) + .widths(&[ + Constraint::Percentage(40), + Constraint::Percentage(15), + Constraint::Percentage(15), + Constraint::Percentage(15), + Constraint::Percentage(15), + ]) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ); + + f.render_stateful_widget(table, area, &mut app.queue_table_state.clone()); +} + +fn render_history_tab(f: &mut Frame, area: Rect, app: &App) { + if app.history.is_empty() { + let loading_text = if app.loading { + "Loading history..." + } else { + "No history found" + }; + let paragraph = Paragraph::new(loading_text) + .block(Block::default().borders(Borders::ALL).title("History")) + .alignment(Alignment::Center); + f.render_widget(paragraph, area); + return; + } + + let header = Row::new(vec!["Date", "Series", "Episode", "Event", "Quality"]); + let rows: Vec = app + .history + .iter() + .map(|h| { + let date = h.date.format("%Y-%m-%d %H:%M").to_string(); + let series = h + .series + .as_ref() + .and_then(|s| s.title.as_deref()) + .unwrap_or("Unknown"); + let episode = h + .episode + .as_ref() + .map(|e| format!("S{:02}E{:02}", e.season_number, e.episode_number)) + .unwrap_or_default(); + let event = &h.event_type; + let quality = h + .quality + .as_ref() + .and_then(|q| q.quality.name.as_deref()) + .unwrap_or("Unknown"); + + Row::new(vec![ + Cell::from(date), + Cell::from(series), + Cell::from(episode), + Cell::from(event), + Cell::from(quality), + ]) + }) + .collect(); + + let table = Table::new(rows) + .header(header.style(Style::default().fg(Color::Yellow))) + .block(Block::default().borders(Borders::ALL).title("History")) + .widths(&[ + Constraint::Percentage(20), + Constraint::Percentage(30), + Constraint::Percentage(15), + Constraint::Percentage(20), + Constraint::Percentage(15), + ]) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ); + + f.render_stateful_widget(table, area, &mut app.history_table_state.clone()); +} + +fn render_health_tab(f: &mut Frame, area: Rect, app: &App) { + if app.health.is_empty() { + let loading_text = if app.loading { + "Loading health status..." + } else { + "All systems healthy" + }; + let paragraph = Paragraph::new(loading_text) + .block( + Block::default() + .borders(Borders::ALL) + .title("Health Status"), + ) + .alignment(Alignment::Center) + .style(Style::default().fg(Color::Green)); + f.render_widget(paragraph, area); + return; + } + + let items: Vec = app + .health + .iter() + .map(|h| { + let source = h.source.as_deref().unwrap_or("System"); + let message = h.message.as_deref().unwrap_or("No message"); + let health_type = &h.health_type; + + let color = match health_type.as_str() { + "error" => Color::Red, + "warning" => Color::Yellow, + "notice" => Color::Blue, + _ => Color::Green, + }; + + ListItem::new(format!( + "[{}] {}: {}", + health_type.to_uppercase(), + source, + message + )) + .style(Style::default().fg(color)) + }) + .collect(); + + let list = List::new(items) + .block( + Block::default() + .borders(Borders::ALL) + .title("Health Status"), + ) + .highlight_style(Style::default().add_modifier(Modifier::BOLD)); + + f.render_stateful_widget(list, area, &mut app.health_list_state.clone()); +} + +fn render_search_tab(f: &mut Frame, area: Rect, app: &App) { + let chunks = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Length(3), Constraint::Min(0)]) + .split(area); + + // Search input + let input_style = if app.input_mode { + Style::default().fg(Color::Yellow) + } else { + Style::default() + }; + + let input = Paragraph::new(app.search_input.as_str()) + .style(input_style) + .block( + Block::default() + .borders(Borders::ALL) + .title("Search Series (Press '/' to search, Enter to execute)"), + ); + f.render_widget(input, chunks[0]); + + // Search results + if app.search_results.is_empty() { + let text = if app.loading { + "Searching..." + } else if app.search_input.is_empty() { + "Enter a search term and press Enter" + } else { + "No results found" + }; + + let paragraph = Paragraph::new(text) + .block( + Block::default() + .borders(Borders::ALL) + .title("Search Results"), + ) + .alignment(Alignment::Center); + f.render_widget(paragraph, chunks[1]); + } else { + let items: Vec = app + .search_results + .iter() + .map(|s| { + let title = s.title.as_deref().unwrap_or("Unknown"); + let year = s.year; + let network = s.network.as_deref().unwrap_or("Unknown Network"); + let overview = s.overview.as_deref().unwrap_or(""); + let truncated_overview = if overview.len() > 80 { + format!("{}...", &overview[..77]) + } else { + overview.to_string() + }; + + ListItem::new(format!( + "{} ({}) - {} | {}", + title, year, network, truncated_overview + )) + }) + .collect(); + + let list = List::new(items) + .block( + Block::default() + .borders(Borders::ALL) + .title("Search Results"), + ) + .highlight_style( + Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD), + ); + + f.render_stateful_widget(list, chunks[1], &mut app.search_list_state.clone()); + } +} + +fn render_footer(f: &mut Frame, area: Rect, app: &App) { + let help_text = if app.input_mode { + "ESC: Cancel | Enter: Search | Type to enter search term" + } else { + "q: Quit | Tab: Next Tab | ↑↓/jk: Navigate | d: Details | r: Refresh | /: Search (in Search tab)" + }; + + let mut spans = vec![Span::raw(help_text)]; + + if let Some(status) = &app.system_status { + spans.push(Span::raw(" | ")); + spans.push(Span::styled( + format!("Sonarr v{}", status.version.as_deref().unwrap_or("Unknown")), + Style::default().fg(Color::Green), + )); + } + + if app.loading { + spans.push(Span::raw(" | ")); + spans.push(Span::styled( + "Loading...", + Style::default().fg(Color::Yellow), + )); + } + + let paragraph = Paragraph::new(Line::from(spans)) + .block(Block::default().borders(Borders::ALL)) + .alignment(Alignment::Center); + + f.render_widget(paragraph, area); +} + +fn render_error_popup(f: &mut Frame, area: Rect, app: &App) { + if let Some(error) = &app.error_message { + let popup_area = centered_rect(60, 20, area); + + f.render_widget(Clear, popup_area); + + let error_paragraph = Paragraph::new(error.as_str()) + .block( + Block::default() + .borders(Borders::ALL) + .title("Error") + .style(Style::default().fg(Color::Red)), + ) + .wrap(Wrap { trim: true }) + .alignment(Alignment::Center); + + f.render_widget(error_paragraph, popup_area); + } +} + +fn centered_rect(percent_x: u16, percent_y: u16, r: Rect) -> Rect { + let popup_layout = Layout::default() + .direction(Direction::Vertical) + .constraints([ + Constraint::Percentage((100 - percent_y) / 2), + Constraint::Percentage(percent_y), + Constraint::Percentage((100 - percent_y) / 2), + ]) + .split(r); + + Layout::default() + .direction(Direction::Horizontal) + .constraints([ + Constraint::Percentage((100 - percent_x) / 2), + Constraint::Percentage(percent_x), + Constraint::Percentage((100 - percent_x) / 2), + ]) + .split(popup_layout[1])[1] +}