From ab13fb6e99d61c312580d38a70759dd135438dd0 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 8 Oct 2024 23:24:51 +0300 Subject: [PATCH 001/579] Fix index variable in fuse worker --- frontend/src/Components/Page/Header/fuse.worker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/Page/Header/fuse.worker.js b/frontend/src/Components/Page/Header/fuse.worker.js index ba592e7b6d..04e84185f2 100644 --- a/frontend/src/Components/Page/Header/fuse.worker.js +++ b/frontend/src/Components/Page/Header/fuse.worker.js @@ -34,7 +34,7 @@ function getSuggestions(movies, value) { key: 'title' } ], - arrayIndex: 0 + refIndex: 0 }); if (suggestions.length > limit) { break; From beeb5204b825f669083cfff56e6a581d0737b5b5 Mon Sep 17 00:00:00 2001 From: Vincent Caron Date: Tue, 8 Oct 2024 17:49:55 +0200 Subject: [PATCH 002/579] New: Parse IMDB and TMDB URLs as search terms --- .../SkyHook/SkyHookProxySearchFixture.cs | 4 ++++ .../MetadataSource/SkyHook/SkyHookProxy.cs | 15 +++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs index 4ae0b066d7..2371d7fb57 100644 --- a/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs +++ b/src/NzbDrone.Core.Test/MetadataSource/SkyHook/SkyHookProxySearchFixture.cs @@ -23,6 +23,8 @@ public void Setup() // [TestCase("The Man from U.N.C.L.E.", "The Man from U.N.C.L.E.")] [TestCase("imdb:tt2527336", "Star Wars: The Last Jedi")] [TestCase("imdb:tt2798920", "Annihilation")] + [TestCase("https://www.imdb.com/title/tt0033467/", "Citizen Kane")] + [TestCase("https://www.themoviedb.org/movie/775-le-voyage-dans-la-lune", "A Trip to the Moon")] public void successful_search(string title, string expected) { var result = Subject.SearchForNewMovie(title); @@ -41,6 +43,8 @@ public void successful_search(string title, string expected) [TestCase("tmdbid:1")] [TestCase("adjalkwdjkalwdjklawjdlKAJD;EF")] [TestCase("imdb: tt9805708")] + [TestCase("https://www.UNKNOWN-DOMAIN.com/title/tt0033467/")] + [TestCase("https://www.themoviedb.org/MALFORMED/775-le-voyage-dans-la-lune")] public void no_search_result(string term) { var result = Subject.SearchForNewMovie(term); diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index df46ed115c..2cf794c878 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Net; +using System.Text.RegularExpressions; using Newtonsoft.Json; using NLog; using NzbDrone.Common.Cloud; @@ -405,6 +406,20 @@ public List SearchForNewMovie(string title) { try { + var match = new Regex("^https://www.imdb.com/title/(tt[0-9]+).*?$").Match(title); + if (match.Success) + { + title = "imdb:" + match.Groups[1].Value; + } + else + { + match = new Regex("^https://www.themoviedb.org/movie/([0-9]+).*$").Match(title); + if (match.Success) + { + title = "tmdb:" + match.Groups[1].Value; + } + } + var lowerTitle = title.ToLower(); lowerTitle = lowerTitle.Replace(".", ""); From 0a7607bb62b26ecec2fff09bd7f48e1a55144437 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 00:42:09 +0300 Subject: [PATCH 003/579] Bump dotnet packages --- src/NzbDrone.Common/Radarr.Common.csproj | 4 ++-- src/NzbDrone.Core/Radarr.Core.csproj | 8 ++++---- .../Radarr.Integration.Test.csproj | 2 +- src/NzbDrone.Test.Common/Radarr.Test.Common.csproj | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Common/Radarr.Common.csproj b/src/NzbDrone.Common/Radarr.Common.csproj index f0065b3e34..02944054d3 100644 --- a/src/NzbDrone.Common/Radarr.Common.csproj +++ b/src/NzbDrone.Common/Radarr.Common.csproj @@ -12,11 +12,11 @@ - + - + diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 8b68ac511b..33f37e0a5d 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -7,13 +7,13 @@ - - + + - + @@ -25,7 +25,7 @@ - + diff --git a/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj b/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj index cafaa7575d..6d4c694f56 100644 --- a/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj +++ b/src/NzbDrone.Integration.Test/Radarr.Integration.Test.csproj @@ -4,7 +4,7 @@ Library - + diff --git a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj index b52876d1be..6496d4b058 100644 --- a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj @@ -3,7 +3,7 @@ net6.0 - + From 7912a942f71256efde95d715474a950248267357 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 01:48:36 +0300 Subject: [PATCH 004/579] Bump frontend packages --- package.json | 74 +- yarn.lock | 2139 ++++++++++++++++++++++++-------------------------- 2 files changed, 1081 insertions(+), 1132 deletions(-) diff --git a/package.json b/package.json index 17a5fe5490..64553d56c8 100644 --- a/package.json +++ b/package.json @@ -22,36 +22,36 @@ "defaults" ], "dependencies": { - "@fortawesome/fontawesome-free": "6.4.0", - "@fortawesome/fontawesome-svg-core": "6.4.0", + "@fortawesome/fontawesome-free": "6.6.0", + "@fortawesome/fontawesome-svg-core": "6.6.0", "@fortawesome/free-brands-svg-icons": "6.6.0", - "@fortawesome/free-regular-svg-icons": "6.4.0", - "@fortawesome/free-solid-svg-icons": "6.4.0", - "@fortawesome/react-fontawesome": "0.2.0", + "@fortawesome/free-regular-svg-icons": "6.6.0", + "@fortawesome/free-solid-svg-icons": "6.6.0", + "@fortawesome/react-fontawesome": "0.2.2", "@juggle/resize-observer": "3.4.0", "@microsoft/signalr": "6.0.25", - "@sentry/browser": "7.100.0", - "@sentry/integrations": "7.100.0", - "@types/node": "18.19.31", + "@sentry/browser": "7.119.1", + "@sentry/integrations": "7.119.1", + "@types/node": "20.16.11", "@types/react": "18.2.79", "@types/react-dom": "18.2.25", - "classnames": "2.3.2", + "classnames": "2.5.1", "connected-react-router": "6.9.3", "copy-to-clipboard": "3.3.3", "element-class": "0.2.2", - "filesize": "10.0.7", + "filesize": "10.1.6", "fuse.js": "6.6.2", "history": "4.10.1", "https-browserify": "1.0.0", "jdu": "1.0.0", - "jquery": "3.7.0", + "jquery": "3.7.1", "lodash": "4.17.21", "mobile-detect": "1.4.5", - "moment": "2.29.4", + "moment": "2.30.1", "mousetrap": "1.6.5", "normalize.css": "8.0.1", "prop-types": "15.8.1", - "qs": "6.11.1", + "qs": "6.13.0", "react": "17.0.2", "react-addons-shallow-compare": "15.6.3", "react-async-script": "1.2.0", @@ -88,45 +88,45 @@ "typescript": "5.1.6" }, "devDependencies": { - "@babel/core": "7.25.2", - "@babel/eslint-parser": "7.25.1", - "@babel/plugin-proposal-export-default-from": "7.24.7", + "@babel/core": "7.25.7", + "@babel/eslint-parser": "7.25.7", + "@babel/plugin-proposal-export-default-from": "7.25.7", "@babel/plugin-syntax-dynamic-import": "7.8.3", - "@babel/preset-env": "7.25.3", - "@babel/preset-react": "7.24.7", - "@babel/preset-typescript": "7.24.7", + "@babel/preset-env": "7.25.7", + "@babel/preset-react": "7.25.7", + "@babel/preset-typescript": "7.25.7", "@types/lodash": "4.14.195", - "@types/react-lazyload": "3.2.0", + "@types/react-lazyload": "3.2.3", "@types/react-router-dom": "5.3.3", - "@types/react-text-truncate": "0.14.1", - "@types/react-window": "1.8.5", - "@types/redux-actions": "2.6.2", - "@types/webpack-livereload-plugin": "2.3.3", + "@types/react-text-truncate": "0.19.0", + "@types/react-window": "1.8.8", + "@types/redux-actions": "2.6.5", + "@types/webpack-livereload-plugin": "2.3.6", "@typescript-eslint/eslint-plugin": "6.21.0", "@typescript-eslint/parser": "6.21.0", "autoprefixer": "10.4.20", - "babel-loader": "9.1.3", + "babel-loader": "9.2.1", "babel-plugin-inline-classnames": "2.0.1", "babel-plugin-transform-react-remove-prop-types": "0.4.24", "core-js": "3.38.1", "css-loader": "6.7.3", "css-modules-typescript-loader": "4.0.1", - "eslint": "8.57.0", + "eslint": "8.57.1", "eslint-config-prettier": "8.10.0", "eslint-plugin-filenames": "1.3.2", - "eslint-plugin-import": "2.29.1", + "eslint-plugin-import": "2.31.0", "eslint-plugin-json": "3.1.0", "eslint-plugin-prettier": "4.2.1", - "eslint-plugin-react": "7.34.1", - "eslint-plugin-react-hooks": "4.6.0", - "eslint-plugin-simple-import-sort": "12.1.0", + "eslint-plugin-react": "7.37.1", + "eslint-plugin-react-hooks": "4.6.2", + "eslint-plugin-simple-import-sort": "12.1.1", "file-loader": "6.2.0", "filemanager-webpack-plugin": "8.0.0", "fork-ts-checker-webpack-plugin": "8.0.0", - "html-webpack-plugin": "5.5.3", + "html-webpack-plugin": "5.6.0", "loader-utils": "^3.2.1", - "mini-css-extract-plugin": "2.7.6", - "postcss": "8.4.41", + "mini-css-extract-plugin": "2.9.1", + "postcss": "8.4.47", "postcss-color-function": "4.1.0", "postcss-loader": "7.3.0", "postcss-mixins": "9.0.4", @@ -140,12 +140,12 @@ "streamqueue": "1.1.2", "style-loader": "3.3.2", "stylelint": "15.6.1", - "stylelint-order": "6.0.3", - "terser-webpack-plugin": "5.3.9", - "ts-loader": "9.4.2", + "stylelint-order": "6.0.4", + "terser-webpack-plugin": "5.3.10", + "ts-loader": "9.5.1", "typescript-plugin-css-modules": "5.0.1", "url-loader": "4.1.1", - "webpack": "5.88.2", + "webpack": "5.95.0", "webpack-cli": "5.1.4", "webpack-livereload-plugin": "3.0.2", "worker-loader": "3.0.8" diff --git a/yarn.lock b/yarn.lock index 735aac2e38..56028eb8d7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,105 +15,105 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.24.7.tgz#882fd9e09e8ee324e496bd040401c6f046ef4465" - integrity sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" + integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== dependencies: - "@babel/highlight" "^7.24.7" + "@babel/highlight" "^7.25.7" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.2": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.4.tgz#7d2a80ce229890edcf4cc259d4d696cb4dae2fcb" - integrity sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ== +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.7.tgz#b8479fe0018ef0ac87b6b7a5c6916fcd67ae2c9c" + integrity sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw== -"@babel/core@7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.2.tgz#ed8eec275118d7613e77a352894cd12ded8eba77" - integrity sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA== +"@babel/core@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.7.tgz#1b3d144157575daf132a3bc80b2b18e6e3ca6ece" + integrity sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.0" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-module-transforms" "^7.25.2" - "@babel/helpers" "^7.25.0" - "@babel/parser" "^7.25.0" - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.2" - "@babel/types" "^7.25.2" + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helpers" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.1.tgz#469cee4bd18a88ff3edbdfbd227bd20e82aa9b82" - integrity sha512-Y956ghgTT4j7rKesabkh5WeqgSFZVFwaPR0IWFm7KFHFmmJ4afbG49SmfW4S+GyRPx0Dy5jxEWA5t0rpxfElWg== +"@babel/eslint-parser@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.7.tgz#27b43de786c83cbabbcb328efbb4f099ae85415e" + integrity sha512-B+BO9x86VYsQHimucBAL1fxTJKF4wyKY6ZVzee9QgzdZOUfs3BaR6AQrgoGrRI+7IFS1wUz/VyQ+SoBcSpdPbw== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@^7.25.0", "@babel/generator@^7.25.4": - version "7.25.5" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.5.tgz#b31cf05b3fe8c32d206b6dad03bb0aacbde73450" - integrity sha512-abd43wyLfbWoxC6ahM8xTkqLpGB2iWBVyuKC9/srhFunCd1SDNrV1s72bBpK4hLj8KLzHBBcOblvLQZBNw9r3w== +"@babel/generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" + integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== dependencies: - "@babel/types" "^7.25.4" + "@babel/types" "^7.25.7" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" - jsesc "^2.5.1" + jsesc "^3.0.2" -"@babel/helper-annotate-as-pure@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.24.7.tgz#5373c7bc8366b12a033b4be1ac13a206c6656aab" - integrity sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg== +"@babel/helper-annotate-as-pure@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.7.tgz#63f02dbfa1f7cb75a9bdb832f300582f30bb8972" + integrity sha512-4xwU8StnqnlIhhioZf1tqnVWeQ9pvH/ujS8hRfw/WOza+/a+1qv69BWNy+oY231maTCWgKWhfBU7kDpsds6zAA== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.25.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.24.7.tgz#37d66feb012024f2422b762b9b2a7cfe27c7fba3" - integrity sha512-xZeCVVdwb4MsDBkkyZ64tReWYrLRHlMN72vP7Bdm3OUOuyFZExhsHUUnuWnm2/XOlAJzR0LfPpB56WXZn0X/lA== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz#d721650c1f595371e0a23ee816f1c3c488c0d622" + integrity sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.24.7", "@babel/helper-compilation-targets@^7.24.8", "@babel/helper-compilation-targets@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.2.tgz#e1d9410a90974a3a5a66e84ff55ef62e3c02d06c" - integrity sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw== +"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4" + integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A== dependencies: - "@babel/compat-data" "^7.25.2" - "@babel/helper-validator-option" "^7.24.8" - browserslist "^4.23.1" + "@babel/compat-data" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + browserslist "^4.24.0" lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.24.7", "@babel/helper-create-class-features-plugin@^7.25.0", "@babel/helper-create-class-features-plugin@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.4.tgz#57eaf1af38be4224a9d9dd01ddde05b741f50e14" - integrity sha512-ro/bFs3/84MDgDmMwbcHgDa8/E6J3QKNTk4xJJnVeFtGE+tL0K26E3pNxhYz2b67fJpt7Aphw5XcploKXuCvCQ== +"@babel/helper-create-class-features-plugin@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz#5d65074c76cae75607421c00d6bd517fe1892d6b" + integrity sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-member-expression-to-functions" "^7.24.8" - "@babel/helper-optimise-call-expression" "^7.24.7" - "@babel/helper-replace-supers" "^7.25.0" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/traverse" "^7.25.4" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-member-expression-to-functions" "^7.25.7" + "@babel/helper-optimise-call-expression" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/traverse" "^7.25.7" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.24.7", "@babel/helper-create-regexp-features-plugin@^7.25.0", "@babel/helper-create-regexp-features-plugin@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.2.tgz#24c75974ed74183797ffd5f134169316cd1808d9" - integrity sha512-+wqVGP+DFmqwFD3EH6TMTfUNeqDehV3E/dl+Sd54eaXqm17tEUNbEIn4sVivVowbvUpOtIGxdo3GoXyDH9N/9g== +"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz#dcb464f0e2cdfe0c25cc2a0a59c37ab940ce894e" + integrity sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - regexpu-core "^5.3.1" + "@babel/helper-annotate-as-pure" "^7.25.7" + regexpu-core "^6.1.1" semver "^6.3.1" "@babel/helper-define-polyfill-provider@^0.6.2": @@ -127,173 +127,173 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-member-expression-to-functions@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.24.8.tgz#6155e079c913357d24a4c20480db7c712a5c3fb6" - integrity sha512-LABppdt+Lp/RlBxqrh4qgf1oEH/WxdzQNDJIu5gC/W1GyvPVrOBiItmmM8wan2fm4oYqFuFfkXmlGpLQhPY8CA== +"@babel/helper-member-expression-to-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz#541a33b071f0355a63a0fa4bdf9ac360116b8574" + integrity sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA== dependencies: - "@babel/traverse" "^7.24.8" - "@babel/types" "^7.24.8" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helper-module-imports@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz#f2f980392de5b84c3328fc71d38bd81bbb83042b" - integrity sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA== +"@babel/helper-module-imports@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" + integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helper-module-transforms@^7.24.7", "@babel/helper-module-transforms@^7.24.8", "@babel/helper-module-transforms@^7.25.0", "@babel/helper-module-transforms@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.2.tgz#ee713c29768100f2776edf04d4eb23b8d27a66e6" - integrity sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ== +"@babel/helper-module-transforms@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a" + integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ== dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-simple-access" "^7.24.7" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.2" + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-simple-access" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/helper-optimise-call-expression@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.24.7.tgz#8b0a0456c92f6b323d27cfd00d1d664e76692a0f" - integrity sha512-jKiTsW2xmWwxT1ixIdfXUZp+P5yURx2suzLZr5Hi64rURpDYdMW0pv+Uf17EYk2Rd428Lx4tLsnjGJzYKDM/6A== +"@babel/helper-optimise-call-expression@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz#1de1b99688e987af723eed44fa7fc0ee7b97d77a" + integrity sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng== dependencies: - "@babel/types" "^7.24.7" + "@babel/types" "^7.25.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.24.7", "@babel/helper-plugin-utils@^7.24.8", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.8.tgz#94ee67e8ec0e5d44ea7baeb51e571bd26af07878" - integrity sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" + integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== -"@babel/helper-remap-async-to-generator@^7.24.7", "@babel/helper-remap-async-to-generator@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.0.tgz#d2f0fbba059a42d68e5e378feaf181ef6055365e" - integrity sha512-NhavI2eWEIz/H9dbrG0TuOicDhNexze43i5z7lEqwYm0WEZVTwnPpA0EafUTP7+6/W79HWIP2cTe3Z5NiSTVpw== +"@babel/helper-remap-async-to-generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz#9efdc39df5f489bcd15533c912b6c723a0a65021" + integrity sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-wrap-function" "^7.25.0" - "@babel/traverse" "^7.25.0" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-wrap-function" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/helper-replace-supers@^7.24.7", "@babel/helper-replace-supers@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.0.tgz#ff44deac1c9f619523fe2ca1fd650773792000a9" - integrity sha512-q688zIvQVYtZu+i2PsdIu/uWGRpfxzr5WESsfpShfZECkO+d2o+WROWezCi/Q6kJ0tfPa5+pUGUlfx2HhrA3Bg== +"@babel/helper-replace-supers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz#38cfda3b6e990879c71d08d0fef9236b62bd75f5" + integrity sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.24.8" - "@babel/helper-optimise-call-expression" "^7.24.7" - "@babel/traverse" "^7.25.0" + "@babel/helper-member-expression-to-functions" "^7.25.7" + "@babel/helper-optimise-call-expression" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/helper-simple-access@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz#bcade8da3aec8ed16b9c4953b74e506b51b5edb3" - integrity sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg== +"@babel/helper-simple-access@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0" + integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helper-skip-transparent-expression-wrappers@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.24.7.tgz#5f8fa83b69ed5c27adc56044f8be2b3ea96669d9" - integrity sha512-IO+DLT3LQUElMbpzlatRASEyQtfhSE0+m465v++3jyyXeBTBUjtVZg28/gHeV5mrTJqvEKhKroBGAvhW+qPHiQ== +"@babel/helper-skip-transparent-expression-wrappers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz#382831c91038b1a6d32643f5f49505b8442cb87c" + integrity sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA== dependencies: - "@babel/traverse" "^7.24.7" - "@babel/types" "^7.24.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helper-string-parser@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.24.8.tgz#5b3329c9a58803d5df425e5785865881a81ca48d" - integrity sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ== +"@babel/helper-string-parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" + integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== -"@babel/helper-validator-identifier@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz#75b889cfaf9e35c2aaf42cf0d72c8e91719251db" - integrity sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w== +"@babel/helper-validator-identifier@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" + integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== -"@babel/helper-validator-option@^7.24.7", "@babel/helper-validator-option@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.24.8.tgz#3725cdeea8b480e86d34df15304806a06975e33d" - integrity sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q== +"@babel/helper-validator-option@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729" + integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ== -"@babel/helper-wrap-function@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.0.tgz#dab12f0f593d6ca48c0062c28bcfb14ebe812f81" - integrity sha512-s6Q1ebqutSiZnEjaofc/UKDyC4SbzV5n5SrA2Gq8UawLycr3i04f1dX4OzoQVnexm6aOCh37SQNYlJ/8Ku+PMQ== +"@babel/helper-wrap-function@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz#9f6021dd1c4fdf4ad515c809967fc4bac9a70fe7" + integrity sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg== dependencies: - "@babel/template" "^7.25.0" - "@babel/traverse" "^7.25.0" - "@babel/types" "^7.25.0" + "@babel/template" "^7.25.7" + "@babel/traverse" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/helpers@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.0.tgz#e69beb7841cb93a6505531ede34f34e6a073650a" - integrity sha512-MjgLZ42aCm0oGjJj8CtSM3DB8NOOf8h2l7DCTePJs29u+v7yO/RBX9nShlKMgFnRks/Q4tBAe7Hxnov9VkGwLw== +"@babel/helpers@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2" + integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA== dependencies: - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.0" + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/highlight@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.24.7.tgz#a05ab1df134b286558aae0ed41e6c5f731bf409d" - integrity sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw== +"@babel/highlight@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.25.7.tgz#20383b5f442aa606e7b5e3043b0b1aafe9f37de5" + integrity sha512-iYyACpW3iW8Fw+ZybQK+drQre+ns/tKpXbNESfrhNnPLIklLbXr7MYJ6gPEd0iETGLOK+SxMjVvKb/ffmk+FEw== dependencies: - "@babel/helper-validator-identifier" "^7.24.7" + "@babel/helper-validator-identifier" "^7.25.7" chalk "^2.4.2" js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.25.0", "@babel/parser@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.4.tgz#af4f2df7d02440286b7de57b1c21acfb2a6f257a" - integrity sha512-nq+eWrOgdtu3jG5Os4TQP3x3cLA8hR8TvJNjD8vnPa20WGycimcparWnLK4jJhElTK6SDyuJo1weMKO/5LpmLA== +"@babel/parser@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" + integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== dependencies: - "@babel/types" "^7.25.4" + "@babel/types" "^7.25.7" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.3": - version "7.25.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.3.tgz#dca427b45a6c0f5c095a1c639dfe2476a3daba7f" - integrity sha512-wUrcsxZg6rqBXG05HG1FPYgsP6EvwF4WpBbxIpWIIYnH8wG0gzx3yZY3dtEHas4sTAOGkbTsc9EGPxwff8lRoA== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz#93969ac50ef4d68b2504b01b758af714e4cbdd64" + integrity sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.3" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.0.tgz#cd0c583e01369ef51676bdb3d7b603e17d2b3f73" - integrity sha512-Bm4bH2qsX880b/3ziJ8KD711LT7z4u8CFudmjqle65AZj/HNUFhEf90dqYv6O86buWvSBmeQDjv0Tn2aF/bIBA== +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz#a338d611adb9dcd599b8b1efa200c88ebeffe046" + integrity sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.0.tgz#749bde80356b295390954643de7635e0dffabe73" - integrity sha512-lXwdNZtTmeVOOFtwM/WDe7yg1PL8sYhRk/XH0FzbR2HDQ0xC+EnQ/JHeoMYSavtU115tnUk0q9CDyq8si+LMAA== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz#c5f755e911dfac7ef6957300c0f9c4a8c18c06f4" + integrity sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.24.7.tgz#e4eabdd5109acc399b38d7999b2ef66fc2022f89" - integrity sha512-+izXIbke1T33mY4MSNnrqhPXDz01WYhEf3yF5NbnUtkiNnm+XBZJl3kNfoK6NKmYlz/D07+l2GWVK/QfDkNCuQ== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz#3b7ea04492ded990978b6deaa1dfca120ad4455a" + integrity sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/plugin-transform-optional-chaining" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/plugin-transform-optional-chaining" "^7.25.7" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.0.tgz#3a82a70e7cb7294ad2559465ebcb871dfbf078fb" - integrity sha512-tggFrk1AIShG/RUQbEwt2Tr/E+ObkfwrPjR6BjbRvsx24+PSjK8zrq0GWPNCjo8qpRx4DuJzlcvWJqlm+0h3kw== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz#9622b1d597a703aa3a921e6f58c9c2d9a028d2c5" + integrity sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.0" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/plugin-proposal-export-default-from@7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.24.7.tgz#0b539c46b8ac804f694e338f803c8354c0f788b6" - integrity sha512-CcmFwUJ3tKhLjPdt4NP+SHMshebytF8ZTYOv5ZDpkzq2sin80Wb5vJrGt8fhPrORQCfoSa0LAxC/DW+GAC5+Hw== +"@babel/plugin-proposal-export-default-from@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.25.7.tgz#7ed72dbdc834bc841953858664008ad30a6653d3" + integrity sha512-Egdiuy7pLTyaPkIr6rItNyFVbblTmx3VgqY+72KiS9BzcA+SMyrS9zSumQeSANo8uE3Kax0ZUMkpNh0Q+mbNwg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/plugin-syntax-export-default-from" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/plugin-syntax-export-default-from" "^7.25.7" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" @@ -328,12 +328,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.24.7.tgz#85dae9098933573aae137fb52141dd3ca52ae7ac" - integrity sha512-bTPz4/635WQ9WhwsyPdxUJDVpsi/X9BMmy/8Rf/UAlOO4jSql4CxUCjWI5PiM+jG+c4LVPTScoTw80geFj9+Bw== +"@babel/plugin-syntax-export-default-from@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.25.7.tgz#3e05205c62303fe088f6b7073e5c143a669c26f4" + integrity sha512-LRUCsC0YucSjabsmxx6yly8+Q/5mxKdp9gemlpR9ro3bfpcOQOXx/CHivs7QCbjgygd6uQ2GcRfHu1FVax/hgg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-export-namespace-from@^7.8.3": version "7.8.3" @@ -342,19 +342,19 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-import-assertions@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.24.7.tgz#2a0b406b5871a20a841240586b1300ce2088a778" - integrity sha512-Ec3NRUMoi8gskrkBe3fNmEQfxDvY8bgfQpz6jlk/41kX9eUjvpyqWU7PBP/pLAvMaSQjbMNKJmvX57jP+M6bPg== +"@babel/plugin-syntax-import-assertions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f" + integrity sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-syntax-import-attributes@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.24.7.tgz#b4f9ea95a79e6912480c4b626739f86a076624ca" - integrity sha512-hbX+lKKeUMGihnK8nvKqmXBInriT3GVjzXKFriV3YC6APGxMbP8RZNFwy91+hocLXq90Mta+HshoB31802bb8A== +"@babel/plugin-syntax-import-attributes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f" + integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-import-meta@^7.10.4": version "7.10.4" @@ -370,12 +370,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-jsx@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz#39a1fa4a7e3d3d7f34e2acc6be585b718d30e02d" - integrity sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ== +"@babel/plugin-syntax-jsx@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165" + integrity sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-logical-assignment-operators@^7.10.4": version "7.10.4" @@ -433,12 +433,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-syntax-typescript@^7.24.7": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.4.tgz#04db9ce5a9043d9c635e75ae7969a2cd50ca97ff" - integrity sha512-uMOCoHVU52BsSWxPOMVv5qKRdeSlPuImUCB2dlPuBSU+W2/ROE7/Zg8F2Kepbk+8yBa68LlRKxO+xgEVWorsDg== +"@babel/plugin-syntax-typescript@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" + integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -448,465 +448,465 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.24.7.tgz#4f6886c11e423bd69f3ce51dbf42424a5f275514" - integrity sha512-Dt9LQs6iEY++gXUwY03DNFat5C2NbO48jj+j/bSAz6b3HgPs39qcPiYt77fDObIcFwj3/C2ICX9YMwGflUoSHQ== +"@babel/plugin-transform-arrow-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz#1b9ed22e6890a0e9ff470371c73b8c749bcec386" + integrity sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-async-generator-functions@^7.25.0": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.4.tgz#2afd4e639e2d055776c9f091b6c0c180ed8cf083" - integrity sha512-jz8cV2XDDTqjKPwVPJBIjORVEmSGYhdRa8e5k5+vN+uwcjSrSxUaebBRa4ko1jqNF2uxyg8G6XYk30Jv285xzg== +"@babel/plugin-transform-async-generator-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.7.tgz#af61a02b30d7bff5108c63bd39ac7938403426d7" + integrity sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-remap-async-to-generator" "^7.25.0" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-remap-async-to-generator" "^7.25.7" "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/traverse" "^7.25.4" + "@babel/traverse" "^7.25.7" -"@babel/plugin-transform-async-to-generator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.24.7.tgz#72a3af6c451d575842a7e9b5a02863414355bdcc" - integrity sha512-SQY01PcJfmQ+4Ash7NE+rpbLFbmqA2GPIgqzxfFTL4t1FKRq4zTms/7htKpoCUI9OcFYgzqfmCdH53s6/jn5fA== +"@babel/plugin-transform-async-to-generator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz#a44c7323f8d4285a6c568dd43c5c361d6367ec52" + integrity sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg== dependencies: - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-remap-async-to-generator" "^7.24.7" + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-remap-async-to-generator" "^7.25.7" -"@babel/plugin-transform-block-scoped-functions@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.24.7.tgz#a4251d98ea0c0f399dafe1a35801eaba455bbf1f" - integrity sha512-yO7RAz6EsVQDaBH18IDJcMB1HnrUn2FJ/Jslc/WtPPWcjhpUJXU/rjbwmluzp7v/ZzWcEhTMXELnnsz8djWDwQ== +"@babel/plugin-transform-block-scoped-functions@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz#e0b8843d5571719a2f1bf7e284117a3379fcc17c" + integrity sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-block-scoping@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.0.tgz#23a6ed92e6b006d26b1869b1c91d1b917c2ea2ac" - integrity sha512-yBQjYoOjXlFv9nlXb3f1casSHOZkWr29NX+zChVanLg5Nc157CrbEX9D7hxxtTpuFy7Q0YzmmWfJxzvps4kXrQ== +"@babel/plugin-transform-block-scoping@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz#6dab95e98adf780ceef1b1c3ab0e55cd20dd410a" + integrity sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-class-properties@^7.24.7": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.4.tgz#bae7dbfcdcc2e8667355cd1fb5eda298f05189fd" - integrity sha512-nZeZHyCWPfjkdU5pA/uHiTaDAFUEqkpzf1YoQT2NeSynCGYq9rxfyI3XpQbfx/a0hSnFH6TGlEXvae5Vi7GD8g== +"@babel/plugin-transform-class-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz#a389cfca7a10ac80e3ff4c75fca08bd097ad1523" + integrity sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.4" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-class-static-block@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.24.7.tgz#c82027ebb7010bc33c116d4b5044fbbf8c05484d" - integrity sha512-HMXK3WbBPpZQufbMG4B46A90PkuuhN9vBCb5T8+VAHqvAqvcLi+2cKoukcpmUYkszLhScU3l1iudhrks3DggRQ== +"@babel/plugin-transform-class-static-block@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz#d2cf3c812e3b3162d56aadf4566f45c30538cb2c" + integrity sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-transform-classes@^7.25.0": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.4.tgz#d29dbb6a72d79f359952ad0b66d88518d65ef89a" - integrity sha512-oexUfaQle2pF/b6E0dwsxQtAol9TLSO88kQvym6HHBWFliV2lGdrPieX+WgMRLSJDVzdYywk7jXbLPuO2KLTLg== +"@babel/plugin-transform-classes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz#5103206cf80d02283bbbd044509ea3b65d0906bb" + integrity sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-replace-supers" "^7.25.0" - "@babel/traverse" "^7.25.4" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" + "@babel/traverse" "^7.25.7" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.24.7.tgz#4cab3214e80bc71fae3853238d13d097b004c707" - integrity sha512-25cS7v+707Gu6Ds2oY6tCkUwsJ9YIDbggd9+cu9jzzDgiNq7hR/8dkzxWfKWnTic26vsI3EsCXNd4iEB6e8esQ== +"@babel/plugin-transform-computed-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz#7f621f0aa1354b5348a935ab12e3903842466f65" + integrity sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/template" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/template" "^7.25.7" -"@babel/plugin-transform-destructuring@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.24.8.tgz#c828e814dbe42a2718a838c2a2e16a408e055550" - integrity sha512-36e87mfY8TnRxc7yc6M9g9gOB7rKgSahqkIKwLpz4Ppk2+zC2Cy1is0uwtuSG6AE4zlTOUa+7JGz9jCJGLqQFQ== +"@babel/plugin-transform-destructuring@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz#f6f26a9feefb5aa41fd45b6f5838901b5333d560" + integrity sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-dotall-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.24.7.tgz#5f8bf8a680f2116a7207e16288a5f974ad47a7a0" - integrity sha512-ZOA3W+1RRTSWvyqcMJDLqbchh7U4NRGqwRfFSVbOLS/ePIP4vHB5e8T8eXcuqyN1QkgKyj5wuW0lcS85v4CrSw== +"@babel/plugin-transform-dotall-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz#9d775c4a3ff1aea64045300fcd4309b4a610ef02" + integrity sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-duplicate-keys@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.24.7.tgz#dd20102897c9a2324e5adfffb67ff3610359a8ee" - integrity sha512-JdYfXyCRihAe46jUIliuL2/s0x0wObgwwiGxw/UbgJBr20gQBThrokO4nYKgWkD7uBaqM7+9x5TU7NkExZJyzw== +"@babel/plugin-transform-duplicate-keys@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz#fbba7d1155eab76bd4f2a038cbd5d65883bd7a93" + integrity sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.0.tgz#809af7e3339466b49c034c683964ee8afb3e2604" - integrity sha512-YLpb4LlYSc3sCUa35un84poXoraOiQucUTTu8X1j18JV+gNa8E0nyUf/CjZ171IRGr4jEguF+vzJU66QZhn29g== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz#102b31608dcc22c08fbca1894e104686029dc141" + integrity sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-dynamic-import@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.24.7.tgz#4d8b95e3bae2b037673091aa09cd33fecd6419f4" - integrity sha512-sc3X26PhZQDb3JhORmakcbvkeInvxz+A8oda99lj7J60QRuPZvNAk9wQlTBS1ZynelDrDmTU4pw1tyc5d5ZMUg== +"@babel/plugin-transform-dynamic-import@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz#31905ab2cfa94dcf1b1f8ce66096720b2908e518" + integrity sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-dynamic-import" "^7.8.3" -"@babel/plugin-transform-exponentiation-operator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.24.7.tgz#b629ee22645f412024297d5245bce425c31f9b0d" - integrity sha512-Rqe/vSc9OYgDajNIK35u7ot+KeCoetqQYFXM4Epf7M7ez3lWlOjrDjrwMei6caCVhfdw+mIKD4cgdGNy5JQotQ== +"@babel/plugin-transform-exponentiation-operator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz#5961a3a23a398faccd6cddb34a2182807d75fb5f" + integrity sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-export-namespace-from@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.24.7.tgz#176d52d8d8ed516aeae7013ee9556d540c53f197" - integrity sha512-v0K9uNYsPL3oXZ/7F9NNIbAj2jv1whUEtyA6aujhekLs56R++JDQuzRcP2/z4WX5Vg/c5lE9uWZA0/iUoFhLTA== +"@babel/plugin-transform-export-namespace-from@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz#beb2679db6fd3bdfe6ad6de2c8cac84a86ef2da1" + integrity sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" -"@babel/plugin-transform-for-of@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.24.7.tgz#f25b33f72df1d8be76399e1b8f3f9d366eb5bc70" - integrity sha512-wo9ogrDG1ITTTBsy46oGiN1dS9A7MROBTcYsfS8DtsImMkHk9JXJ3EWQM6X2SUw4x80uGPlwj0o00Uoc6nEE3g== +"@babel/plugin-transform-for-of@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz#0acfea0f27aa290818b5b48a5a44b3f03fc13669" + integrity sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" -"@babel/plugin-transform-function-name@^7.25.1": - version "7.25.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.1.tgz#b85e773097526c1a4fc4ba27322748643f26fc37" - integrity sha512-TVVJVdW9RKMNgJJlLtHsKDTydjZAbwIsn6ySBPQaEAUU5+gVvlJt/9nRmqVbsV/IBanRjzWoaAQKLoamWVOUuA== +"@babel/plugin-transform-function-name@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz#7e394ccea3693902a8b50ded8b6ae1fa7b8519fd" + integrity sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ== dependencies: - "@babel/helper-compilation-targets" "^7.24.8" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/traverse" "^7.25.1" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/plugin-transform-json-strings@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.24.7.tgz#f3e9c37c0a373fee86e36880d45b3664cedaf73a" - integrity sha512-2yFnBGDvRuxAaE/f0vfBKvtnvvqU8tGpMHqMNpTN2oWMKIR3NqFkjaAgGwawhqK/pIN2T3XdjGPdaG0vDhOBGw== +"@babel/plugin-transform-json-strings@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz#6626433554aff4bd6f76a2c621a1f40e802dfb0a" + integrity sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-json-strings" "^7.8.3" -"@babel/plugin-transform-literals@^7.25.2": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.2.tgz#deb1ad14fc5490b9a65ed830e025bca849d8b5f3" - integrity sha512-HQI+HcTbm9ur3Z2DkO+jgESMAMcYLuN/A7NRw9juzxAezN9AvqvUTnpKP/9kkYANz6u7dFlAyOu44ejuGySlfw== +"@babel/plugin-transform-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz#70cbdc742f2cfdb1a63ea2cbd018d12a60b213c3" + integrity sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-logical-assignment-operators@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.24.7.tgz#a58fb6eda16c9dc8f9ff1c7b1ba6deb7f4694cb0" - integrity sha512-4D2tpwlQ1odXmTEIFWy9ELJcZHqrStlzK/dAOWYyxX3zT0iXQB6banjgeOJQXzEc4S0E0a5A+hahxPaEFYftsw== +"@babel/plugin-transform-logical-assignment-operators@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz#93847feb513a1f191c5f5d903d991a0ee24fe99b" + integrity sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" -"@babel/plugin-transform-member-expression-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.24.7.tgz#3b4454fb0e302e18ba4945ba3246acb1248315df" - integrity sha512-T/hRC1uqrzXMKLQ6UCwMT85S3EvqaBXDGf0FaMf4446Qx9vKwlghvee0+uuZcDUCZU5RuNi4781UQ7R308zzBw== +"@babel/plugin-transform-member-expression-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz#0a36c3fbd450cc9e6485c507f005fa3d1bc8fca5" + integrity sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-modules-amd@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.24.7.tgz#65090ed493c4a834976a3ca1cde776e6ccff32d7" - integrity sha512-9+pB1qxV3vs/8Hdmz/CulFB8w2tuu6EB94JZFsjdqxQokwGa9Unap7Bo2gGBGIvPmDIVvQrom7r5m/TCDMURhg== +"@babel/plugin-transform-modules-amd@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz#bb4e543b5611f6c8c685a2fd485408713a3adf3d" + integrity sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA== dependencies: - "@babel/helper-module-transforms" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-modules-commonjs@^7.24.7", "@babel/plugin-transform-modules-commonjs@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.24.8.tgz#ab6421e564b717cb475d6fff70ae7f103536ea3c" - integrity sha512-WHsk9H8XxRs3JXKWFiqtQebdh9b/pTk4EgueygFzYlTKAg0Ud985mSevdNjdXdFBATSKVJGQXP1tv6aGbssLKA== +"@babel/plugin-transform-modules-commonjs@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz#173f0c791bb7407c092ce6d77ee90eb3f2d1d2fd" + integrity sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg== dependencies: - "@babel/helper-module-transforms" "^7.24.8" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-simple-access" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-simple-access" "^7.25.7" -"@babel/plugin-transform-modules-systemjs@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.0.tgz#8f46cdc5f9e5af74f3bd019485a6cbe59685ea33" - integrity sha512-YPJfjQPDXxyQWg/0+jHKj1llnY5f/R6a0p/vP4lPymxLu7Lvl4k2WMitqi08yxwQcCVUUdG9LCUj4TNEgAp3Jw== +"@babel/plugin-transform-modules-systemjs@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz#8b14d319a177cc9c85ef8b0512afd429d9e2e60b" + integrity sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g== dependencies: - "@babel/helper-module-transforms" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" - "@babel/traverse" "^7.25.0" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" + "@babel/traverse" "^7.25.7" -"@babel/plugin-transform-modules-umd@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.24.7.tgz#edd9f43ec549099620df7df24e7ba13b5c76efc8" - integrity sha512-3aytQvqJ/h9z4g8AsKPLvD4Zqi2qT+L3j7XoFFu1XBlZWEl2/1kWnhmAbxpLgPrHSY0M6UA02jyTiwUVtiKR6A== +"@babel/plugin-transform-modules-umd@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz#00ee7a7e124289549381bfb0e24d87fd7f848367" + integrity sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw== dependencies: - "@babel/helper-module-transforms" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-module-transforms" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-named-capturing-groups-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.24.7.tgz#9042e9b856bc6b3688c0c2e4060e9e10b1460923" - integrity sha512-/jr7h/EWeJtk1U/uz2jlsCioHkZk1JJZVcc8oQsJ1dUlaJD83f4/6Zeh2aHt9BIFokHIsSeDfhUmju0+1GPd6g== +"@babel/plugin-transform-named-capturing-groups-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz#a2f3f6d7f38693b462542951748f0a72a34d196d" + integrity sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-new-target@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.24.7.tgz#31ff54c4e0555cc549d5816e4ab39241dfb6ab00" - integrity sha512-RNKwfRIXg4Ls/8mMTza5oPF5RkOW8Wy/WgMAp1/F1yZ8mMbtwXW+HDoJiOsagWrAhI5f57Vncrmr9XeT4CVapA== +"@babel/plugin-transform-new-target@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz#52b2bde523b76c548749f38dc3054f1f45e82bc9" + integrity sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-nullish-coalescing-operator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.24.7.tgz#1de4534c590af9596f53d67f52a92f12db984120" - integrity sha512-Ts7xQVk1OEocqzm8rHMXHlxvsfZ0cEF2yomUqpKENHWMF4zKk175Y4q8H5knJes6PgYad50uuRmt3UJuhBw8pQ== +"@babel/plugin-transform-nullish-coalescing-operator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz#0af84b86d4332654c43cf028dbdcf878b00ac168" + integrity sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.24.7.tgz#bea62b538c80605d8a0fac9b40f48e97efa7de63" - integrity sha512-e6q1TiVUzvH9KRvicuxdBTUj4AdKSRwzIyFFnfnezpCfP2/7Qmbb8qbU2j7GODbl4JMkblitCQjKYUaX/qkkwA== +"@babel/plugin-transform-numeric-separator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz#a516b78f894d1c08283f39d809b2048fd2f29448" + integrity sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.24.7.tgz#d13a2b93435aeb8a197e115221cab266ba6e55d6" - integrity sha512-4QrHAr0aXQCEFni2q4DqKLD31n2DL+RxcwnNjDFkSG0eNQ/xCavnRkfCUjsyqGC2OviNJvZOF/mQqZBw7i2C5Q== +"@babel/plugin-transform-object-rest-spread@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz#fa0916521be96fd434e2db59780b24b308c6d169" + integrity sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg== dependencies: - "@babel/helper-compilation-targets" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-transform-parameters" "^7.24.7" + "@babel/plugin-transform-parameters" "^7.25.7" -"@babel/plugin-transform-object-super@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.24.7.tgz#66eeaff7830bba945dd8989b632a40c04ed625be" - integrity sha512-A/vVLwN6lBrMFmMDmPPz0jnE6ZGx7Jq7d6sT/Ev4H65RER6pZ+kczlf1DthF5N0qaPHBsI7UXiE8Zy66nmAovg== +"@babel/plugin-transform-object-super@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz#582a9cea8cf0a1e02732be5b5a703a38dedf5661" + integrity sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-replace-supers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-replace-supers" "^7.25.7" -"@babel/plugin-transform-optional-catch-binding@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.24.7.tgz#00eabd883d0dd6a60c1c557548785919b6e717b4" - integrity sha512-uLEndKqP5BfBbC/5jTwPxLh9kqPWWgzN/f8w6UwAIirAEqiIVJWWY312X72Eub09g5KF9+Zn7+hT7sDxmhRuKA== +"@babel/plugin-transform-optional-catch-binding@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz#400e2d891f9288f5231694234696aa67164e4913" + integrity sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.24.7", "@babel/plugin-transform-optional-chaining@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.24.8.tgz#bb02a67b60ff0406085c13d104c99a835cdf365d" - integrity sha512-5cTOLSMs9eypEy8JUVvIKOu6NgvbJMnpG62VpIHrTmROdQ+L5mDAaI40g25k5vXti55JWNX5jCkq3HZxXBQANw== +"@babel/plugin-transform-optional-chaining@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz#b7f7c9321aa1d8414e67799c28d87c23682e4d68" + integrity sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" "@babel/plugin-syntax-optional-chaining" "^7.8.3" -"@babel/plugin-transform-parameters@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.24.7.tgz#5881f0ae21018400e320fc7eb817e529d1254b68" - integrity sha512-yGWW5Rr+sQOhK0Ot8hjDJuxU3XLRQGflvT4lhlSY0DFvdb3TwKaY26CJzHtYllU0vT9j58hc37ndFPsqT1SrzA== +"@babel/plugin-transform-parameters@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz#80c38b03ef580f6d6bffe1c5254bb35986859ac7" + integrity sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-private-methods@^7.24.7": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.4.tgz#9bbefbe3649f470d681997e0b64a4b254d877242" - integrity sha512-ao8BG7E2b/URaUQGqN3Tlsg+M3KlHY6rJ1O1gXAEUnZoyNQnvKyH87Kfg+FoxSeyWUB8ISZZsC91C44ZuBFytw== +"@babel/plugin-transform-private-methods@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz#c790a04f837b4bd61d6b0317b43aa11ff67dce80" + integrity sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.4" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-private-property-in-object@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.24.7.tgz#4eec6bc701288c1fab5f72e6a4bbc9d67faca061" - integrity sha512-9z76mxwnwFxMyxZWEgdgECQglF2Q7cFLm0kMf8pGwt+GSJsY0cONKj/UuO4bOH0w/uAel3ekS4ra5CEAyJRmDA== +"@babel/plugin-transform-private-property-in-object@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz#aff877efd05b57c4ad04611d8de97bf155a53369" + integrity sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-create-class-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" "@babel/plugin-syntax-private-property-in-object" "^7.14.5" -"@babel/plugin-transform-property-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.24.7.tgz#f0d2ed8380dfbed949c42d4d790266525d63bbdc" - integrity sha512-EMi4MLQSHfd2nrCqQEWxFdha2gBCqU4ZcCng4WBGZ5CJL4bBRW0ptdqqDdeirGZcpALazVVNJqRmsO8/+oNCBA== +"@babel/plugin-transform-property-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz#a8612b4ea4e10430f00012ecf0155662c7d6550d" + integrity sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-react-display-name@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.24.7.tgz#9caff79836803bc666bcfe210aeb6626230c293b" - integrity sha512-H/Snz9PFxKsS1JLI4dJLtnJgCJRoo0AUm3chP6NYr+9En1JMKloheEiLIhlp5MDVznWo+H3AAC1Mc8lmUEpsgg== +"@babel/plugin-transform-react-display-name@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.7.tgz#2753e875a1b702fb1d806c4f5d4c194d64cadd88" + integrity sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-react-jsx-development@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.24.7.tgz#eaee12f15a93f6496d852509a850085e6361470b" - integrity sha512-QG9EnzoGn+Qar7rxuW+ZOsbWOt56FvvI93xInqsZDC5fsekx1AlIO4KIJ5M+D0p0SqSH156EpmZyXq630B8OlQ== +"@babel/plugin-transform-react-jsx-development@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.7.tgz#2fbd77887b8fa2942d7cb61edf1029ea1b048554" + integrity sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg== dependencies: - "@babel/plugin-transform-react-jsx" "^7.24.7" + "@babel/plugin-transform-react-jsx" "^7.25.7" -"@babel/plugin-transform-react-jsx@^7.24.7": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.2.tgz#e37e8ebfa77e9f0b16ba07fadcb6adb47412227a" - integrity sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA== +"@babel/plugin-transform-react-jsx@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.7.tgz#f5e2af6020a562fe048dd343e571c4428e6c5632" + integrity sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-module-imports" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/plugin-syntax-jsx" "^7.24.7" - "@babel/types" "^7.25.2" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-module-imports" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/plugin-syntax-jsx" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/plugin-transform-react-pure-annotations@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.24.7.tgz#bdd9d140d1c318b4f28b29a00fb94f97ecab1595" - integrity sha512-PLgBVk3fzbmEjBJ/u8kFzOqS9tUeDjiaWud/rRym/yjCo/M9cASPlnrd2ZmmZpQT40fOOrvR8jh+n8jikrOhNA== +"@babel/plugin-transform-react-pure-annotations@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.7.tgz#6d0b8dadb2d3c5cbb8ade68c5efd49470b0d65f7" + integrity sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-regenerator@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.24.7.tgz#021562de4534d8b4b1851759fd7af4e05d2c47f8" - integrity sha512-lq3fvXPdimDrlg6LWBoqj+r/DEWgONuwjuOuQCSYgRroXDH/IdM1C0IZf59fL5cHLpjEH/O6opIRBbqv7ELnuA== +"@babel/plugin-transform-regenerator@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz#6eb006e6d26f627bc2f7844a9f19770721ad6f3e" + integrity sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.24.7.tgz#80037fe4fbf031fc1125022178ff3938bb3743a4" - integrity sha512-0DUq0pHcPKbjFZCfTss/pGkYMfy3vFWydkUBd9r0GHpIyfs2eCDENvqadMycRS9wZCXR41wucAfJHJmwA0UmoQ== +"@babel/plugin-transform-reserved-words@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz#dc56b25e02afaabef3ce0c5b06b0916e8523e995" + integrity sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-shorthand-properties@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.24.7.tgz#85448c6b996e122fa9e289746140aaa99da64e73" - integrity sha512-KsDsevZMDsigzbA09+vacnLpmPH4aWjcZjXdyFKGzpplxhbeB4wYtury3vglQkg6KM/xEPKt73eCjPPf1PgXBA== +"@babel/plugin-transform-shorthand-properties@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz#92690a9c671915602d91533c278cc8f6bf12275f" + integrity sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-spread@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.24.7.tgz#e8a38c0fde7882e0fb8f160378f74bd885cc7bb3" - integrity sha512-x96oO0I09dgMDxJaANcRyD4ellXFLLiWhuwDxKZX5g2rWP1bTPkBSwCYv96VDXVT1bD9aPj8tppr5ITIh8hBng== +"@babel/plugin-transform-spread@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz#df83e899a9fc66284ee601a7b738568435b92998" + integrity sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" -"@babel/plugin-transform-sticky-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.24.7.tgz#96ae80d7a7e5251f657b5cf18f1ea6bf926f5feb" - integrity sha512-kHPSIJc9v24zEml5geKg9Mjx5ULpfncj0wRpYtxbvKyTtHCYDkVE3aHQ03FrpEo4gEe2vrJJS1Y9CJTaThA52g== +"@babel/plugin-transform-sticky-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz#341c7002bef7f29037be7fb9684e374442dd0d17" + integrity sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-template-literals@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.24.7.tgz#a05debb4a9072ae8f985bcf77f3f215434c8f8c8" - integrity sha512-AfDTQmClklHCOLxtGoP7HkeMw56k1/bTQjwsfhL6pppo/M4TOBSq+jjBUBLmV/4oeFg4GWMavIl44ZeCtmmZTw== +"@babel/plugin-transform-template-literals@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz#e566c581bb16d8541dd8701093bb3457adfce16b" + integrity sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-typeof-symbol@^7.24.8": - version "7.24.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.24.8.tgz#383dab37fb073f5bfe6e60c654caac309f92ba1c" - integrity sha512-adNTUpDCVnmAE58VEqKlAA6ZBlNkMnWD0ZcW76lyNFN3MJniyGFZfNwERVk8Ap56MCnXztmDr19T4mPTztcuaw== +"@babel/plugin-transform-typeof-symbol@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz#debb1287182efd20488f126be343328c679b66eb" + integrity sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA== dependencies: - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-typescript@^7.24.7": - version "7.25.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.2.tgz#237c5d10de6d493be31637c6b9fa30b6c5461add" - integrity sha512-lBwRvjSmqiMYe/pS0+1gggjJleUJi7NzjvQ1Fkqtt69hBa/0t1YuW/MLQMAPixfwaQOHUXsd6jeU3Z+vdGv3+A== +"@babel/plugin-transform-typescript@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.7.tgz#8fc7c3d28ddd36bce45b9b48594129d0e560cfbe" + integrity sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q== dependencies: - "@babel/helper-annotate-as-pure" "^7.24.7" - "@babel/helper-create-class-features-plugin" "^7.25.0" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-skip-transparent-expression-wrappers" "^7.24.7" - "@babel/plugin-syntax-typescript" "^7.24.7" + "@babel/helper-annotate-as-pure" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/plugin-syntax-typescript" "^7.25.7" -"@babel/plugin-transform-unicode-escapes@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.24.7.tgz#2023a82ced1fb4971630a2e079764502c4148e0e" - integrity sha512-U3ap1gm5+4edc2Q/P+9VrBNhGkfnf+8ZqppY71Bo/pzZmXhhLdqgaUl6cuB07O1+AQJtCLfaOmswiNbSQ9ivhw== +"@babel/plugin-transform-unicode-escapes@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz#973592b6d13a914794e1de8cf1383e50e0f87f81" + integrity sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-unicode-property-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.24.7.tgz#9073a4cd13b86ea71c3264659590ac086605bbcd" - integrity sha512-uH2O4OV5M9FZYQrwc7NdVmMxQJOCCzFeYudlZSzUAHRFeOujQefa92E74TQDVskNHCzOXoigEuoyzHDhaEaK5w== +"@babel/plugin-transform-unicode-property-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz#25349197cce964b1343f74fa7cfdf791a1b1919e" + integrity sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-unicode-regex@^7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.24.7.tgz#dfc3d4a51127108099b19817c0963be6a2adf19f" - integrity sha512-hlQ96MBZSAXUq7ltkjtu3FJCCSMx/j629ns3hA3pXnBXjanNP0LHi+JpPeA81zaWgVK1VGH95Xuy7u0RyQ8kMg== +"@babel/plugin-transform-unicode-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz#f93a93441baf61f713b6d5552aaa856bfab34809" + integrity sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.24.7" - "@babel/helper-plugin-utils" "^7.24.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-unicode-sets-regex@^7.24.7": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.4.tgz#be664c2a0697ffacd3423595d5edef6049e8946c" - integrity sha512-qesBxiWkgN1Q+31xUE9RcMk79eOXXDCv6tfyGMRSs4RGlioSg2WVyQAm07k726cSE56pa+Kb0y9epX2qaXzTvA== +"@babel/plugin-transform-unicode-sets-regex@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz#d1b3295d29e0f8f4df76abc909ad1ebee919560c" + integrity sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" + "@babel/helper-create-regexp-features-plugin" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" -"@babel/preset-env@7.25.3": - version "7.25.3" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.3.tgz#0bf4769d84ac51d1073ab4a86f00f30a3a83c67c" - integrity sha512-QsYW7UeAaXvLPX9tdVliMJE7MD7M6MLYVTovRTIwhoYQVFHR1rM4wO8wqAezYi3/BpSD+NzVCZ69R6smWiIi8g== +"@babel/preset-env@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.7.tgz#fc1b092152db4b58377b85dc05c890081c1157e0" + integrity sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g== dependencies: - "@babel/compat-data" "^7.25.2" - "@babel/helper-compilation-targets" "^7.25.2" - "@babel/helper-plugin-utils" "^7.24.8" - "@babel/helper-validator-option" "^7.24.8" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.3" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.0" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.0" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.24.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.0" + "@babel/compat-data" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.7" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.7" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.7" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/plugin-syntax-class-properties" "^7.12.13" "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-import-assertions" "^7.24.7" - "@babel/plugin-syntax-import-attributes" "^7.24.7" + "@babel/plugin-syntax-import-assertions" "^7.25.7" + "@babel/plugin-syntax-import-attributes" "^7.25.7" "@babel/plugin-syntax-import-meta" "^7.10.4" "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" @@ -918,60 +918,60 @@ "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.24.7" - "@babel/plugin-transform-async-generator-functions" "^7.25.0" - "@babel/plugin-transform-async-to-generator" "^7.24.7" - "@babel/plugin-transform-block-scoped-functions" "^7.24.7" - "@babel/plugin-transform-block-scoping" "^7.25.0" - "@babel/plugin-transform-class-properties" "^7.24.7" - "@babel/plugin-transform-class-static-block" "^7.24.7" - "@babel/plugin-transform-classes" "^7.25.0" - "@babel/plugin-transform-computed-properties" "^7.24.7" - "@babel/plugin-transform-destructuring" "^7.24.8" - "@babel/plugin-transform-dotall-regex" "^7.24.7" - "@babel/plugin-transform-duplicate-keys" "^7.24.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.0" - "@babel/plugin-transform-dynamic-import" "^7.24.7" - "@babel/plugin-transform-exponentiation-operator" "^7.24.7" - "@babel/plugin-transform-export-namespace-from" "^7.24.7" - "@babel/plugin-transform-for-of" "^7.24.7" - "@babel/plugin-transform-function-name" "^7.25.1" - "@babel/plugin-transform-json-strings" "^7.24.7" - "@babel/plugin-transform-literals" "^7.25.2" - "@babel/plugin-transform-logical-assignment-operators" "^7.24.7" - "@babel/plugin-transform-member-expression-literals" "^7.24.7" - "@babel/plugin-transform-modules-amd" "^7.24.7" - "@babel/plugin-transform-modules-commonjs" "^7.24.8" - "@babel/plugin-transform-modules-systemjs" "^7.25.0" - "@babel/plugin-transform-modules-umd" "^7.24.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.24.7" - "@babel/plugin-transform-new-target" "^7.24.7" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.24.7" - "@babel/plugin-transform-numeric-separator" "^7.24.7" - "@babel/plugin-transform-object-rest-spread" "^7.24.7" - "@babel/plugin-transform-object-super" "^7.24.7" - "@babel/plugin-transform-optional-catch-binding" "^7.24.7" - "@babel/plugin-transform-optional-chaining" "^7.24.8" - "@babel/plugin-transform-parameters" "^7.24.7" - "@babel/plugin-transform-private-methods" "^7.24.7" - "@babel/plugin-transform-private-property-in-object" "^7.24.7" - "@babel/plugin-transform-property-literals" "^7.24.7" - "@babel/plugin-transform-regenerator" "^7.24.7" - "@babel/plugin-transform-reserved-words" "^7.24.7" - "@babel/plugin-transform-shorthand-properties" "^7.24.7" - "@babel/plugin-transform-spread" "^7.24.7" - "@babel/plugin-transform-sticky-regex" "^7.24.7" - "@babel/plugin-transform-template-literals" "^7.24.7" - "@babel/plugin-transform-typeof-symbol" "^7.24.8" - "@babel/plugin-transform-unicode-escapes" "^7.24.7" - "@babel/plugin-transform-unicode-property-regex" "^7.24.7" - "@babel/plugin-transform-unicode-regex" "^7.24.7" - "@babel/plugin-transform-unicode-sets-regex" "^7.24.7" + "@babel/plugin-transform-arrow-functions" "^7.25.7" + "@babel/plugin-transform-async-generator-functions" "^7.25.7" + "@babel/plugin-transform-async-to-generator" "^7.25.7" + "@babel/plugin-transform-block-scoped-functions" "^7.25.7" + "@babel/plugin-transform-block-scoping" "^7.25.7" + "@babel/plugin-transform-class-properties" "^7.25.7" + "@babel/plugin-transform-class-static-block" "^7.25.7" + "@babel/plugin-transform-classes" "^7.25.7" + "@babel/plugin-transform-computed-properties" "^7.25.7" + "@babel/plugin-transform-destructuring" "^7.25.7" + "@babel/plugin-transform-dotall-regex" "^7.25.7" + "@babel/plugin-transform-duplicate-keys" "^7.25.7" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7" + "@babel/plugin-transform-dynamic-import" "^7.25.7" + "@babel/plugin-transform-exponentiation-operator" "^7.25.7" + "@babel/plugin-transform-export-namespace-from" "^7.25.7" + "@babel/plugin-transform-for-of" "^7.25.7" + "@babel/plugin-transform-function-name" "^7.25.7" + "@babel/plugin-transform-json-strings" "^7.25.7" + "@babel/plugin-transform-literals" "^7.25.7" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.7" + "@babel/plugin-transform-member-expression-literals" "^7.25.7" + "@babel/plugin-transform-modules-amd" "^7.25.7" + "@babel/plugin-transform-modules-commonjs" "^7.25.7" + "@babel/plugin-transform-modules-systemjs" "^7.25.7" + "@babel/plugin-transform-modules-umd" "^7.25.7" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7" + "@babel/plugin-transform-new-target" "^7.25.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.7" + "@babel/plugin-transform-numeric-separator" "^7.25.7" + "@babel/plugin-transform-object-rest-spread" "^7.25.7" + "@babel/plugin-transform-object-super" "^7.25.7" + "@babel/plugin-transform-optional-catch-binding" "^7.25.7" + "@babel/plugin-transform-optional-chaining" "^7.25.7" + "@babel/plugin-transform-parameters" "^7.25.7" + "@babel/plugin-transform-private-methods" "^7.25.7" + "@babel/plugin-transform-private-property-in-object" "^7.25.7" + "@babel/plugin-transform-property-literals" "^7.25.7" + "@babel/plugin-transform-regenerator" "^7.25.7" + "@babel/plugin-transform-reserved-words" "^7.25.7" + "@babel/plugin-transform-shorthand-properties" "^7.25.7" + "@babel/plugin-transform-spread" "^7.25.7" + "@babel/plugin-transform-sticky-regex" "^7.25.7" + "@babel/plugin-transform-template-literals" "^7.25.7" + "@babel/plugin-transform-typeof-symbol" "^7.25.7" + "@babel/plugin-transform-unicode-escapes" "^7.25.7" + "@babel/plugin-transform-unicode-property-regex" "^7.25.7" + "@babel/plugin-transform-unicode-regex" "^7.25.7" + "@babel/plugin-transform-unicode-sets-regex" "^7.25.7" "@babel/preset-modules" "0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2 "^0.4.10" - babel-plugin-polyfill-corejs3 "^0.10.4" + babel-plugin-polyfill-corejs3 "^0.10.6" babel-plugin-polyfill-regenerator "^0.6.1" - core-js-compat "^3.37.1" + core-js-compat "^3.38.1" semver "^6.3.1" "@babel/preset-modules@0.1.6-no-external-plugins": @@ -983,70 +983,65 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.24.7.tgz#480aeb389b2a798880bf1f889199e3641cbb22dc" - integrity sha512-AAH4lEkpmzFWrGVlHaxJB7RLH21uPQ9+He+eFLWHmF9IuFQVugz8eAsamaW0DXRrTfco5zj1wWtpdcXJUOfsag== +"@babel/preset-react@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.7.tgz#081cbe1dea363b732764d06a0fdda67ffa17735d" + integrity sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" - "@babel/plugin-transform-react-display-name" "^7.24.7" - "@babel/plugin-transform-react-jsx" "^7.24.7" - "@babel/plugin-transform-react-jsx-development" "^7.24.7" - "@babel/plugin-transform-react-pure-annotations" "^7.24.7" + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-transform-react-display-name" "^7.25.7" + "@babel/plugin-transform-react-jsx" "^7.25.7" + "@babel/plugin-transform-react-jsx-development" "^7.25.7" + "@babel/plugin-transform-react-pure-annotations" "^7.25.7" -"@babel/preset-typescript@7.24.7": - version "7.24.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.24.7.tgz#66cd86ea8f8c014855671d5ea9a737139cbbfef1" - integrity sha512-SyXRe3OdWwIwalxDg5UtJnJQO+YPcTfwiIY2B0Xlddh9o7jpWLvv8X1RthIeDOxQ+O1ML5BLPCONToObyVQVuQ== +"@babel/preset-typescript@7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.25.7.tgz#43c5b68eccb856ae5b52274b77b1c3c413cde1b7" + integrity sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw== dependencies: - "@babel/helper-plugin-utils" "^7.24.7" - "@babel/helper-validator-option" "^7.24.7" - "@babel/plugin-syntax-jsx" "^7.24.7" - "@babel/plugin-transform-modules-commonjs" "^7.24.7" - "@babel/plugin-transform-typescript" "^7.24.7" - -"@babel/regjsgen@^0.8.0": - version "0.8.0" - resolved "https://registry.yarnpkg.com/@babel/regjsgen/-/regjsgen-0.8.0.tgz#f0ba69b075e1f05fb2825b7fad991e7adbb18310" - integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== + "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-validator-option" "^7.25.7" + "@babel/plugin-syntax-jsx" "^7.25.7" + "@babel/plugin-transform-modules-commonjs" "^7.25.7" + "@babel/plugin-transform-typescript" "^7.25.7" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.4.tgz#6ef37d678428306e7d75f054d5b1bdb8cf8aa8ee" - integrity sha512-DSgLeL/FNcpXuzav5wfYvHCGvynXkJbn3Zvc3823AEe9nPwW9IK4UoCSS5yGymmQzN0pCPvivtgS6/8U2kkm1w== + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.25.7.tgz#7ffb53c37a8f247c8c4d335e89cdf16a2e0d0fb6" + integrity sha512-FjoyLe754PMiYsFaN5C94ttGiOmBNYTf6pLr4xXHAT5uctHb092PBszndLDR5XA/jghQvn4n7JMHl7dmTgbm9w== dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.24.7", "@babel/template@^7.25.0": - version "7.25.0" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.0.tgz#e733dc3134b4fede528c15bc95e89cb98c52592a" - integrity sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q== +"@babel/template@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" + integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/parser" "^7.25.0" - "@babel/types" "^7.25.0" + "@babel/code-frame" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/types" "^7.25.7" -"@babel/traverse@^7.24.7", "@babel/traverse@^7.24.8", "@babel/traverse@^7.25.0", "@babel/traverse@^7.25.1", "@babel/traverse@^7.25.2", "@babel/traverse@^7.25.3", "@babel/traverse@^7.25.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.4.tgz#648678046990f2957407e3086e97044f13c3e18e" - integrity sha512-VJ4XsrD+nOvlXyLzmLzUs/0qjFS4sK30te5yEFlvbbUNEgKaVb2BHZUpAL+ttLPQAHNrsI3zZisbfha5Cvr8vg== +"@babel/traverse@^7.25.7": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" + integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== dependencies: - "@babel/code-frame" "^7.24.7" - "@babel/generator" "^7.25.4" - "@babel/parser" "^7.25.4" - "@babel/template" "^7.25.0" - "@babel/types" "^7.25.4" + "@babel/code-frame" "^7.25.7" + "@babel/generator" "^7.25.7" + "@babel/parser" "^7.25.7" + "@babel/template" "^7.25.7" + "@babel/types" "^7.25.7" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.24.7", "@babel/types@^7.24.8", "@babel/types@^7.25.0", "@babel/types@^7.25.2", "@babel/types@^7.25.4", "@babel/types@^7.4.4": - version "7.25.4" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.4.tgz#6bcb46c72fdf1012a209d016c07f769e10adcb5f" - integrity sha512-zQ1ijeeCXVEh+aNL0RlmkPkG8HUiDcU2pzQQFjtbntgAczRASFzj4H+6+bV+dy1ntKR14I/DypeuRG1uma98iQ== +"@babel/types@^7.25.7", "@babel/types@^7.4.4": + version "7.25.7" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" + integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== dependencies: - "@babel/helper-string-parser" "^7.24.8" - "@babel/helper-validator-identifier" "^7.24.7" + "@babel/helper-string-parser" "^7.25.7" + "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" "@csstools/css-parser-algorithms@^2.1.1": @@ -1082,9 +1077,9 @@ eslint-visitor-keys "^3.3.0" "@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": - version "4.11.0" - resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.0.tgz#b0ffd0312b4a3fd2d6f77237e7248a5ad3a680ae" - integrity sha512-G/M/tIiMrTAxEWRfLfQJMmGNX28IxBg4PBz8XqQhqUHLFI6TL2htpIB1iQCj144V5ee/JaKyT9/WZ0MGZWfA7A== + version "4.11.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" + integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== "@eslint/eslintrc@^2.1.4": version "2.1.4" @@ -1101,32 +1096,27 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@eslint/js@8.57.0": - version "8.57.0" - resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.0.tgz#a5417ae8427873f1dd08b70b3574b453e67b5f7f" - integrity sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g== - -"@fortawesome/fontawesome-common-types@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.4.0.tgz#88da2b70d6ca18aaa6ed3687832e11f39e80624b" - integrity sha512-HNii132xfomg5QVZw0HwXXpN22s7VBHQBv9CeOu9tfJnhsWQNd2lmTNi8CSrnw5B+5YOmzu1UoPAyxaXsJ6RgQ== +"@eslint/js@8.57.1": + version "8.57.1" + resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" + integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== "@fortawesome/fontawesome-common-types@6.6.0": version "6.6.0" resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz#31ab07ca6a06358c5de4d295d4711b675006163f" integrity sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw== -"@fortawesome/fontawesome-free@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.4.0.tgz#1ee0c174e472c84b23cb46c995154dc383e3b4fe" - integrity sha512-0NyytTlPJwB/BF5LtRV8rrABDbe3TdTXqNB3PdZ+UUUZAEIrdOJdmABqKjt4AXwIoJNaRVVZEXxpNrqvE1GAYQ== +"@fortawesome/fontawesome-free@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz#0e984f0f2344ee513c185d87d77defac4c0c8224" + integrity sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow== -"@fortawesome/fontawesome-svg-core@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.4.0.tgz#3727552eff9179506e9203d72feb5b1063c11a21" - integrity sha512-Bertv8xOiVELz5raB2FlXDPKt+m94MQ3JgDfsVbrqNpLU9+UE2E18GKjLKw+d3XbeYPqg1pzyQKGsrzbw+pPaw== +"@fortawesome/fontawesome-svg-core@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz#2a24c32ef92136e98eae2ff334a27145188295ff" + integrity sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg== dependencies: - "@fortawesome/fontawesome-common-types" "6.4.0" + "@fortawesome/fontawesome-common-types" "6.6.0" "@fortawesome/free-brands-svg-icons@6.6.0": version "6.6.0" @@ -1135,33 +1125,33 @@ dependencies: "@fortawesome/fontawesome-common-types" "6.6.0" -"@fortawesome/free-regular-svg-icons@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.4.0.tgz#cacc53bd8d832d46feead412d9ea9ce80a55e13a" - integrity sha512-ZfycI7D0KWPZtf7wtMFnQxs8qjBXArRzczABuMQqecA/nXohquJ5J/RCR77PmY5qGWkxAZDxpnUFVXKwtY/jPw== +"@fortawesome/free-regular-svg-icons@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz#fc49a947ac8dfd20403c9ea5f37f0919425bdf04" + integrity sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ== dependencies: - "@fortawesome/fontawesome-common-types" "6.4.0" + "@fortawesome/fontawesome-common-types" "6.6.0" -"@fortawesome/free-solid-svg-icons@6.4.0": - version "6.4.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.4.0.tgz#48c0e790847fa56299e2f26b82b39663b8ad7119" - integrity sha512-kutPeRGWm8V5dltFP1zGjQOEAzaLZj4StdQhWVZnfGFCvAPVvHh8qk5bRrU4KXnRRRNni5tKQI9PBAdI6MP8nQ== +"@fortawesome/free-solid-svg-icons@6.6.0": + version "6.6.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b" + integrity sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA== dependencies: - "@fortawesome/fontawesome-common-types" "6.4.0" + "@fortawesome/fontawesome-common-types" "6.6.0" -"@fortawesome/react-fontawesome@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.0.tgz#d90dd8a9211830b4e3c08e94b63a0ba7291ddcf4" - integrity sha512-uHg75Rb/XORTtVt7OS9WoK8uM276Ufi7gCzshVWkUJbHhh3svsUUeqXerrM96Wm7fRiDzfKRwSoahhMIkGAYHw== +"@fortawesome/react-fontawesome@0.2.2": + version "0.2.2" + resolved "https://registry.yarnpkg.com/@fortawesome/react-fontawesome/-/react-fontawesome-0.2.2.tgz#68b058f9132b46c8599875f6a636dad231af78d4" + integrity sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g== dependencies: prop-types "^15.8.1" -"@humanwhocodes/config-array@^0.11.14": - version "0.11.14" - resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.14.tgz#d78e481a039f7566ecc9660b4ea7fe6b1fec442b" - integrity sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg== +"@humanwhocodes/config-array@^0.13.0": + version "0.13.0" + resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.13.0.tgz#fb907624df3256d04b9aa2df50d7aa97ec648748" + integrity sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw== dependencies: - "@humanwhocodes/object-schema" "^2.0.2" + "@humanwhocodes/object-schema" "^2.0.3" debug "^4.3.1" minimatch "^3.0.5" @@ -1170,7 +1160,7 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz#af5b2691a22b44be847b0ca81641c5fb6ad0172c" integrity sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA== -"@humanwhocodes/object-schema@^2.0.2": +"@humanwhocodes/object-schema@^2.0.3": version "2.0.3" resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== @@ -1207,7 +1197,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== -"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": +"@jridgewell/trace-mapping@^0.3.20", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.25": version "0.3.25" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz#15f190e98895f3fc23276ee14bc76b675c2e50f0" integrity sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ== @@ -1274,86 +1264,92 @@ resolved "https://registry.yarnpkg.com/@react-dnd/shallowequal/-/shallowequal-2.0.0.tgz#a3031eb54129f2c66b2753f8404266ec7bf67f0a" integrity sha512-Pc/AFTdwZwEKJxFJvlxrSmGe/di+aAOBn60sremrpLo6VI/6cmiUYNNwlI5KNYttg7uypzA3ILPMPgxB2GYZEg== -"@sentry-internal/feedback@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.100.0.tgz#38d8d4cb8ac3e6e24d91b13878bd6208a55bcab3" - integrity sha512-SMW2QhNKOuSjw8oPtvryDlJjiwrNyAKljbgtMk057os/fd8QMp38Yt1ImqLCM4B2rTQZ6REJ6hRGRTRcfqoG+w== - dependencies: - "@sentry/core" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" +"@rtsao/scc@^1.1.0": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@rtsao/scc/-/scc-1.1.0.tgz#927dd2fae9bc3361403ac2c7a00c32ddce9ad7e8" + integrity sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g== -"@sentry-internal/replay-canvas@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.100.0.tgz#b462346832631ed5a9446686419113ff331bd984" - integrity sha512-DePinj5IgNiC4RZv0yX0DLccMZebfFdKl3zHwDeLBeZqtMz9VrPzchv57IWP+5MI1+iuOn+WOg4oTNBUG6hFRw== +"@sentry-internal/feedback@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/feedback/-/feedback-7.119.1.tgz#98285dc9dba0ab62369d758124901b00faf58697" + integrity sha512-EPyW6EKZmhKpw/OQUPRkTynXecZdYl4uhZwdZuGqnGMAzswPOgQvFrkwsOuPYvoMfXqCH7YuRqyJrox3uBOrTA== dependencies: - "@sentry/core" "7.100.0" - "@sentry/replay" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" -"@sentry-internal/tracing@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.100.0.tgz#01f0925a287a6e5d0becd731ab361cabbd27c007" - integrity sha512-qf4W1STXky9WOQYoPSw2AmCBDK4FzvAyq5yeD2sLU7OCUEfbRUcN0lQljUvmWRKv/jTIAyeU5icDLJPZuR50nA== +"@sentry-internal/replay-canvas@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/replay-canvas/-/replay-canvas-7.119.1.tgz#b1413fb37734d609b0745ac24d49ddf9d63b9c51" + integrity sha512-O/lrzENbMhP/UDr7LwmfOWTjD9PLNmdaCF408Wx8SDuj7Iwc+VasGfHg7fPH4Pdr4nJON6oh+UqoV4IoG05u+A== dependencies: - "@sentry/core" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry/core" "7.119.1" + "@sentry/replay" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" -"@sentry/browser@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.100.0.tgz#adf57f660baa6190a7e1709605f73b94818ee04b" - integrity sha512-XpM0jEVe6DJWXjMSOjtJxsSNR/XnJKrlcuyoI4Re3qLG+noEF5QLc0r3VJkySXPRFnmdW05sLswQ6a/n9Sijmg== +"@sentry-internal/tracing@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry-internal/tracing/-/tracing-7.119.1.tgz#500d50d451bfd0ce6b185e9f112208229739ab03" + integrity sha512-cI0YraPd6qBwvUA3wQdPGTy8PzAoK0NZiaTN1LM3IczdPegehWOaEG5GVTnpGnTsmBAzn1xnBXNBhgiU4dgcrQ== dependencies: - "@sentry-internal/feedback" "7.100.0" - "@sentry-internal/replay-canvas" "7.100.0" - "@sentry-internal/tracing" "7.100.0" - "@sentry/core" "7.100.0" - "@sentry/replay" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" -"@sentry/core@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.100.0.tgz#5b28c7b3e41e45e4d50e3bdea5d35434fd78e86b" - integrity sha512-eWRPuP0Zdj4a2F7SybqNjf13LGOVgGwvW6sojweQp9oxGAfCPp/EMDGBhlpYbMJeLbzmqzJ4ZFHIedaiEC+7kg== +"@sentry/browser@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/browser/-/browser-7.119.1.tgz#260470dd7fd18de366017c3bf23a252a24d2ff05" + integrity sha512-aMwAnFU4iAPeLyZvqmOQaEDHt/Dkf8rpgYeJ0OEi50dmP6AjG+KIAMCXU7CYCCQDn70ITJo8QD5+KzCoZPYz0A== dependencies: - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry-internal/feedback" "7.119.1" + "@sentry-internal/replay-canvas" "7.119.1" + "@sentry-internal/tracing" "7.119.1" + "@sentry/core" "7.119.1" + "@sentry/integrations" "7.119.1" + "@sentry/replay" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" -"@sentry/integrations@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.100.0.tgz#6620cce950dce7c1f3e63d5b047b320a7d25b3c7" - integrity sha512-aO9wgnqlbav7FECKNcgTxQSGGSsMeYH9mV0cniuu520cDAhmVxtA+PqlnS3nsJZJj4cKjX6MWA2SbBG0szKmkw== +"@sentry/core@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/core/-/core-7.119.1.tgz#63e949cad167a0ee5e52986c93b96ff1d6a05b57" + integrity sha512-YUNnH7O7paVd+UmpArWCPH4Phlb5LwrkWVqzFWqL3xPyCcTSof2RL8UmvpkTjgYJjJ+NDfq5mPFkqv3aOEn5Sw== dependencies: - "@sentry/core" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" + +"@sentry/integrations@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/integrations/-/integrations-7.119.1.tgz#9fc17aa9fcb942fbd2fc12eecd77a0f316897960" + integrity sha512-CGmLEPnaBqbUleVqrmGYjRjf5/OwjUXo57I9t0KKWViq81mWnYhaUhRZWFNoCNQHns+3+GPCOMvl0zlawt+evw== + dependencies: + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" localforage "^1.8.1" -"@sentry/replay@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.100.0.tgz#4f2e35155626ab286692ade3e31da282c73bd402" - integrity sha512-6Yo56J+x+eedaMXri8pPlFxXOofnSXVdsUuFj+kJ7lC/qHrwIbgC5g1ONEK/WlYwpVH4gA0aNnCa5AOkMu+ZTg== +"@sentry/replay@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/replay/-/replay-7.119.1.tgz#117cf493a3008a39943b7d571d451c6218542847" + integrity sha512-4da+ruMEipuAZf35Ybt2StBdV1S+oJbSVccGpnl9w6RoeQoloT4ztR6ML3UcFDTXeTPT1FnHWDCyOfST0O7XMw== dependencies: - "@sentry-internal/tracing" "7.100.0" - "@sentry/core" "7.100.0" - "@sentry/types" "7.100.0" - "@sentry/utils" "7.100.0" + "@sentry-internal/tracing" "7.119.1" + "@sentry/core" "7.119.1" + "@sentry/types" "7.119.1" + "@sentry/utils" "7.119.1" -"@sentry/types@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.100.0.tgz#a16f60d78613bd9810298e9e8d80134be58b24f8" - integrity sha512-c+RHwZwpKeBk7h8sUX4nQcelxBz8ViCojifnbEe3tcn8O15HOLvZqRKgLLOiff3MoErxiv4oxs0sPbEFRm/IvA== +"@sentry/types@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/types/-/types-7.119.1.tgz#f9c3c12e217c9078a6d556c92590e42a39b750dd" + integrity sha512-4G2mcZNnYzK3pa2PuTq+M2GcwBRY/yy1rF+HfZU+LAPZr98nzq2X3+mJHNJoobeHRkvVh7YZMPi4ogXiIS5VNQ== -"@sentry/utils@7.100.0": - version "7.100.0" - resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.100.0.tgz#a9d36c01eede117c3e17b0350d399a87934e9c66" - integrity sha512-LAhZMEGq3C125prZN/ShqeXpRfdfgJkl9RAKjfq8cmMFsF7nsF72dEHZgIwrZ0lgNmtaWAB83AwJcyN83RwOxQ== +"@sentry/utils@7.119.1": + version "7.119.1" + resolved "https://registry.yarnpkg.com/@sentry/utils/-/utils-7.119.1.tgz#08b28fa8170987a60e149e2102e83395a95e9a89" + integrity sha512-ju/Cvyeu/vkfC5/XBV30UNet5kLEicZmXSyuLwZu95hEbL+foPdxN+re7pCI/eNqfe3B2vz7lvz5afLVOlQ2Hg== dependencies: - "@sentry/types" "7.100.0" + "@sentry/types" "7.119.1" "@types/archiver@^5.3.1": version "5.3.4" @@ -1362,26 +1358,10 @@ dependencies: "@types/readdir-glob" "*" -"@types/eslint-scope@^3.7.3": - version "3.7.7" - resolved "https://registry.yarnpkg.com/@types/eslint-scope/-/eslint-scope-3.7.7.tgz#3108bd5f18b0cdb277c867b3dd449c9ed7079ac5" - integrity sha512-MzMFlSLBqNF2gcHWO0G1vP/YQyfvrxZ0bF+u7mzUdZ1/xK4A4sru+nraZz5i3iEIk1l1uyicaDVTB4QbbEkAYg== - dependencies: - "@types/eslint" "*" - "@types/estree" "*" - -"@types/eslint@*": - version "9.6.0" - resolved "https://registry.yarnpkg.com/@types/eslint/-/eslint-9.6.0.tgz#51d4fe4d0316da9e9f2c80884f2c20ed5fb022ff" - integrity sha512-gi6WQJ7cHRgZxtkQEoyHMppPjq9Kxo5Tjn2prSKDSmZrCz8TZ3jSRCeTJm+WoM+oB0WG37bRqLzaaU3q7JypGg== - dependencies: - "@types/estree" "*" - "@types/json-schema" "*" - -"@types/estree@*", "@types/estree@^1.0.0": - version "1.0.5" - resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.5.tgz#a6ce3e556e00fd9895dd872dd172ad0d4bd687f4" - integrity sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw== +"@types/estree@^1.0.5": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== "@types/history@^4.7.11": version "4.7.11" @@ -1401,7 +1381,7 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== -"@types/json-schema@*", "@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1422,18 +1402,18 @@ integrity sha512-hov8bUuiLiyFPGyFPE1lwWhmzYbirOXQNNo40+y3zow8aFVTeyn3VWL0VFFfdNddA8S4Vf0Tc062rzyNr7Paag== "@types/node@*": - version "22.5.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.5.0.tgz#10f01fe9465166b4cab72e75f60d8b99d019f958" - integrity sha512-DkFrJOe+rfdHTqqMg0bSNlGlQ85hSoh2TPzZyhHsXnMtligRWpxUySiyw8FY14ITt24HVCiQPWxS3KO/QlGmWg== + version "22.7.5" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.7.5.tgz#cfde981727a7ab3611a481510b473ae54442b92b" + integrity sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ== dependencies: undici-types "~6.19.2" -"@types/node@18.19.31": - version "18.19.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.19.31.tgz#b7d4a00f7cb826b60a543cebdbda5d189aaecdcd" - integrity sha512-ArgCD39YpyyrtFKIqMDvjz79jto5fcI/SVUs2HwB+f0dAzq68yqOdyaSivLiLugSziTpNXLQrVb7RZFmdZzbhA== +"@types/node@20.16.11": + version "20.16.11" + resolved "https://registry.yarnpkg.com/@types/node/-/node-20.16.11.tgz#9b544c3e716b1577ac12e70f9145193f32750b33" + integrity sha512-y+cTCACu92FyA5fgQSAI8A1H429g7aSK2HsO7K4XYUWc4dY5IUz55JSDIYT6/VsOLfGy8vmvQYC2hfb0iF16Uw== dependencies: - undici-types "~5.26.4" + undici-types "~6.19.2" "@types/normalize-package-data@^2.4.0": version "2.4.4" @@ -1460,9 +1440,9 @@ postcss "^8.0.0" "@types/prop-types@*": - version "15.7.12" - resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.12.tgz#12bb1e2be27293c1406acb6af1c3f3a1481d98c6" - integrity sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q== + version "15.7.13" + resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451" + integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA== "@types/react-dom@18.2.25": version "18.2.25" @@ -1471,17 +1451,17 @@ dependencies: "@types/react" "*" -"@types/react-lazyload@3.2.0": - version "3.2.0" - resolved "https://registry.yarnpkg.com/@types/react-lazyload/-/react-lazyload-3.2.0.tgz#b763f8f0c724df2c969d7e0b3a56c6aa2720fa1f" - integrity sha512-4+r+z8Cf7L/mgxA1vl5uHx5GS/8gY2jqq2p5r5WCm+nUsg9KilwQ+8uaJA3EUlLj57AOzOfGGwwRJ5LOVl8fwA== +"@types/react-lazyload@3.2.3": + version "3.2.3" + resolved "https://registry.yarnpkg.com/@types/react-lazyload/-/react-lazyload-3.2.3.tgz#42129b6e11353bfe8ed2ba5e1b964676ee23668b" + integrity sha512-s03gWlHXiFqZr7TEFDTx8Lkl+ZEYrwTkXP9MNZ3Z3blzsPrnkYjgeSK2tjfzVv/TYVCnDk6TZwNRDHQlHy/1Ug== dependencies: "@types/react" "*" "@types/react-redux@^7.1.16": - version "7.1.33" - resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.33.tgz#53c5564f03f1ded90904e3c90f77e4bd4dc20b15" - integrity sha512-NF8m5AjWCkert+fosDsN3hAlHzpjSiXlVy9EgQEmLoBhaNXbmyeGs/aj5dQzKuF+/q+S7JQagorGDW8pJ28Hmg== + version "7.1.34" + resolved "https://registry.yarnpkg.com/@types/react-redux/-/react-redux-7.1.34.tgz#83613e1957c481521e6776beeac4fd506d11bd0e" + integrity sha512-GdFaVjEbYv4Fthm2ZLvj1VSCedV7TqE5y1kNwnjSdBOTXuRSgowux6J8TAct15T3CKBr63UMk+2CO7ilRhyrAQ== dependencies: "@types/hoist-non-react-statics" "^3.3.0" "@types/react" "*" @@ -1505,24 +1485,24 @@ "@types/history" "^4.7.11" "@types/react" "*" -"@types/react-text-truncate@0.14.1": - version "0.14.1" - resolved "https://registry.yarnpkg.com/@types/react-text-truncate/-/react-text-truncate-0.14.1.tgz#3d24eca927e5fd1bfd789b047ae8ec53ba878b28" - integrity sha512-yCtOOOJzrsfWF6TbnTDZz0gM5JYOxJmewExaTJTv01E7yrmpkNcmVny2fAtsNgSFCp8k2VgCePBoIvFBpKyEOw== +"@types/react-text-truncate@0.19.0": + version "0.19.0" + resolved "https://registry.yarnpkg.com/@types/react-text-truncate/-/react-text-truncate-0.19.0.tgz#322dd718dcbe1267a9d1279f8ac4dc844c322a13" + integrity sha512-8H7BjVf7Rp3ERTTiFZpQf6a5hllwdJrWuQ92nwQGp7DWQ2Ju89GRuzXHuZHXU9T+hLTGLCUPbimjQnW1mAogqQ== dependencies: "@types/react" "*" -"@types/react-window@1.8.5": - version "1.8.5" - resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.5.tgz#285fcc5cea703eef78d90f499e1457e9b5c02fc1" - integrity sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw== +"@types/react-window@1.8.8": + version "1.8.8" + resolved "https://registry.yarnpkg.com/@types/react-window/-/react-window-1.8.8.tgz#c20645414d142364fbe735818e1c1e0a145696e3" + integrity sha512-8Ls660bHR1AUA2kuRvVG9D/4XpRC6wjAaPT9dil7Ckc76eP9TKWZwwmgfq8Q1LANX3QNDnoU4Zp48A3w+zK69Q== dependencies: "@types/react" "*" "@types/react@*": - version "18.3.4" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.4.tgz#dfdd534a1d081307144c00e325c06e00312c93a3" - integrity sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw== + version "18.3.11" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.11.tgz#9d530601ff843ee0d7030d4227ea4360236bd537" + integrity sha512-r6QZ069rFTjrEYgFdOck1gK7FLVsgJE7tTz0pQBczlBNUhBNk0MQH4UbnFSwjpQLMkLzgqvBBa+qGpLje16eTQ== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -1542,10 +1522,10 @@ dependencies: "@types/node" "*" -"@types/redux-actions@2.6.2": - version "2.6.2" - resolved "https://registry.yarnpkg.com/@types/redux-actions/-/redux-actions-2.6.2.tgz#5956d9e7b9a644358e2c0610f47b1fa3060edc21" - integrity sha512-TvcINy8rWFANcpc3EiEQX9Yv3owM3d3KIrqr2ryUIOhYIYzXA/bhDZeGSSSuai62iVR2qMZUgz9tQ5kr0Kl+Tg== +"@types/redux-actions@2.6.5": + version "2.6.5" + resolved "https://registry.yarnpkg.com/@types/redux-actions/-/redux-actions-2.6.5.tgz#3728477ada6c4bc0fe54ffae11def23a65c0714b" + integrity sha512-RgXOigay5cNweP+xH1ru+Vaaj1xXYLpWIfSVO8cSA8Ii2xvR+HRfWYdLe1UVOA8X0kIklalGOa0DTDyld0obkg== "@types/semver@^7.5.0": version "7.5.8" @@ -1569,10 +1549,10 @@ dependencies: source-map "^0.6.1" -"@types/webpack-livereload-plugin@2.3.3": - version "2.3.3" - resolved "https://registry.yarnpkg.com/@types/webpack-livereload-plugin/-/webpack-livereload-plugin-2.3.3.tgz#96f34133f1e1515571233a3e5099d863dc8723e7" - integrity sha512-R8P2HG2mAHY3Qptspt0il8zYVNqiEeOmMe2cGFcEjH7qnJZ4uC7hujLwfAm6jrIO7I5uEs6CxfpKSXM9ULAggw== +"@types/webpack-livereload-plugin@2.3.6": + version "2.3.6" + resolved "https://registry.yarnpkg.com/@types/webpack-livereload-plugin/-/webpack-livereload-plugin-2.3.6.tgz#2c3ccefc8858525f40aeb8be0f784d5027144e23" + integrity sha512-H8nZSOWSiY/6kCpOmbutZPu7Sai1xyEXo/SrXQPCymMPNBwpYWAdOsjKqr32d+IrVjnn9GGgKSYY34TEPRxJ/A== dependencies: "@types/webpack" "^4" @@ -1688,7 +1668,7 @@ resolved "https://registry.yarnpkg.com/@ungap/structured-clone/-/structured-clone-1.2.0.tgz#756641adb587851b5ccb3e095daf27ae581c8406" integrity sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ== -"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.11.5": +"@webassemblyjs/ast@1.12.1", "@webassemblyjs/ast@^1.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.12.1.tgz#bb16a0e8b1914f979f45864c23819cc3e3f0d4bb" integrity sha512-EKfMUOPRRUTy5UII4qJDGPpqfwjOmZ5jeGFwid9mnoqIFK+e0vqoi1qH56JpmZSzEL53jKnNzScdmftJyG5xWg== @@ -1754,7 +1734,7 @@ resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.11.6.tgz#90f8bc34c561595fe156603be7253cdbcd0fab5a" integrity sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA== -"@webassemblyjs/wasm-edit@^1.11.5": +"@webassemblyjs/wasm-edit@^1.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.12.1.tgz#9f9f3ff52a14c980939be0ef9d5df9ebc678ae3b" integrity sha512-1DuwbVvADvS5mGnXbE+c9NfA8QRcZ6iKquqjjmR10k6o+zzsRVesil54DKexiowcFCPdr/Q0qaMgB01+SQ1u6g== @@ -1789,7 +1769,7 @@ "@webassemblyjs/wasm-gen" "1.12.1" "@webassemblyjs/wasm-parser" "1.12.1" -"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.11.5": +"@webassemblyjs/wasm-parser@1.12.1", "@webassemblyjs/wasm-parser@^1.12.1": version "1.12.1" resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.12.1.tgz#c47acb90e6f083391e3fa61d113650eea1e95937" integrity sha512-xikIi7c2FHXysxXe3COrVUPSheuBtpcfhbpFj4gmu7KRLYOzANztwUU0IbsqvMqzuNK2+glRGWCEqZo1WCLyAQ== @@ -1841,10 +1821,10 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -acorn-import-assertions@^1.9.0: - version "1.9.0" - resolved "https://registry.yarnpkg.com/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz#507276249d684797c84e0734ef84860334cfb1ac" - integrity sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA== +acorn-import-attributes@^1.9.5: + version "1.9.5" + resolved "https://registry.yarnpkg.com/acorn-import-attributes/-/acorn-import-attributes-1.9.5.tgz#7eb1557b1ba05ef18b5ed0ec67591bfab04688ef" + integrity sha512-n02Vykv5uA3eHGM/Z2dQrcD56kL8TyDb2p1+0P83PClMnC/nc+anbQRhIOWnSq4Ke/KvDPrY3C9hDtC/A3eHnQ== acorn-jsx@^5.3.2: version "5.3.2" @@ -2047,7 +2027,7 @@ array-buffer-byte-length@^1.0.1: call-bind "^1.0.5" is-array-buffer "^3.0.4" -array-includes@^3.1.6, array-includes@^3.1.7: +array-includes@^3.1.6, array-includes@^3.1.8: version "3.1.8" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.8.tgz#5e370cbe172fdd5dd6530c1d4aadda25281ba97d" integrity sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ== @@ -2069,7 +2049,7 @@ array-union@^2.1.0: resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" integrity sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw== -array.prototype.findlast@^1.2.4: +array.prototype.findlast@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz#3e4fbcb30a15a7f5bf64cf2faae22d139c2e4904" integrity sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ== @@ -2081,7 +2061,7 @@ array.prototype.findlast@^1.2.4: es-object-atoms "^1.0.0" es-shim-unscopables "^1.0.2" -array.prototype.findlastindex@^1.2.3: +array.prototype.findlastindex@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz#8c35a755c72908719453f87145ca011e39334d0d" integrity sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ== @@ -2113,17 +2093,7 @@ array.prototype.flatmap@^1.3.2: es-abstract "^1.22.1" es-shim-unscopables "^1.0.0" -array.prototype.toreversed@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/array.prototype.toreversed/-/array.prototype.toreversed-1.1.2.tgz#b989a6bf35c4c5051e1dc0325151bf8088954eba" - integrity sha512-wwDCoT4Ck4Cz7sLtgUmzR5UV3YF5mFHUlbChCzZBQZ+0m2cl/DH3tKgvphv1nKgFsJ48oCSg6p91q2Vm0I/ZMA== - dependencies: - call-bind "^1.0.2" - define-properties "^1.2.0" - es-abstract "^1.22.1" - es-shim-unscopables "^1.0.0" - -array.prototype.tosorted@^1.1.3: +array.prototype.tosorted@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz#fe954678ff53034e717ea3352a03f0b0b86f7ffc" integrity sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA== @@ -2189,10 +2159,10 @@ available-typed-arrays@^1.0.7: dependencies: possible-typed-array-names "^1.0.0" -babel-loader@9.1.3: - version "9.1.3" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.1.3.tgz#3d0e01b4e69760cc694ee306fe16d358aa1c6f9a" - integrity sha512-xG3ST4DglodGf8qSwv0MdeWLhrDsw/32QMdTO5T1ZIp9gQur0HkCyFs7Awskr10JKXFXwpAhiCuYX5oGXnRGbw== +babel-loader@9.2.1: + version "9.2.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-9.2.1.tgz#04c7835db16c246dd19ba0914418f3937797587b" + integrity sha512-fqe8naHt46e0yIdkjUZYqddSXfej3AHajX+CSO5X7oy0EmPc6o5Xh+RClNoHjnieWz9AW4kZxW9yyFMhVB1QLA== dependencies: find-cache-dir "^4.0.0" schema-utils "^4.0.0" @@ -2211,7 +2181,7 @@ babel-plugin-polyfill-corejs2@^0.4.10: "@babel/helper-define-polyfill-provider" "^0.6.2" semver "^6.3.1" -babel-plugin-polyfill-corejs3@^0.10.4: +babel-plugin-polyfill-corejs3@^0.10.6: version "0.10.6" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.10.6.tgz#2deda57caef50f59c525aeb4964d3b2f867710c7" integrity sha512-b37+KR2i/khY5sKmWNVQAnitvquQbNdWy6lJdsr0kmquCKEEUgMKK4SboVM3HtfnZilfjr4MMQ7vY58FVWDtIA== @@ -2315,13 +2285,13 @@ braces@^3.0.3, braces@~3.0.2: dependencies: fill-range "^7.1.1" -browserslist@^4.14.5, browserslist@^4.23.1, browserslist@^4.23.3: - version "4.23.3" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.23.3.tgz#debb029d3c93ebc97ffbc8d9cbb03403e227c800" - integrity sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA== +browserslist@^4.21.10, browserslist@^4.23.3, browserslist@^4.24.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.24.0.tgz#a1325fe4bc80b64fda169629fc01b3d6cecd38d4" + integrity sha512-Rmb62sR1Zpjql25eSanFGEhAxcFwfA1K0GuQcLoaJBAcENegrQut3hYdhXFF1obQfiDyqIW/cLM5HSJ/9k884A== dependencies: - caniuse-lite "^1.0.30001646" - electron-to-chromium "^1.5.4" + caniuse-lite "^1.0.30001663" + electron-to-chromium "^1.5.28" node-releases "^2.0.18" update-browserslist-db "^1.1.0" @@ -2391,9 +2361,9 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== -caniuse-lite@^1.0.30001646: +caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663: version "1.0.30001667" - resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz#99fc5ea0d9c6e96897a104a8352604378377f949" integrity sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw== chalk@^1.1.3: @@ -2424,7 +2394,7 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: ansi-styles "^4.1.0" supports-color "^7.1.0" -"chokidar@>=3.0.0 <4.0.0", chokidar@^3.5.3: +chokidar@^3.5.3: version "3.6.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.6.0.tgz#197c6cc669ef2a8dc5e7b4d97ee4e092c3eb0d5b" integrity sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw== @@ -2439,15 +2409,22 @@ chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.2: optionalDependencies: fsevents "~2.3.2" +chokidar@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-4.0.1.tgz#4a6dff66798fb0f72a94f616abbd7e1a19f31d41" + integrity sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA== + dependencies: + readdirp "^4.0.1" + chrome-trace-event@^1.0.2: version "1.0.4" resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz#05bffd7ff928465093314708c93bdfa9bd1f0f5b" integrity sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ== -classnames@2.3.2: - version "2.3.2" - resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.3.2.tgz#351d813bf0137fcc6a76a16b88208d2560a0d924" - integrity sha512-CSbhY4cFEJRe6/GQzIk5qXZ4Jeg5pcsP7b5peFSDpffpe1cqjASH/n9UTjBwOp6XpMSTwQ8Za2K5V02ueA7Tmw== +classnames@2.5.1: + version "2.5.1" + resolved "https://registry.yarnpkg.com/classnames/-/classnames-2.5.1.tgz#ba774c614be0f016da105c858e7159eae8e7687b" + integrity sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow== clean-css@^5.2.2: version "5.3.3" @@ -2605,14 +2582,7 @@ copy-to-clipboard@3.3.3: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.37.1: - version "3.38.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.0.tgz#d93393b1aa346b6ee683377b0c31172ccfe607aa" - integrity sha512-75LAicdLa4OJVwFxFbQR3NdnZjNgX6ILpVcVzcC4T2smerB5lELMrJQQQoWV6TiuC/vlaFqgU2tKQx9w5s0e0A== - dependencies: - browserslist "^4.23.3" - -core-js-compat@^3.38.0: +core-js-compat@^3.38.0, core-js-compat@^3.38.1: version "3.38.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.38.1.tgz#2bc7a298746ca5a7bcb9c164bcb120f2ebc09a09" integrity sha512-JRH6gfXxGmrzF3tZ57lFx97YARxCXPaMzPo6jELZhv88pBH5VXpQ+y0znKGlFnzuaihqhLbefxSJxWJMPtfDzw== @@ -2696,9 +2666,9 @@ css-color-function@~1.3.3: rgb "~0.1.0" css-functions-list@^3.1.0: - version "3.2.2" - resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.2.tgz#9a54c6dd8416ed25c1079cd88234e927526c1922" - integrity sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ== + version "3.2.3" + resolved "https://registry.yarnpkg.com/css-functions-list/-/css-functions-list-3.2.3.tgz#95652b0c24f0f59b291a9fc386041a19d4f40dbe" + integrity sha512-IQOkD3hbR5KrN93MtcYuad6YPuTSUhntLHDuLEbFWE+ff2/XSZNdZG+LcbbIW5AXKg/WFIfYItIzVoHngHXZzA== css-loader@6.7.3: version "6.7.3" @@ -2801,11 +2771,11 @@ debug@^3.1.0, debug@^3.2.7: ms "^2.1.1" debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.4: - version "4.3.6" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.6.tgz#2ab2c38fbaffebf8aa95fdfe6d88438c7a13c52b" - integrity sha512-O/09Bd4Z1fBrU4VzkhFqVgpPzaGbw6Sm9FEkBT1A/YBXQFGuuSxa1dN2nxgxS34JmKXqYx8CZAwEVoJFImUXIg== + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== dependencies: - ms "2.1.2" + ms "^2.1.3" decamelize-keys@^1.1.0: version "1.1.1" @@ -2851,7 +2821,7 @@ define-data-property@^1.0.1, define-data-property@^1.1.4: es-errors "^1.3.0" gopd "^1.0.1" -define-properties@^1.2.0, define-properties@^1.2.1: +define-properties@^1.1.3, define-properties@^1.2.0, define-properties@^1.2.1: version "1.2.1" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.2.1.tgz#10781cc616eb951a80a034bafcaa7377f6af2b6c" integrity sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg== @@ -2987,10 +2957,10 @@ dotenv@^16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== -electron-to-chromium@^1.5.4: - version "1.5.13" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.13.tgz#1abf0410c5344b2b829b7247e031f02810d442e6" - integrity sha512-lbBcvtIJ4J6sS4tb5TLp1b4LyfCdMkwStzXPyAgVgTRAsep4bvrAGaBOP7ZJtQMNJpSQ9SqG4brWOroNaQtm7Q== +electron-to-chromium@^1.5.28: + version "1.5.35" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.35.tgz#1d38d386186c72b1fa6e74c3a7de5f888b503100" + integrity sha512-hOSRInrIDm0Brzp4IHW2F/VM+638qOL2CzE0DgpnGzKW27C95IqqeqgKz/hxHGnvPxvQGpHUGD5qRVC9EZY2+A== element-class@0.2.2: version "0.2.2" @@ -3014,7 +2984,7 @@ end-of-stream@^1.4.1: dependencies: once "^1.4.0" -enhanced-resolve@^5.0.0, enhanced-resolve@^5.15.0: +enhanced-resolve@^5.0.0, enhanced-resolve@^5.17.1: version "5.17.1" resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.17.1.tgz#67bfbbcc2f81d511be77d686a90267ef7f898a15" integrity sha512-LMHl3dXhTcfv8gM4kEzIUeTQ+7fpdA0l2tUf34BddXPkz2A5xJ5L/Pchd5BL6rdccM9QGvu0sWZzK1Z1t4wwyg== @@ -3028,9 +2998,9 @@ entities@^2.0.0: integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A== envinfo@^7.7.3: - version "7.13.0" - resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.13.0.tgz#81fbb81e5da35d74e814941aeab7c325a606fb31" - integrity sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q== + version "7.14.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-7.14.0.tgz#26dac5db54418f2a4c1159153a0b2ae980838aae" + integrity sha512-CO40UI41xDQzhLB1hWyqUKgFhs250pNcGbyGKe1l/e4FSaI/+YE4IMG76GDt0In67WLPACIITC+sOi08x4wIvg== errno@^0.1.1: version "0.1.8" @@ -3060,7 +3030,7 @@ error@^7.0.0: dependencies: string-template "~0.2.1" -es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: +es-abstract@^1.17.5, es-abstract@^1.22.1, es-abstract@^1.22.3, es-abstract@^1.23.0, es-abstract@^1.23.1, es-abstract@^1.23.2, es-abstract@^1.23.3: version "1.23.3" resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.23.3.tgz#8f0c5a35cd215312573c5a27c87dfd6c881a0aa0" integrity sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A== @@ -3124,10 +3094,10 @@ es-errors@^1.2.1, es-errors@^1.3.0: resolved "https://registry.yarnpkg.com/es-errors/-/es-errors-1.3.0.tgz#05f75a25dab98e4fb1dcd5e1472c0546d5057c8f" integrity sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw== -es-iterator-helpers@^1.0.17: - version "1.0.19" - resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.0.19.tgz#117003d0e5fec237b4b5c08aded722e0c6d50ca8" - integrity sha512-zoMwbCcH5hwUkKJkT8kDIBZSz9I6mVG//+lDCinLCGov4+r7NIy0ld8o03M0cJxl2spVf6ESYVS6/gpIfq1FFw== +es-iterator-helpers@^1.0.19: + version "1.1.0" + resolved "https://registry.yarnpkg.com/es-iterator-helpers/-/es-iterator-helpers-1.1.0.tgz#f6d745d342aea214fe09497e7152170dc333a7a6" + integrity sha512-/SurEfycdyssORP/E+bj4sEu1CWw4EmLDsHynHwSXQ7utgbrMRWW195pTrCjFgFCddf/UkYm3oqKPRq5i8bJbw== dependencies: call-bind "^1.0.7" define-properties "^1.2.1" @@ -3136,12 +3106,12 @@ es-iterator-helpers@^1.0.17: es-set-tostringtag "^2.0.3" function-bind "^1.1.2" get-intrinsic "^1.2.4" - globalthis "^1.0.3" + globalthis "^1.0.4" has-property-descriptors "^1.0.2" has-proto "^1.0.3" has-symbols "^1.0.3" internal-slot "^1.0.7" - iterator.prototype "^1.1.2" + iterator.prototype "^1.1.3" safe-array-concat "^1.1.2" es-module-lexer@^1.2.1: @@ -3186,10 +3156,10 @@ es6-promise@^4.2.8: resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.2.8.tgz#4eb21594c972bc40553d276e510539143db53e0a" integrity sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w== -escalade@^3.1.2: - version "3.1.2" - resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.2.tgz#54076e9ab29ea5bf3d8f1ed62acffbb88272df27" - integrity sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA== +escalade@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" + integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" @@ -3215,10 +3185,10 @@ eslint-import-resolver-node@^0.3.9: is-core-module "^2.13.0" resolve "^1.22.4" -eslint-module-utils@^2.8.0: - version "2.8.1" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz#52f2404300c3bd33deece9d7372fb337cc1d7c34" - integrity sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q== +eslint-module-utils@^2.12.0: + version "2.12.0" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz#fe4cfb948d61f49203d7b08871982b65b9af0b0b" + integrity sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg== dependencies: debug "^3.2.7" @@ -3232,27 +3202,29 @@ eslint-plugin-filenames@1.3.2: lodash.snakecase "4.1.1" lodash.upperfirst "4.3.1" -eslint-plugin-import@2.29.1: - version "2.29.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz#d45b37b5ef5901d639c15270d74d46d161150643" - integrity sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw== +eslint-plugin-import@2.31.0: + version "2.31.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" + integrity sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A== dependencies: - array-includes "^3.1.7" - array.prototype.findlastindex "^1.2.3" + "@rtsao/scc" "^1.1.0" + array-includes "^3.1.8" + array.prototype.findlastindex "^1.2.5" array.prototype.flat "^1.3.2" array.prototype.flatmap "^1.3.2" debug "^3.2.7" doctrine "^2.1.0" eslint-import-resolver-node "^0.3.9" - eslint-module-utils "^2.8.0" - hasown "^2.0.0" - is-core-module "^2.13.1" + eslint-module-utils "^2.12.0" + hasown "^2.0.2" + is-core-module "^2.15.1" is-glob "^4.0.3" minimatch "^3.1.2" - object.fromentries "^2.0.7" - object.groupby "^1.0.1" - object.values "^1.1.7" + object.fromentries "^2.0.8" + object.groupby "^1.0.3" + object.values "^1.2.0" semver "^6.3.1" + string.prototype.trimend "^1.0.8" tsconfig-paths "^3.15.0" eslint-plugin-json@3.1.0: @@ -3270,39 +3242,39 @@ eslint-plugin-prettier@4.2.1: dependencies: prettier-linter-helpers "^1.0.0" -eslint-plugin-react-hooks@4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" - integrity sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g== +eslint-plugin-react-hooks@4.6.2: + version "4.6.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.2.tgz#c829eb06c0e6f484b3fbb85a97e57784f328c596" + integrity sha512-QzliNJq4GinDBcD8gPB5v0wh6g8q3SUi6EFF0x8N/BL9PoVs0atuGc47ozMRyOWAKdwaZ5OnbOEa3WR+dSGKuQ== -eslint-plugin-react@7.34.1: - version "7.34.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.34.1.tgz#6806b70c97796f5bbfb235a5d3379ece5f4da997" - integrity sha512-N97CxlouPT1AHt8Jn0mhhN2RrADlUAsk1/atcT2KyA/l9Q/E6ll7OIGwNumFmWfZ9skV3XXccYS19h80rHtgkw== +eslint-plugin-react@7.37.1: + version "7.37.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-react/-/eslint-plugin-react-7.37.1.tgz#56493d7d69174d0d828bc83afeffe96903fdadbd" + integrity sha512-xwTnwDqzbDRA8uJ7BMxPs/EXRB3i8ZfnOIp8BsxEQkT0nHPp+WWceqGgo6rKb9ctNi8GJLDT4Go5HAWELa/WMg== dependencies: - array-includes "^3.1.7" - array.prototype.findlast "^1.2.4" + array-includes "^3.1.8" + array.prototype.findlast "^1.2.5" array.prototype.flatmap "^1.3.2" - array.prototype.toreversed "^1.1.2" - array.prototype.tosorted "^1.1.3" + array.prototype.tosorted "^1.1.4" doctrine "^2.1.0" - es-iterator-helpers "^1.0.17" + es-iterator-helpers "^1.0.19" estraverse "^5.3.0" + hasown "^2.0.2" jsx-ast-utils "^2.4.1 || ^3.0.0" minimatch "^3.1.2" - object.entries "^1.1.7" - object.fromentries "^2.0.7" - object.hasown "^1.1.3" - object.values "^1.1.7" + object.entries "^1.1.8" + object.fromentries "^2.0.8" + object.values "^1.2.0" prop-types "^15.8.1" resolve "^2.0.0-next.5" semver "^6.3.1" - string.prototype.matchall "^4.0.10" + string.prototype.matchall "^4.0.11" + string.prototype.repeat "^1.0.0" -eslint-plugin-simple-import-sort@12.1.0: - version "12.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.0.tgz#8186ad55474d2f5c986a2f1bf70625a981e30d05" - integrity sha512-Y2fqAfC11TcG/WP3TrI1Gi3p3nc8XJyEOJYHyEPEGI/UAgNx6akxxlX74p7SbAQdLcgASKhj8M0GKvH3vq/+ig== +eslint-plugin-simple-import-sort@12.1.1: + version "12.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-simple-import-sort/-/eslint-plugin-simple-import-sort-12.1.1.tgz#e64bfdaf91c5b98a298619aa634a9f7aa43b709e" + integrity sha512-6nuzu4xwQtE3332Uz0to+TxDQYRLTKRESSc2hefVT48Zc8JthmN23Gx9lnYhu0FtkRSL1oxny3kJ2aveVhmOVA== eslint-scope@5.1.1: version "5.1.1" @@ -3330,16 +3302,16 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== -eslint@8.57.0: - version "8.57.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.0.tgz#c786a6fd0e0b68941aaf624596fb987089195668" - integrity sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ== +eslint@8.57.1: + version "8.57.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" + integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA== dependencies: "@eslint-community/eslint-utils" "^4.2.0" "@eslint-community/regexpp" "^4.6.1" "@eslint/eslintrc" "^2.1.4" - "@eslint/js" "8.57.0" - "@humanwhocodes/config-array" "^0.11.14" + "@eslint/js" "8.57.1" + "@humanwhocodes/config-array" "^0.13.0" "@humanwhocodes/module-importer" "^1.0.1" "@nodelib/fs.walk" "^1.2.8" "@ungap/structured-clone" "^1.2.0" @@ -3476,9 +3448,9 @@ fast-levenshtein@^2.0.6: integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== fast-uri@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.1.tgz#cddd2eecfc83a71c1be2cc2ef2061331be8a7134" - integrity sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw== + version "3.0.2" + resolved "https://registry.yarnpkg.com/fast-uri/-/fast-uri-3.0.2.tgz#d78b298cf70fd3b752fd951175a3da6a7b48f024" + integrity sha512-GR6f0hD7XXyNJa25Tb9BuIdN0tdr+0BMi6/CJPH3wJO1JjNG3n/VsSw38AwRdKZABm8lGbPfakLRkYzx2V9row== fastest-levenshtein@^1.0.12, fastest-levenshtein@^1.0.16: version "1.0.16" @@ -3535,10 +3507,10 @@ filemanager-webpack-plugin@8.0.0: normalize-path "^3.0.0" schema-utils "^4.0.0" -filesize@10.0.7: - version "10.0.7" - resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.0.7.tgz#2237a816ee60a83fd0c3382ae70800e54eced3ad" - integrity sha512-iMRG7Qo9nayLoU3PNCiLizYtsy4W1ClrapeCwEgtiQelOAOuRJiw4QaLI+sSr8xr901dgHv+EYP2bCusGZgoiA== +filesize@10.1.6: + version "10.1.6" + resolved "https://registry.yarnpkg.com/filesize/-/filesize-10.1.6.tgz#31194da825ac58689c0bce3948f33ce83aabd361" + integrity sha512-sJslQKU2uM33qH5nqewAwVB2QgR6w1aMNsYUp3aN5rMRyXEwJGmZvaWzeJFNTOXWlHQyBFCWrdj3fV/fsTOX8w== fill-range@^7.1.1: version "7.1.1" @@ -3788,7 +3760,7 @@ globals@^13.19.0: dependencies: type-fest "^0.20.2" -globalthis@^1.0.3: +globalthis@^1.0.3, globalthis@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" integrity sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ== @@ -3820,7 +3792,7 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.9: +graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.11, graceful-fs@^4.2.4: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -3947,10 +3919,10 @@ html-tags@^3.3.1: resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.3.1.tgz#a04026a18c882e4bba8a01a3d39cfe465d40b5ce" integrity sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ== -html-webpack-plugin@5.5.3: - version "5.5.3" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz#72270f4a78e222b5825b296e5e3e1328ad525a3e" - integrity sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg== +html-webpack-plugin@5.6.0: + version "5.6.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-5.6.0.tgz#50a8fa6709245608cb00e811eacecb8e0d7b7ea0" + integrity sha512-iwaY4wzbe48AfKLZ/Cc8k0L+FKG6oSNRaZ8x5A/T/IVDGyXcbHncM9TdDa93wn0FsSm82FhTKW7f3vS61thXAw== dependencies: "@types/html-minifier-terser" "^6.0.0" html-minifier-terser "^6.0.2" @@ -4140,7 +4112,7 @@ is-callable@^1.1.3, is-callable@^1.1.4, is-callable@^1.2.7: resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.7.tgz#3bc2a85ea742d9e36205dcacdd72ca1fdc51b055" integrity sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA== -is-core-module@^2.13.0, is-core-module@^2.13.1, is-core-module@^2.5.0: +is-core-module@^2.13.0, is-core-module@^2.15.1, is-core-module@^2.5.0: version "2.15.1" resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== @@ -4337,10 +4309,10 @@ isstream@^0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== -iterator.prototype@^1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.2.tgz#5e29c8924f01916cb9335f1ff80619dcff22b0c0" - integrity sha512-DR33HMMr8EzwuRL8Y9D3u2BMj8+RqSE850jfGu59kS7tbmPLzGkZmVSfyCFSDxuZiEY6Rzt3T2NA/qU+NwVj1w== +iterator.prototype@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.3.tgz#016c2abe0be3bbdb8319852884f60908ac62bf9c" + integrity sha512-FW5iMbeQ6rBGm/oKgzq2aW4KvAGpxPzYES8N4g4xNXUKpL1mclMvOe+76AcLDTvD+Ze+sOpVhgdAQEKF4L9iGQ== dependencies: define-properties "^1.2.1" get-intrinsic "^1.2.1" @@ -4367,10 +4339,10 @@ jiti@^1.18.2: resolved "https://registry.yarnpkg.com/jiti/-/jiti-1.21.6.tgz#6c7f7398dd4b3142767f9a168af2f317a428d268" integrity sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w== -jquery@3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.0.tgz#fe2c01a05da500709006d8790fe21c8a39d75612" - integrity sha512-umpJ0/k8X0MvD1ds0P9SfowREz2LenHsQaxSohMZ5OMNEU2r0tf8pdeEFTHMFxWVxKNyU9rTtK3CWzUCTKJUeQ== +jquery@3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.7.1.tgz#083ef98927c9a6a74d05a6af02806566d16274de" + integrity sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg== "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0: version "4.0.0" @@ -4384,15 +4356,10 @@ js-yaml@^4.1.0: dependencies: argparse "^2.0.1" -jsesc@^2.5.1: - version "2.5.2" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4" - integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA== - -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" - integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +jsesc@^3.0.2, jsesc@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-3.0.2.tgz#bb8b09a6597ba426425f2e4a07245c3d00b9343e" + integrity sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g== json-buffer@3.0.1: version "3.0.1" @@ -4835,12 +4802,13 @@ mini-create-react-context@^0.4.0: "@babel/runtime" "^7.12.1" tiny-warning "^1.0.3" -mini-css-extract-plugin@2.7.6: - version "2.7.6" - resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.7.6.tgz#282a3d38863fddcd2e0c220aaed5b90bc156564d" - integrity sha512-Qk7HcgaPkGG6eD77mLvZS1nmxlao3j+9PkrT9Uc7HAE1id3F41+DdBRYRYkbyfNRGzm8/YWtzhw7nVPmwhqTQw== +mini-css-extract-plugin@2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/mini-css-extract-plugin/-/mini-css-extract-plugin-2.9.1.tgz#4d184f12ce90582e983ccef0f6f9db637b4be758" + integrity sha512-+Vyi+GCCOHnrJ2VPS+6aPoXN2k2jgUzDRhTFLjjTBn23qyXJXkjUWQgTL+mXpF5/A8ixLdCc6kWsoeOjKGejKQ== dependencies: schema-utils "^4.0.0" + tapable "^2.2.1" minimatch@9.0.3: version "9.0.3" @@ -4913,22 +4881,17 @@ mobile-detect@1.4.5: resolved "https://registry.yarnpkg.com/mobile-detect/-/mobile-detect-1.4.5.tgz#da393c3c413ca1a9bcdd9ced653c38281c0fb6ad" integrity sha512-yc0LhH6tItlvfLBugVUEtgawwFU2sIe+cSdmRJJCTMZ5GEJyLxNyC/NIOAOGk67Fa8GNpOttO3Xz/1bHpXFD/g== -moment@2.29.4: - version "2.29.4" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108" - integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w== +moment@2.30.1: + version "2.30.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" + integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== mousetrap@1.6.5: version "1.6.5" resolved "https://registry.yarnpkg.com/mousetrap/-/mousetrap-1.6.5.tgz#8a766d8c272b08393d5f56074e0b5ec183485bf9" integrity sha512-QNo4kEepaIBwiT8CDhP98umTetp+JNfQYBWvC1pc6/OAibuXtRcxZ58Qz8skvEHYvURne/7R8T5VoOI7rDsEUA== -ms@2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" - integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== - -ms@^2.1.1: +ms@^2.1.1, ms@^2.1.3: version "2.1.3" resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== @@ -5061,7 +5024,7 @@ object.assign@^4.1.4, object.assign@^4.1.5: has-symbols "^1.0.3" object-keys "^1.1.1" -object.entries@^1.1.7: +object.entries@^1.1.8: version "1.1.8" resolved "https://registry.yarnpkg.com/object.entries/-/object.entries-1.1.8.tgz#bffe6f282e01f4d17807204a24f8edd823599c41" integrity sha512-cmopxi8VwRIAw/fkijJohSfpef5PdN0pMQJN6VC/ZKvn0LIknWD8KtgY6KlQdEc4tIjcQ3HxSMmnvtzIscdaYQ== @@ -5070,7 +5033,7 @@ object.entries@^1.1.7: define-properties "^1.2.1" es-object-atoms "^1.0.0" -object.fromentries@^2.0.7: +object.fromentries@^2.0.8: version "2.0.8" resolved "https://registry.yarnpkg.com/object.fromentries/-/object.fromentries-2.0.8.tgz#f7195d8a9b97bd95cbc1999ea939ecd1a2b00c65" integrity sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ== @@ -5080,7 +5043,7 @@ object.fromentries@^2.0.7: es-abstract "^1.23.2" es-object-atoms "^1.0.0" -object.groupby@^1.0.1: +object.groupby@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/object.groupby/-/object.groupby-1.0.3.tgz#9b125c36238129f6f7b61954a1e7176148d5002e" integrity sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ== @@ -5089,16 +5052,7 @@ object.groupby@^1.0.1: define-properties "^1.2.1" es-abstract "^1.23.2" -object.hasown@^1.1.3: - version "1.1.4" - resolved "https://registry.yarnpkg.com/object.hasown/-/object.hasown-1.1.4.tgz#e270ae377e4c120cdcb7656ce66884a6218283dc" - integrity sha512-FZ9LZt9/RHzGySlBARE3VF+gE26TxR38SdmqOqliuTnl9wrKulaQs+4dee1V+Io8VfxqzAfHu6YuRgUy8OHoTg== - dependencies: - define-properties "^1.2.1" - es-abstract "^1.23.2" - es-object-atoms "^1.0.0" - -object.values@^1.1.6, object.values@^1.1.7: +object.values@^1.1.6, object.values@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/object.values/-/object.values-1.2.0.tgz#65405a9d92cee68ac2d303002e0b8470a4d9ab1b" integrity sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ== @@ -5252,9 +5206,9 @@ path-scurry@^1.6.1: minipass "^5.0.0 || ^6.0.2 || ^7.0.0" path-to-regexp@^1.7.0: - version "1.8.0" - resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" - integrity sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA== + version "1.9.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.9.0.tgz#5dc0753acbf8521ca2e0f137b4578b917b10cf24" + integrity sha512-xIp7/apCFJuUHdDLWe8O1HIkb0kQrOMb/0u6FXQjemHn/ii5LrIzU6bdECnsiTF/GjZkMEKg1xdiZwNqDYlZ6g== dependencies: isarray "0.0.1" @@ -5268,10 +5222,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== -picocolors@^1.0.0, picocolors@^1.0.1: - version "1.0.1" - resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.1.tgz#a8ad579b571952f0e5d25892de5445bcfe25aaa1" - integrity sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew== +picocolors@^1.0.0, picocolors@^1.0.1, picocolors@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.1.0.tgz#5358b76a78cde483ba5cef6a9dc9671440b27d59" + integrity sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw== picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" @@ -5465,14 +5419,14 @@ postcss-value-parser@^4.1.0, postcss-value-parser@^4.2.0: resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514" integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ== -postcss@8.4.41, postcss@^8.0.0, postcss@^8.4.19, postcss@^8.4.21, postcss@^8.4.23: - version "8.4.41" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.41.tgz#d6104d3ba272d882fe18fc07d15dc2da62fa2681" - integrity sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ== +postcss@8.4.47, postcss@^8.0.0, postcss@^8.4.19, postcss@^8.4.21, postcss@^8.4.23, postcss@^8.4.32: + version "8.4.47" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.47.tgz#5bf6c9a010f3e724c503bf03ef7947dcb0fea365" + integrity sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ== dependencies: nanoid "^3.3.7" - picocolors "^1.0.1" - source-map-js "^1.2.0" + picocolors "^1.1.0" + source-map-js "^1.2.1" postcss@^6.0.23: version "6.0.23" @@ -5542,14 +5496,7 @@ punycode@^2.1.0, punycode@^2.1.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.3.1.tgz#027422e2faec0b25e1549c3e1bd8309b9133b6e5" integrity sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg== -qs@6.11.1: - version "6.11.1" - resolved "https://registry.yarnpkg.com/qs/-/qs-6.11.1.tgz#6c29dff97f0c0060765911ba65cbc9764186109f" - integrity sha512-0wsrzgTz/kAVIeuxSjnpGC56rzYtr6JT/2BwEvMaPhFIoYa1aGO8LbzuU1R0uUYQkLpWBTOj0l/CLAJB64J6nQ== - dependencies: - side-channel "^1.0.4" - -qs@^6.4.0: +qs@6.13.0, qs@^6.4.0: version "6.13.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.13.0.tgz#6ca3bd58439f7e245655798997787b0d88a51906" integrity sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg== @@ -5910,6 +5857,11 @@ readdir-glob@^1.1.2: dependencies: minimatch "^5.1.0" +readdirp@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-4.0.2.tgz#388fccb8b75665da3abffe2d8f8ed59fe74c230a" + integrity sha512-yDMz9g+VaZkqBYS/ozoBJwaBhTbZo3UNYQHNRw1D3UFQB8oHB4uS/tAODO+ZLjGWmUbKnIlOWO+aaIiAxrUWHA== + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -5983,10 +5935,10 @@ reflect.getprototypeof@^1.0.4: globalthis "^1.0.3" which-builtin-type "^1.1.3" -regenerate-unicode-properties@^10.1.0: - version "10.1.1" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.1.tgz#6b0e05489d9076b04c436f318d9b067bba459480" - integrity sha512-X007RyZLsCJVVrjgEFVpLUTZwyOZk3oiL75ZcuYjlIWd6rNJtOjkBwQc5AsRrpbKVkxN6sklw/k/9m2jJYOf8Q== +regenerate-unicode-properties@^10.2.0: + version "10.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.2.0.tgz#626e39df8c372338ea9b8028d1f99dc3fd9c3db0" + integrity sha512-DqHn3DwbmmPVzeKj9woBadqmXxLvQoQIwu7nopMc72ztvxVmVk2SBhSnx67zuye5TP+lJsb/TBQsjLKhnDf3MA== dependencies: regenerate "^1.4.2" @@ -6013,33 +5965,38 @@ regenerator-transform@^0.15.2: "@babel/runtime" "^7.8.4" regexp.prototype.flags@^1.5.1, regexp.prototype.flags@^1.5.2: - version "1.5.2" - resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz#138f644a3350f981a858c44f6bb1a61ff59be334" - integrity sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw== + version "1.5.3" + resolved "https://registry.yarnpkg.com/regexp.prototype.flags/-/regexp.prototype.flags-1.5.3.tgz#b3ae40b1d2499b8350ab2c3fe6ef3845d3a96f42" + integrity sha512-vqlC04+RQoFalODCbCumG2xIOvapzVMHwsyIGM/SIE8fRhFFsXeH8/QQ+s0T0kDAhKc4k30s73/0ydkHQz6HlQ== dependencies: - call-bind "^1.0.6" + call-bind "^1.0.7" define-properties "^1.2.1" es-errors "^1.3.0" - set-function-name "^2.0.1" + set-function-name "^2.0.2" -regexpu-core@^5.3.1: - version "5.3.2" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.3.2.tgz#11a2b06884f3527aec3e93dbbf4a3b958a95546b" - integrity sha512-RAM5FlZz+Lhmo7db9L298p2vHP5ZywrVXmVXpmAD9GuL5MPH6t9ROw1iA/wfHkQ76Qe7AaPF0nGuim96/IrQMQ== +regexpu-core@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.1.1.tgz#b469b245594cb2d088ceebc6369dceb8c00becac" + integrity sha512-k67Nb9jvwJcJmVpw0jPttR1/zVfnKf8Km0IPatrU/zJ5XeG3+Slx0xLXs9HByJSzXzrlz5EDvN6yLNMDc2qdnw== dependencies: - "@babel/regjsgen" "^0.8.0" regenerate "^1.4.2" - regenerate-unicode-properties "^10.1.0" - regjsparser "^0.9.1" + regenerate-unicode-properties "^10.2.0" + regjsgen "^0.8.0" + regjsparser "^0.11.0" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" -regjsparser@^0.9.1: - version "0.9.1" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.9.1.tgz#272d05aa10c7c1f67095b1ff0addae8442fc5709" - integrity sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ== +regjsgen@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" + integrity sha512-RvwtGe3d7LvWiDQXeQw8p5asZUmfU1G/l6WbUXeHta7Y2PEIvBTwH6E2EfmYUK8pxcxEdEmaomqyp0vZZ7C+3Q== + +regjsparser@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.11.1.tgz#ae55c74f646db0c8fcb922d4da635e33da405149" + integrity sha512-1DHODs4B8p/mQHU9kr+jv8+wIC9mtG4eBHxWxIq5mhjE3D5oORhCc6deRKzTjs9DcfRFmj9BHSDguZklqCGFWQ== dependencies: - jsesc "~0.5.0" + jsesc "~3.0.2" relateurl@^0.2.7: version "0.2.7" @@ -6207,11 +6164,11 @@ safe-regex-test@^1.0.3: integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== sass@^1.58.3: - version "1.77.8" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.77.8.tgz#9f18b449ea401759ef7ec1752a16373e296b52bd" - integrity sha512-4UHg6prsrycW20fqLGPShtEvo/WyHRVRHwOP4DzkUrObWoWI05QBSfzU71TVB7PFaL104TwNaHpjlWXAZbQiNQ== + version "1.79.4" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.79.4.tgz#f9c45af35fbeb53d2c386850ec842098d9935267" + integrity sha512-K0QDSNPXgyqO4GZq2HO5Q70TLxTH6cIT59RdoCHMivrC8rqzaTw5ab9prjz9KUN1El4FLXrBXJhik61JR4HcGg== dependencies: - chokidar ">=3.0.0 <4.0.0" + chokidar "^4.0.0" immutable "^4.0.0" source-map-js ">=0.6.2 <2.0.0" @@ -6364,10 +6321,10 @@ slice-ansi@^4.0.0: astral-regex "^2.0.0" is-fullwidth-code-point "^3.0.0" -"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.0.tgz#16b809c162517b5b8c3e7dcd315a2a5c2612b2af" - integrity sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg== +"source-map-js@>=0.6.2 <2.0.0", source-map-js@^1.0.1, source-map-js@^1.0.2, source-map-js@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.2.1.tgz#1ce5650fddd87abc099eda37dcff024c2667ae46" + integrity sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA== source-map-support@~0.5.20: version "0.5.21" @@ -6387,7 +6344,7 @@ source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.0: resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g== -source-map@^0.7.3: +source-map@^0.7.3, source-map@^0.7.4: version "0.7.4" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.4.tgz#a9bbe705c9d8846f4e08ff6765acf0f1b0898656" integrity sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA== @@ -6474,7 +6431,7 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" -string.prototype.matchall@^4.0.10: +string.prototype.matchall@^4.0.11: version "4.0.11" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" integrity sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg== @@ -6492,6 +6449,14 @@ string.prototype.matchall@^4.0.10: set-function-name "^2.0.2" side-channel "^1.0.6" +string.prototype.repeat@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz#e90872ee0308b29435aa26275f6e1b762daee01a" + integrity sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w== + dependencies: + define-properties "^1.1.3" + es-abstract "^1.17.5" + string.prototype.trim@^1.2.9: version "1.2.9" resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz#b6fa326d72d2c78b6df02f7759c73f8f6274faa4" @@ -6580,12 +6545,12 @@ style-search@^0.1.0: resolved "https://registry.yarnpkg.com/style-search/-/style-search-0.1.0.tgz#7958c793e47e32e07d2b5cafe5c0bf8e12e77902" integrity sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg== -stylelint-order@6.0.3: - version "6.0.3" - resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-6.0.3.tgz#160b78650bd90463241b992581efee7159baefc2" - integrity sha512-1j1lOb4EU/6w49qZeT2SQVJXm0Ht+Qnq9GMfUa3pMwoyojIWfuA+JUDmoR97Bht1RLn4ei0xtLGy87M7d29B1w== +stylelint-order@6.0.4: + version "6.0.4" + resolved "https://registry.yarnpkg.com/stylelint-order/-/stylelint-order-6.0.4.tgz#3e80d876c61a98d2640de181433686f24284748b" + integrity sha512-0UuKo4+s1hgQ/uAxlYU4h0o0HS4NiQDud0NAUNI0aa8FJdmYHA5ZZTFHiV5FpmE3071e9pZx5j0QpVJW5zOCUA== dependencies: - postcss "^8.4.21" + postcss "^8.4.32" postcss-sorting "^8.0.2" stylelint@15.6.1: @@ -6731,18 +6696,7 @@ tar-stream@^2.2.0: inherits "^2.0.3" readable-stream "^3.1.1" -terser-webpack-plugin@5.3.9: - version "5.3.9" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz#832536999c51b46d468067f9e37662a3b96adfe1" - integrity sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA== - dependencies: - "@jridgewell/trace-mapping" "^0.3.17" - jest-worker "^27.4.5" - schema-utils "^3.1.1" - serialize-javascript "^6.0.1" - terser "^5.16.8" - -terser-webpack-plugin@^5.3.7: +terser-webpack-plugin@5.3.10, terser-webpack-plugin@^5.3.10: version "5.3.10" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-5.3.10.tgz#904f4c9193c6fd2a03f693a2150c62a92f40d199" integrity sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w== @@ -6753,10 +6707,10 @@ terser-webpack-plugin@^5.3.7: serialize-javascript "^6.0.1" terser "^5.26.0" -terser@^5.10.0, terser@^5.16.8, terser@^5.26.0: - version "5.31.6" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.31.6.tgz#c63858a0f0703988d0266a82fcbf2d7ba76422b1" - integrity sha512-PQ4DAriWzKj+qgehQ7LK5bQqCFNMmlhjR2PFFLuqGCpuCAauxemVBWwWOxo3UIwWQx8+Pr61Df++r76wDmkQBg== +terser@^5.10.0, terser@^5.26.0: + version "5.34.1" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.34.1.tgz#af40386bdbe54af0d063e0670afd55c3105abeb6" + integrity sha512-FsJZ7iZLd/BXkz+4xrRTGJ26o/6VTjQytUk8b8OxkwcD2I+79VPJlz7qss1+zE7h8GNIScFqXcDyJ/KqBYZFVA== dependencies: "@jridgewell/source-map" "^0.3.3" acorn "^8.8.2" @@ -6856,15 +6810,16 @@ ts-api-utils@^1.0.1: resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== -ts-loader@9.4.2: - version "9.4.2" - resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.4.2.tgz#80a45eee92dd5170b900b3d00abcfa14949aeb78" - integrity sha512-OmlC4WVmFv5I0PpaxYb+qGeGOdm5giHU7HwDDUjw59emP2UYMHy9fFSDcYgSNoH8sXcj4hGCSEhlDZ9ULeDraA== +ts-loader@9.5.1: + version "9.5.1" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-9.5.1.tgz#63d5912a86312f1fbe32cef0859fb8b2193d9b89" + integrity sha512-rNH3sK9kGZcH9dYzC7CewQm4NtxJTjSEVRJ2DyBZR7f8/wcta+iV44UPCXc5+nzDzivKtlzV6c9P4e+oFhDLYg== dependencies: chalk "^4.1.0" enhanced-resolve "^5.0.0" micromatch "^4.0.0" semver "^7.3.4" + source-map "^0.7.4" tsconfig-paths@^3.15.0: version "3.15.0" @@ -7008,20 +6963,15 @@ unbox-primitive@^1.0.2: has-symbols "^1.0.3" which-boxed-primitive "^1.0.2" -undici-types@~5.26.4: - version "5.26.5" - resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-5.26.5.tgz#bcd539893d00b56e964fd2657a4866b221a65617" - integrity sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA== - undici-types@~6.19.2: version "6.19.8" resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.19.8.tgz#35111c9d1437ab83a7cdc0abae2f26d88eda0a02" integrity sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw== unicode-canonical-property-names-ecmascript@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" - integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== + version "2.0.1" + resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz#cb3173fe47ca743e228216e4a3ddc4c84d628cc2" + integrity sha512-dA8WbNeb2a6oQzAQ55YlT5vQAWGV9WXOsi3SskE3bcCdM0P4SDd+24zS/OCacdRq5BkdsRj9q3Pg6YyQoxIGqg== unicode-match-property-ecmascript@^2.0.0: version "2.0.0" @@ -7032,9 +6982,9 @@ unicode-match-property-ecmascript@^2.0.0: unicode-property-aliases-ecmascript "^2.0.0" unicode-match-property-value-ecmascript@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.1.0.tgz#cb5fffdcd16a05124f5a4b0bf7c3770208acbbe0" - integrity sha512-qxkjQt6qjg/mYscYMC0XKRn3Rh0wFPlfxB0xkt9CfyTvpX1Ra0+rAmdX2QyAobptSEvuy4RtpPRui6XkV+8wjA== + version "2.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-2.2.0.tgz#a0401aee72714598f739b68b104e4fe3a0cb3c71" + integrity sha512-4IehN3V/+kkr5YeSSDDQG8QLqO26XpL2XP3GQtqwlT/QYSECAwFztxVHjlbh0+gjJ3XmNLS0zDsbgs9jWKExLg== unicode-property-aliases-ecmascript@^2.0.0: version "2.1.0" @@ -7052,12 +7002,12 @@ universalify@^2.0.0: integrity sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw== update-browserslist-db@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.0.tgz#7ca61c0d8650766090728046e416a8cde682859e" - integrity sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ== + version "1.1.1" + resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.1.1.tgz#80846fba1d79e82547fb661f8d141e0945755fe5" + integrity sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A== dependencies: - escalade "^3.1.2" - picocolors "^1.0.1" + escalade "^3.2.0" + picocolors "^1.1.0" uri-js@^4.2.2: version "4.4.1" @@ -7164,7 +7114,7 @@ warning@^4.0.2, warning@^4.0.3: dependencies: loose-envify "^1.0.0" -watchpack@^2.4.0: +watchpack@^2.4.1: version "2.4.2" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-2.4.2.tgz#2feeaed67412e7c33184e5a79ca738fbd38564da" integrity sha512-TnbFSbcOCcDgjZ4piURLCbJ3nJhznVh9kw6F6iokjiFPl8ONxe9A6nMDVXDiNbrSfLILs6vB07F7wLBrwPYzJw== @@ -7220,34 +7170,33 @@ webpack-sources@^3.2.3: resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-3.2.3.tgz#2d4daab8451fd4b240cc27055ff6a0c2ccea0cde" integrity sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w== -webpack@5.88.2: - version "5.88.2" - resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.88.2.tgz#f62b4b842f1c6ff580f3fcb2ed4f0b579f4c210e" - integrity sha512-JmcgNZ1iKj+aiR0OvTYtWQqJwq37Pf683dY9bVORwVbUrDhLhdn/PlO2sHsFHPkj7sHNQF3JwaAkp49V+Sq1tQ== +webpack@5.95.0: + version "5.95.0" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-5.95.0.tgz#8fd8c454fa60dad186fbe36c400a55848307b4c0" + integrity sha512-2t3XstrKULz41MNMBF+cJ97TyHdyQ8HCt//pqErqDvNjU9YQBnZxIHa11VXsi7F3mb5/aO2tuDxdeTPdU7xu9Q== dependencies: - "@types/eslint-scope" "^3.7.3" - "@types/estree" "^1.0.0" - "@webassemblyjs/ast" "^1.11.5" - "@webassemblyjs/wasm-edit" "^1.11.5" - "@webassemblyjs/wasm-parser" "^1.11.5" + "@types/estree" "^1.0.5" + "@webassemblyjs/ast" "^1.12.1" + "@webassemblyjs/wasm-edit" "^1.12.1" + "@webassemblyjs/wasm-parser" "^1.12.1" acorn "^8.7.1" - acorn-import-assertions "^1.9.0" - browserslist "^4.14.5" + acorn-import-attributes "^1.9.5" + browserslist "^4.21.10" chrome-trace-event "^1.0.2" - enhanced-resolve "^5.15.0" + enhanced-resolve "^5.17.1" es-module-lexer "^1.2.1" eslint-scope "5.1.1" events "^3.2.0" glob-to-regexp "^0.4.1" - graceful-fs "^4.2.9" + graceful-fs "^4.2.11" json-parse-even-better-errors "^2.3.1" loader-runner "^4.2.0" mime-types "^2.1.27" neo-async "^2.6.2" schema-utils "^3.2.0" tapable "^2.1.1" - terser-webpack-plugin "^5.3.7" - watchpack "^2.4.0" + terser-webpack-plugin "^5.3.10" + watchpack "^2.4.1" webpack-sources "^3.2.3" websocket-driver@>=0.5.1: From 64122b4cfb3bf53bdbf5c924baee5e1b0814501a Mon Sep 17 00:00:00 2001 From: Steel City Phantom Date: Wed, 9 Oct 2024 19:41:07 -0400 Subject: [PATCH 005/579] Auto-detect building on macOS ARM (#10539) --- src/Directory.Build.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 174d1cb8a2..1e722177f0 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -221,7 +221,7 @@ <_UsingDefaultRuntimeIdentifier>true - osx-x64 + osx-$(Architecture) From f90b43b3e1c7d938eaaf290148b488d3b814968a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 03:23:00 +0300 Subject: [PATCH 006/579] Simplify parsing IMDb and TMDb urls as search terms --- src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 2cf794c878..6428b1e1f0 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -406,14 +406,16 @@ public List SearchForNewMovie(string title) { try { - var match = new Regex("^https://www.imdb.com/title/(tt[0-9]+).*?$").Match(title); + var match = new Regex(@"\bimdb\.com/title/(tt\d{7,})\b", RegexOptions.IgnoreCase).Match(title); + if (match.Success) { title = "imdb:" + match.Groups[1].Value; } else { - match = new Regex("^https://www.themoviedb.org/movie/([0-9]+).*$").Match(title); + match = new Regex(@"\bthemoviedb\.org/movie/(\d+)\b", RegexOptions.IgnoreCase).Match(title); + if (match.Success) { title = "tmdb:" + match.Groups[1].Value; From 9928d711a3bb72d40c99541bfc530eb7bcad811b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 15:26:00 +0300 Subject: [PATCH 007/579] Trim multiple occurrences of ending separators in filename --- src/NzbDrone.Core/Organizer/FileNameBuilder.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index f726a9349a..c600e2c69e 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -45,7 +45,7 @@ public class FileNameBuilder : IBuildFileNames RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled); - private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]$", RegexOptions.Compiled); + private static readonly Regex TrimSeparatorsRegex = new Regex(@"[- ._]+$", RegexOptions.Compiled); private static readonly Regex ScenifyRemoveChars = new Regex(@"(?<=\s)(,|<|>|\/|\\|;|:|'|""|\||`|’|~|!|\?|@|$|%|^|\*|-|_|=){1}(?=\s)|('|`|’|:|\?|,)(?=(?:(?:s|m|t|ve|ll|d|re)\s)|\s|$)|(\(|\)|\[|\]|\{|\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex ScenifyReplaceChars = new Regex(@"[\/]", RegexOptions.Compiled | RegexOptions.IgnoreCase); From 430719baacd6cf97ec2eb8a64d77efa0aefbe32d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 18:55:46 +0300 Subject: [PATCH 008/579] Remove unused gulp packages --- package.json | 3 - yarn.lock | 165 +-------------------------------------------------- 2 files changed, 3 insertions(+), 165 deletions(-) diff --git a/package.json b/package.json index 64553d56c8..ef5ecc1a16 100644 --- a/package.json +++ b/package.json @@ -42,7 +42,6 @@ "filesize": "10.1.6", "fuse.js": "6.6.2", "history": "4.10.1", - "https-browserify": "1.0.0", "jdu": "1.0.0", "jquery": "3.7.1", "lodash": "4.17.21", @@ -136,8 +135,6 @@ "prettier": "2.8.8", "require-nocache": "1.0.0", "rimraf": "4.4.1", - "run-sequence": "2.2.1", - "streamqueue": "1.1.2", "style-loader": "3.3.2", "stylelint": "15.6.1", "stylelint-order": "6.0.4", diff --git a/yarn.lock b/yarn.lock index 56028eb8d7..7d9e338631 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1888,42 +1888,11 @@ ajv@^8.0.0, ajv@^8.0.1, ajv@^8.9.0: json-schema-traverse "^1.0.0" require-from-string "^2.0.2" -ansi-cyan@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-cyan/-/ansi-cyan-0.1.1.tgz#538ae528af8982f28ae30d86f2f17456d2609873" - integrity sha512-eCjan3AVo/SxZ0/MyIYRtkpxIu/H3xZN7URr1vXVrISxeyz8fUFz0FJziamK4sS8I+t35y4rHg1b2PklyBe/7A== - dependencies: - ansi-wrap "0.1.0" - -ansi-gray@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-gray/-/ansi-gray-0.1.1.tgz#2962cf54ec9792c48510a3deb524436861ef7251" - integrity sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw== - dependencies: - ansi-wrap "0.1.0" - -ansi-red@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/ansi-red/-/ansi-red-0.1.1.tgz#8c638f9d1080800a353c9c28c8a81ca4705d946c" - integrity sha512-ewaIr5y+9CUTGFwZfpECUbFlGcC0GCw1oqR9RI6h1gQCd9Aj2GxSckCnPsVJnmfMZbwFYE+leZGASgkWl06Jow== - dependencies: - ansi-wrap "0.1.0" - -ansi-regex@^2.0.0: - version "2.1.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" - integrity sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA== - ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== -ansi-styles@^2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" - integrity sha512-kmCevFghRiWM7HB5zTPULl4r9bVFSWjz62MhqizDGUrq2NWuNMQyuv4tHHoKJHs69M/MF64lEcHdYIocrdWQYA== - ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1938,11 +1907,6 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" -ansi-wrap@0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/ansi-wrap/-/ansi-wrap-0.1.0.tgz#a82250ddb0015e9a27ca82e82ea603bbfa45efaf" - integrity sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw== - anymatch@^3.0.0, anymatch@^3.1.1, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -2001,24 +1965,6 @@ argparse@^2.0.1: resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== -arr-diff@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-1.1.0.tgz#687c32758163588fef7de7b36fabe495eb1a399a" - integrity sha512-OQwDZUqYaQwyyhDJHThmzId8daf4/RFNLaeh3AevmSeZ5Y7ug4Ga/yKc6l6kTZOBW781rCj103ZuTh8GAsB3+Q== - dependencies: - arr-flatten "^1.0.1" - array-slice "^0.2.3" - -arr-flatten@^1.0.1: - version "1.1.0" - resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" - integrity sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg== - -arr-union@^2.0.1: - version "2.1.0" - resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-2.1.0.tgz#20f9eab5ec70f5c7d215b1077b1c39161d292c7d" - integrity sha512-t5db90jq+qdgk8aFnxEkjqta0B/GHrM1pxzuuZz2zWsOXc5nKu3t+76s/PQBA8FTcM/ipspIH9jWG4OxCBc2eA== - array-buffer-byte-length@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz#1e5583ec16763540a27ae52eed99ff899223568f" @@ -2039,11 +1985,6 @@ array-includes@^3.1.6, array-includes@^3.1.8: get-intrinsic "^1.2.4" is-string "^1.0.7" -array-slice@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/array-slice/-/array-slice-0.2.3.tgz#dd3cfb80ed7973a75117cdac69b0b99ec86186f5" - integrity sha512-rlVfZW/1Ph2SNySXwR9QYkChp8EkOEiTMO5Vwx60usw04i4nWemkm9RXmQqgkQFaLHsqLuADvjp6IfgL9l2M8Q== - array-union@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/array-union/-/array-union-2.1.0.tgz#b798420adbeb1de828d84acd8a2e23d3efe85e8d" @@ -2366,17 +2307,6 @@ caniuse-lite@^1.0.30001646, caniuse-lite@^1.0.30001663: resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001667.tgz#99fc5ea0d9c6e96897a104a8352604378377f949" integrity sha512-7LTwJjcRkzKFmtqGsibMeuXmvFDfZq/nzIjnmgCGzKKRVzjD72selLDK1oPF/Oxzmt4fNcPvTDvGqSDG4tCALw== -chalk@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" - integrity sha512-U3lRVLMSlsCfjqYPbLyVv11M9CPW4I728d6TCKMAOJueEeB9/8o+eSsMnxPJD+Q+K909sdESg7C+tIkoH6on1A== - dependencies: - ansi-styles "^2.2.1" - escape-string-regexp "^1.0.2" - has-ansi "^2.0.0" - strip-ansi "^3.0.0" - supports-color "^2.0.0" - chalk@^2.4.1, chalk@^2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -2488,11 +2418,6 @@ color-string@^0.3.0: dependencies: color-name "^1.0.0" -color-support@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" - integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== - color@^0.11.0: version "0.11.4" resolved "https://registry.yarnpkg.com/color/-/color-0.11.4.tgz#6d7b5c74fb65e841cd48792ad1ed5e07b904d764" @@ -3161,7 +3086,7 @@ escalade@^3.2.0: resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.2.0.tgz#011a3f69856ba189dffa7dc8fcce99d2a87903e5" integrity sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA== -escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg== @@ -3399,23 +3324,6 @@ eventsource@^1.0.7: resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-1.1.2.tgz#bc75ae1c60209e7cb1541231980460343eaea7c2" integrity sha512-xAH3zWhgO2/3KIniEKYPr8plNSzlGINOUqYj0m0u7AB81iRw8b/3E73W6AuU+6klLbaSFmZnaETQ2lXPfAydrA== -extend-shallow@^1.1.2: - version "1.1.4" - resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-1.1.4.tgz#19d6bf94dfc09d76ba711f39b872d21ff4dd9071" - integrity sha512-L7AGmkO6jhDkEBBGWlLtftA80Xq8DipnrRPr0pyi7GQLXkaq9JYA4xF4z6qnadIC6euiTDKco0cGSU9muw+WTw== - dependencies: - kind-of "^1.1.0" - -fancy-log@^1.3.2: - version "1.3.3" - resolved "https://registry.yarnpkg.com/fancy-log/-/fancy-log-1.3.3.tgz#dbc19154f558690150a23953a0adbd035be45fc7" - integrity sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw== - dependencies: - ansi-gray "^0.1.1" - color-support "^1.1.3" - parse-node-version "^1.0.0" - time-stamp "^1.0.0" - fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" @@ -3812,13 +3720,6 @@ hard-rejection@^2.1.0: resolved "https://registry.yarnpkg.com/hard-rejection/-/hard-rejection-2.1.0.tgz#1c6eda5c1685c63942766d79bb40ae773cecd883" integrity sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA== -has-ansi@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" - integrity sha512-C8vBJ8DwUCx19vhm7urhTuUsr4/IyP6l4VzNQDv+ryHQObW3TTTp9yB68WpYgRe2bbaGuZ/se74IqFeVnMnLZg== - dependencies: - ansi-regex "^2.0.0" - has-bigints@^1.0.1, has-bigints@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa" @@ -3945,11 +3846,6 @@ http-parser-js@>=0.5.1: resolved "https://registry.yarnpkg.com/http-parser-js/-/http-parser-js-0.5.8.tgz#af23090d9ac4e24573de6f6aecc9d84a48bf20e3" integrity sha512-SGeBX54F94Wgu5RH3X5jsDtf4eHyRogWX1XGT3b4HuW3tQPM4AaBzoUji/4AAJNXCEOWZ5O0DgZmJw1947gD5Q== -https-browserify@1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" - integrity sha512-J+FkSdyD+0mA0N+81tMotaRMfSL9SGi+xpD3T6YApKsc3bGSXJlfXri3VyFOeYkfLRQisDk1W+jIFFKBeUBbBg== - iconv-lite@^0.6.3: version "0.6.3" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.6.3.tgz#a52f80bf38da1952eb5c681790719871a1a72501" @@ -4304,11 +4200,6 @@ isobject@^3.0.1: resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" integrity sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg== -isstream@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" - integrity sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g== - iterator.prototype@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/iterator.prototype/-/iterator.prototype-1.1.3.tgz#016c2abe0be3bbdb8319852884f60908ac62bf9c" @@ -4434,11 +4325,6 @@ keyv@^4.5.3: dependencies: json-buffer "3.0.1" -kind-of@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-1.1.0.tgz#140a3d2d41a36d2efcfa9377b62c24f8495a5c44" - integrity sha512-aUH6ElPnMGon2/YkxRIigV32MOpTVcoXQ1Oo8aYn40s+sJ3j+0gFZsT8HKDcxNy7Fi9zuquWtGaGAahOdv5p/g== - kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" @@ -5159,7 +5045,7 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" -parse-node-version@^1.0.0, parse-node-version@^1.0.1: +parse-node-version@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-node-version/-/parse-node-version-1.0.1.tgz#e2b5dbede00e7fa9bc363607f53327e8b073189b" integrity sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA== @@ -5251,17 +5137,6 @@ pkg-dir@^7.0.0: dependencies: find-up "^6.3.0" -plugin-error@^0.1.2: - version "0.1.2" - resolved "https://registry.yarnpkg.com/plugin-error/-/plugin-error-0.1.2.tgz#3b9bb3335ccf00f425e07437e19276967da47ace" - integrity sha512-WzZHcm4+GO34sjFMxQMqZbsz3xiNEgonCskQ9v+IroMmYgk/tas8dG+Hr2D6IbRPybZ12oWpzE/w3cGJ6FJzOw== - dependencies: - ansi-cyan "^0.1.1" - ansi-red "^0.1.1" - arr-diff "^1.0.1" - arr-union "^2.0.1" - extend-shallow "^1.1.2" - popper.js@^1.14.4: version "1.16.1" resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.16.1.tgz#2a223cb3dc7b6213d740e40372be40de43e65b1b" @@ -5828,7 +5703,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -readable-stream@^2.0.0, readable-stream@^2.0.5, readable-stream@^2.3.3: +readable-stream@^2.0.0, readable-stream@^2.0.5: version "2.3.8" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== @@ -6115,15 +5990,6 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" -run-sequence@2.2.1: - version "2.2.1" - resolved "https://registry.yarnpkg.com/run-sequence/-/run-sequence-2.2.1.tgz#1ce643da36fd8c7ea7e1a9329da33fc2b8898495" - integrity sha512-qkzZnQWMZjcKbh3CNly2srtrkaO/2H/SI5f2eliMCapdRD3UhMrwjfOAZJAnZ2H8Ju4aBzFZkBGXUqFs9V0yxw== - dependencies: - chalk "^1.1.3" - fancy-log "^1.3.2" - plugin-error "^0.1.2" - safe-array-concat@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/safe-array-concat/-/safe-array-concat-1.1.2.tgz#81d77ee0c4e8b863635227c721278dd524c20edb" @@ -6409,14 +6275,6 @@ stacktrace-js@2.0.2: stack-generator "^2.0.5" stacktrace-gps "^3.0.4" -streamqueue@1.1.2: - version "1.1.2" - resolved "https://registry.yarnpkg.com/streamqueue/-/streamqueue-1.1.2.tgz#6c99c7c20d62b57f5819296bf9ec942542380192" - integrity sha512-CHUpqa+1BM99z7clQz9W6L9ZW4eXRRQCR0H+utVAGGvNo2ePlJAFjhdK0IjunaBbY/gWKJawk5kpJeyz0EXxRA== - dependencies: - isstream "^0.1.2" - readable-stream "^2.3.3" - string-template@~0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" @@ -6504,13 +6362,6 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^3.0.0: - version "3.0.1" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" - integrity sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg== - dependencies: - ansi-regex "^2.0.0" - strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" @@ -6617,11 +6468,6 @@ sugarss@^4.0.1: resolved "https://registry.yarnpkg.com/sugarss/-/sugarss-4.0.1.tgz#128a783ed71ee0fc3b489ce1f7d5a89bc1e24383" integrity sha512-WCjS5NfuVJjkQzK10s8WOBY+hhDxxNt/N6ZaGwxFZ+wN3/lKKFSaaKUNecULcTTvE4urLcKaZFQD8vO0mOZujw== -supports-color@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" - integrity sha512-KKNVtd6pCYgPIKU4cp2733HWYCpplQhddZLBUryaAHou723x+FRzQ5Df824Fj+IyyuiQTRoub4SnIFfIcrp70g== - supports-color@^5.3.0, supports-color@^5.4.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -6722,11 +6568,6 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== -time-stamp@^1.0.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/time-stamp/-/time-stamp-1.1.0.tgz#764a5a11af50561921b133f3b44e618687e0f5c3" - integrity sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw== - tiny-invariant@^1.0.2: version "1.3.3" resolved "https://registry.yarnpkg.com/tiny-invariant/-/tiny-invariant-1.3.3.tgz#46680b7a873a0d5d10005995eb90a70d74d60127" From 3c995a0fff4caf8e68e398dc263887c06211a84f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 19:00:05 +0300 Subject: [PATCH 009/579] Bump babel packages --- package.json | 27 +-- yarn.lock | 658 ++++++++++++++++++++++----------------------------- 2 files changed, 301 insertions(+), 384 deletions(-) diff --git a/package.json b/package.json index ef5ecc1a16..e2de8190b1 100644 --- a/package.json +++ b/package.json @@ -56,13 +56,13 @@ "react-async-script": "1.2.0", "react-autosuggest": "10.1.0", "react-custom-scrollbars-2": "4.5.0", - "react-dnd": "14.0.2", - "react-dnd-html5-backend": "14.0.0", + "react-dnd": "14.0.4", + "react-dnd-html5-backend": "14.0.2", "react-dnd-multi-backend": "6.0.2", - "react-dnd-touch-backend": "14.0.0", + "react-dnd-touch-backend": "14.1.1", "react-document-title": "2.0.3", "react-dom": "17.0.2", - "react-focus-lock": "2.5.0", + "react-focus-lock": "2.9.4", "react-google-recaptcha": "2.1.0", "react-lazyload": "3.2.0", "react-measure": "1.4.7", @@ -71,27 +71,27 @@ "react-router": "5.2.0", "react-router-dom": "5.2.0", "react-slider": "1.1.4", - "react-tabs": "3.2.2", - "react-text-truncate": "0.18.0", + "react-tabs": "4.3.0", + "react-text-truncate": "0.19.0", "react-use-measure": "2.1.1", "react-virtualized": "9.21.1", - "react-window": "1.8.9", + "react-window": "1.8.10", "redux": "4.2.1", "redux-actions": "2.6.5", "redux-batched-actions": "0.5.0", "redux-localstorage": "0.4.1", - "redux-thunk": "2.3.0", + "redux-thunk": "2.4.2", "reselect": "4.1.8", "stacktrace-js": "2.0.2", "swiper": "8.3.2", "typescript": "5.1.6" }, "devDependencies": { - "@babel/core": "7.25.7", - "@babel/eslint-parser": "7.25.7", - "@babel/plugin-proposal-export-default-from": "7.25.7", + "@babel/core": "7.25.8", + "@babel/eslint-parser": "7.25.8", + "@babel/plugin-proposal-export-default-from": "7.25.8", "@babel/plugin-syntax-dynamic-import": "7.8.3", - "@babel/preset-env": "7.25.7", + "@babel/preset-env": "7.25.8", "@babel/preset-react": "7.25.7", "@babel/preset-typescript": "7.25.7", "@types/lodash": "4.14.195", @@ -114,7 +114,6 @@ "eslint-config-prettier": "8.10.0", "eslint-plugin-filenames": "1.3.2", "eslint-plugin-import": "2.31.0", - "eslint-plugin-json": "3.1.0", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-react": "7.37.1", "eslint-plugin-react-hooks": "4.6.2", @@ -134,7 +133,7 @@ "postcss-url": "10.1.3", "prettier": "2.8.8", "require-nocache": "1.0.0", - "rimraf": "4.4.1", + "rimraf": "6.0.1", "style-loader": "3.3.2", "stylelint": "15.6.1", "stylelint-order": "6.0.4", diff --git a/yarn.lock b/yarn.lock index 7d9e338631..8e2abbbd8e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -23,15 +23,15 @@ "@babel/highlight" "^7.25.7" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.7.tgz#b8479fe0018ef0ac87b6b7a5c6916fcd67ae2c9c" - integrity sha512-9ickoLz+hcXCeh7jrcin+/SLWm+GkxE2kTvoYyp38p4WkdFXfQJxDFGWp/YHjiKLPx06z2A7W8XKuqbReXDzsw== +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7", "@babel/compat-data@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402" + integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA== -"@babel/core@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.7.tgz#1b3d144157575daf132a3bc80b2b18e6e3ca6ece" - integrity sha512-yJ474Zv3cwiSOO9nXJuqzvwEeM+chDuQ8GJirw+pZ91sCGCyOZ3dJkVE09fTV0VEVzXyLWhh3G/AolYTPX7Mow== +"@babel/core@7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6" + integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg== dependencies: "@ampproject/remapping" "^2.2.0" "@babel/code-frame" "^7.25.7" @@ -39,20 +39,20 @@ "@babel/helper-compilation-targets" "^7.25.7" "@babel/helper-module-transforms" "^7.25.7" "@babel/helpers" "^7.25.7" - "@babel/parser" "^7.25.7" + "@babel/parser" "^7.25.8" "@babel/template" "^7.25.7" "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/types" "^7.25.8" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.7.tgz#27b43de786c83cbabbcb328efbb4f099ae85415e" - integrity sha512-B+BO9x86VYsQHimucBAL1fxTJKF4wyKY6ZVzee9QgzdZOUfs3BaR6AQrgoGrRI+7IFS1wUz/VyQ+SoBcSpdPbw== +"@babel/eslint-parser@7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.8.tgz#0119dec46be547d7a339978dedb9d29e517c2443" + integrity sha512-Po3VLMN7fJtv0nsOjBDSbO1J71UhzShE9MuOSkWEV9IZQXzhZklYtzKZ8ZD/Ij3a0JBv1AG3Ny2L3jvAHQVOGg== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" @@ -160,7 +160,7 @@ dependencies: "@babel/types" "^7.25.7" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.12.13", "@babel/helper-plugin-utils@^7.14.5", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== @@ -241,12 +241,12 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.7.tgz#99b927720f4ddbfeb8cd195a363ed4532f87c590" - integrity sha512-aZn7ETtQsjjGG5HruveUK06cU3Hljuhd9Iojm4M8WWv3wLE6OkE5PWbDUkItmMgegmccaITudyuW5RPYrYlgWw== +"@babel/parser@^7.25.7", "@babel/parser@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" + integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== dependencies: - "@babel/types" "^7.25.7" + "@babel/types" "^7.25.8" "@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7": version "7.25.7" @@ -287,61 +287,25 @@ "@babel/helper-plugin-utils" "^7.25.7" "@babel/traverse" "^7.25.7" -"@babel/plugin-proposal-export-default-from@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.25.7.tgz#7ed72dbdc834bc841953858664008ad30a6653d3" - integrity sha512-Egdiuy7pLTyaPkIr6rItNyFVbblTmx3VgqY+72KiS9BzcA+SMyrS9zSumQeSANo8uE3Kax0ZUMkpNh0Q+mbNwg== +"@babel/plugin-proposal-export-default-from@7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.25.8.tgz#fa22151caa240683c3659796037237813767f348" + integrity sha512-5SLPHA/Gk7lNdaymtSVS9jH77Cs7yuHTR3dYj+9q+M7R7tNLXhNuvnmOfafRIzpWL+dtMibuu1I4ofrc768Gkw== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-export-default-from" "^7.25.7" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-property-in-object/-/plugin-proposal-private-property-in-object-7.21.0-placeholder-for-preset-env.2.tgz#7844f9289546efa9febac2de4cfe358a050bd703" integrity sha512-SOSkfJDddaM7mak6cPEpswyTRnuRltl429hMraQEglW+OkovnCzsiszTmsrlY//qLFjCpQDFRvjdm2wA5pPm9w== -"@babel/plugin-syntax-async-generators@^7.8.4": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" - integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-class-properties@^7.12.13": - version "7.12.13" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz#b5c987274c4a3a82b89714796931a6b53544ae10" - integrity sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA== - dependencies: - "@babel/helper-plugin-utils" "^7.12.13" - -"@babel/plugin-syntax-class-static-block@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-static-block/-/plugin-syntax-class-static-block-7.14.5.tgz#195df89b146b4b78b3bf897fd7a257c84659d406" - integrity sha512-b+YyPmr6ldyNnM6sqYeMWE+bgJcJpO6yS4QD7ymxgH34GBPNDM/THBh8iunyvKIZztiwLH4CJZ0RxTk9emgpjw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-dynamic-import@7.8.3", "@babel/plugin-syntax-dynamic-import@^7.8.3": +"@babel/plugin-syntax-dynamic-import@7.8.3": version "7.8.3" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-export-default-from@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.25.7.tgz#3e05205c62303fe088f6b7073e5c143a669c26f4" - integrity sha512-LRUCsC0YucSjabsmxx6yly8+Q/5mxKdp9gemlpR9ro3bfpcOQOXx/CHivs7QCbjgygd6uQ2GcRfHu1FVax/hgg== - dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - -"@babel/plugin-syntax-export-namespace-from@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" - integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.3" - "@babel/plugin-syntax-import-assertions@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f" @@ -356,20 +320,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-syntax-import-meta@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" - integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-json-strings@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" - integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - "@babel/plugin-syntax-jsx@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165" @@ -377,62 +327,6 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" - integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" - integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-numeric-separator@^7.10.4": - version "7.10.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" - integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== - dependencies: - "@babel/helper-plugin-utils" "^7.10.4" - -"@babel/plugin-syntax-object-rest-spread@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" - integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" - integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-optional-chaining@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" - integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== - dependencies: - "@babel/helper-plugin-utils" "^7.8.0" - -"@babel/plugin-syntax-private-property-in-object@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-private-property-in-object/-/plugin-syntax-private-property-in-object-7.14.5.tgz#0dc6671ec0ea22b6e94a1114f857970cd39de1ad" - integrity sha512-0wVnp9dxJ72ZUJDV27ZfbSj6iHLoytYZmh3rFcxNnvsJF3ktkzLDZPy/mA17HGsaQT3/DQsWYX1f1QGWkCoVUg== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - -"@babel/plugin-syntax-top-level-await@^7.14.5": - version "7.14.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz#c1cfdadc35a646240001f06138247b741c34d94c" - integrity sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/plugin-syntax-typescript@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" @@ -455,14 +349,13 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-async-generator-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.7.tgz#af61a02b30d7bff5108c63bd39ac7938403426d7" - integrity sha512-4B6OhTrwYKHYYgcwErvZjbmH9X5TxQBsaBHdzEIB4l71gR5jh/tuHGlb9in47udL2+wVUcOz5XXhhfhVJwEpEg== +"@babel/plugin-transform-async-generator-functions@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz#3331de02f52cc1f2c75b396bec52188c85b0b1ec" + integrity sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA== dependencies: "@babel/helper-plugin-utils" "^7.25.7" "@babel/helper-remap-async-to-generator" "^7.25.7" - "@babel/plugin-syntax-async-generators" "^7.8.4" "@babel/traverse" "^7.25.7" "@babel/plugin-transform-async-to-generator@^7.25.7": @@ -496,14 +389,13 @@ "@babel/helper-create-class-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-class-static-block@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.7.tgz#d2cf3c812e3b3162d56aadf4566f45c30538cb2c" - integrity sha512-rvUUtoVlkDWtDWxGAiiQj0aNktTPn3eFynBcMC2IhsXweehwgdI9ODe+XjWw515kEmv22sSOTp/rxIRuTiB7zg== +"@babel/plugin-transform-class-static-block@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz#a8af22028920fe404668031eceb4c3aadccb5262" + integrity sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ== dependencies: "@babel/helper-create-class-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-class-static-block" "^7.14.5" "@babel/plugin-transform-classes@^7.25.7": version "7.25.7" @@ -555,13 +447,12 @@ "@babel/helper-create-regexp-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-dynamic-import@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.7.tgz#31905ab2cfa94dcf1b1f8ce66096720b2908e518" - integrity sha512-UvcLuual4h7/GfylKm2IAA3aph9rwvAM2XBA0uPKU3lca+Maai4jBjjEVUS568ld6kJcgbouuumCBhMd/Yz17w== +"@babel/plugin-transform-dynamic-import@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz#f1edbe75b248cf44c70c8ca8ed3818a668753aaa" + integrity sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-transform-exponentiation-operator@^7.25.7": version "7.25.7" @@ -571,13 +462,12 @@ "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-export-namespace-from@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.7.tgz#beb2679db6fd3bdfe6ad6de2c8cac84a86ef2da1" - integrity sha512-h3MDAP5l34NQkkNulsTNyjdaR+OiB0Im67VU//sFupouP8Q6m9Spy7l66DcaAQxtmCqGdanPByLsnwFttxKISQ== +"@babel/plugin-transform-export-namespace-from@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz#d1988c3019a380b417e0516418b02804d3858145" + integrity sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-transform-for-of@^7.25.7": version "7.25.7" @@ -596,13 +486,12 @@ "@babel/helper-plugin-utils" "^7.25.7" "@babel/traverse" "^7.25.7" -"@babel/plugin-transform-json-strings@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.7.tgz#6626433554aff4bd6f76a2c621a1f40e802dfb0a" - integrity sha512-Ot43PrL9TEAiCe8C/2erAjXMeVSnE/BLEx6eyrKLNFCCw5jvhTHKyHxdI1pA0kz5njZRYAnMO2KObGqOCRDYSA== +"@babel/plugin-transform-json-strings@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz#6fb3ec383a2ea92652289fdba653e3f9de722694" + integrity sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-json-strings" "^7.8.3" "@babel/plugin-transform-literals@^7.25.7": version "7.25.7" @@ -611,13 +500,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-logical-assignment-operators@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.7.tgz#93847feb513a1f191c5f5d903d991a0ee24fe99b" - integrity sha512-iImzbA55BjiovLyG2bggWS+V+OLkaBorNvc/yJoeeDQGztknRnDdYfp2d/UPmunZYEnZi6Lg8QcTmNMHOB0lGA== +"@babel/plugin-transform-logical-assignment-operators@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz#01868ff92daa9e525b4c7902aa51979082a05710" + integrity sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" "@babel/plugin-transform-member-expression-literals@^7.25.7": version "7.25.7" @@ -676,30 +564,27 @@ dependencies: "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-nullish-coalescing-operator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.7.tgz#0af84b86d4332654c43cf028dbdcf878b00ac168" - integrity sha512-FbuJ63/4LEL32mIxrxwYaqjJxpbzxPVQj5a+Ebrc8JICV6YX8nE53jY+K0RZT3um56GoNWgkS2BQ/uLGTjtwfw== +"@babel/plugin-transform-nullish-coalescing-operator@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz#befb4900c130bd52fccf2b926314557987f1b552" + integrity sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" -"@babel/plugin-transform-numeric-separator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.7.tgz#a516b78f894d1c08283f39d809b2048fd2f29448" - integrity sha512-8CbutzSSh4hmD+jJHIA8vdTNk15kAzOnFLVVgBSMGr28rt85ouT01/rezMecks9pkU939wDInImwCKv4ahU4IA== +"@babel/plugin-transform-numeric-separator@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz#91e370486371637bd42161052f2602c701386891" + integrity sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" -"@babel/plugin-transform-object-rest-spread@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.7.tgz#fa0916521be96fd434e2db59780b24b308c6d169" - integrity sha512-1JdVKPhD7Y5PvgfFy0Mv2brdrolzpzSoUq2pr6xsR+m+3viGGeHEokFKsCgOkbeFOQxfB1Vt2F0cPJLRpFI4Zg== +"@babel/plugin-transform-object-rest-spread@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz#0904ac16bcce41df4db12d915d6780f85c7fb04b" + integrity sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g== dependencies: "@babel/helper-compilation-targets" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" "@babel/plugin-transform-parameters" "^7.25.7" "@babel/plugin-transform-object-super@^7.25.7": @@ -710,22 +595,20 @@ "@babel/helper-plugin-utils" "^7.25.7" "@babel/helper-replace-supers" "^7.25.7" -"@babel/plugin-transform-optional-catch-binding@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.7.tgz#400e2d891f9288f5231694234696aa67164e4913" - integrity sha512-m9obYBA39mDPN7lJzD5WkGGb0GO54PPLXsbcnj1Hyeu8mSRz7Gb4b1A6zxNX32ZuUySDK4G6it8SDFWD1nCnqg== +"@babel/plugin-transform-optional-catch-binding@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz#2649b86a3bb202c6894ec81a6ddf41b94d8f3103" + integrity sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg== dependencies: "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-transform-optional-chaining@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.7.tgz#b7f7c9321aa1d8414e67799c28d87c23682e4d68" - integrity sha512-h39agClImgPWg4H8mYVAbD1qP9vClFbEjqoJmt87Zen8pjqK8FTPUwrOXAvqu5soytwxrLMd2fx2KSCp2CHcNg== +"@babel/plugin-transform-optional-chaining@^7.25.7", "@babel/plugin-transform-optional-chaining@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz#f46283b78adcc5b6ab988a952f989e7dce70653f" + integrity sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg== dependencies: "@babel/helper-plugin-utils" "^7.25.7" "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-transform-parameters@^7.25.7": version "7.25.7" @@ -742,15 +625,14 @@ "@babel/helper-create-class-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" -"@babel/plugin-transform-private-property-in-object@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.7.tgz#aff877efd05b57c4ad04611d8de97bf155a53369" - integrity sha512-LzA5ESzBy7tqj00Yjey9yWfs3FKy4EmJyKOSWld144OxkTji81WWnUT8nkLUn+imN/zHL8ZQlOu/MTUAhHaX3g== +"@babel/plugin-transform-private-property-in-object@^7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz#1234f856ce85e061f9688764194e51ea7577c434" + integrity sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow== dependencies: "@babel/helper-annotate-as-pure" "^7.25.7" "@babel/helper-create-class-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" "@babel/plugin-transform-property-literals@^7.25.7": version "7.25.7" @@ -885,12 +767,12 @@ "@babel/helper-create-regexp-features-plugin" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" -"@babel/preset-env@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.7.tgz#fc1b092152db4b58377b85dc05c890081c1157e0" - integrity sha512-Gibz4OUdyNqqLj+7OAvBZxOD7CklCtMA5/j0JgUEwOnaRULsPDXmic2iKxL2DX2vQduPR5wH2hjZas/Vr/Oc0g== +"@babel/preset-env@7.25.8": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.8.tgz#dc6b719627fb29cd9cccbbbe041802fd575b524c" + integrity sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg== dependencies: - "@babel/compat-data" "^7.25.7" + "@babel/compat-data" "^7.25.8" "@babel/helper-compilation-targets" "^7.25.7" "@babel/helper-plugin-utils" "^7.25.7" "@babel/helper-validator-option" "^7.25.7" @@ -900,45 +782,30 @@ "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7" "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" "@babel/plugin-syntax-import-assertions" "^7.25.7" "@babel/plugin-syntax-import-attributes" "^7.25.7" - "@babel/plugin-syntax-import-meta" "^7.10.4" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" "@babel/plugin-transform-arrow-functions" "^7.25.7" - "@babel/plugin-transform-async-generator-functions" "^7.25.7" + "@babel/plugin-transform-async-generator-functions" "^7.25.8" "@babel/plugin-transform-async-to-generator" "^7.25.7" "@babel/plugin-transform-block-scoped-functions" "^7.25.7" "@babel/plugin-transform-block-scoping" "^7.25.7" "@babel/plugin-transform-class-properties" "^7.25.7" - "@babel/plugin-transform-class-static-block" "^7.25.7" + "@babel/plugin-transform-class-static-block" "^7.25.8" "@babel/plugin-transform-classes" "^7.25.7" "@babel/plugin-transform-computed-properties" "^7.25.7" "@babel/plugin-transform-destructuring" "^7.25.7" "@babel/plugin-transform-dotall-regex" "^7.25.7" "@babel/plugin-transform-duplicate-keys" "^7.25.7" "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7" - "@babel/plugin-transform-dynamic-import" "^7.25.7" + "@babel/plugin-transform-dynamic-import" "^7.25.8" "@babel/plugin-transform-exponentiation-operator" "^7.25.7" - "@babel/plugin-transform-export-namespace-from" "^7.25.7" + "@babel/plugin-transform-export-namespace-from" "^7.25.8" "@babel/plugin-transform-for-of" "^7.25.7" "@babel/plugin-transform-function-name" "^7.25.7" - "@babel/plugin-transform-json-strings" "^7.25.7" + "@babel/plugin-transform-json-strings" "^7.25.8" "@babel/plugin-transform-literals" "^7.25.7" - "@babel/plugin-transform-logical-assignment-operators" "^7.25.7" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.8" "@babel/plugin-transform-member-expression-literals" "^7.25.7" "@babel/plugin-transform-modules-amd" "^7.25.7" "@babel/plugin-transform-modules-commonjs" "^7.25.7" @@ -946,15 +813,15 @@ "@babel/plugin-transform-modules-umd" "^7.25.7" "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7" "@babel/plugin-transform-new-target" "^7.25.7" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.7" - "@babel/plugin-transform-numeric-separator" "^7.25.7" - "@babel/plugin-transform-object-rest-spread" "^7.25.7" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.8" + "@babel/plugin-transform-numeric-separator" "^7.25.8" + "@babel/plugin-transform-object-rest-spread" "^7.25.8" "@babel/plugin-transform-object-super" "^7.25.7" - "@babel/plugin-transform-optional-catch-binding" "^7.25.7" - "@babel/plugin-transform-optional-chaining" "^7.25.7" + "@babel/plugin-transform-optional-catch-binding" "^7.25.8" + "@babel/plugin-transform-optional-chaining" "^7.25.8" "@babel/plugin-transform-parameters" "^7.25.7" "@babel/plugin-transform-private-methods" "^7.25.7" - "@babel/plugin-transform-private-property-in-object" "^7.25.7" + "@babel/plugin-transform-private-property-in-object" "^7.25.8" "@babel/plugin-transform-property-literals" "^7.25.7" "@babel/plugin-transform-regenerator" "^7.25.7" "@babel/plugin-transform-reserved-words" "^7.25.7" @@ -1035,10 +902,10 @@ debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.25.7", "@babel/types@^7.4.4": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.7.tgz#1b7725c1d3a59f328cb700ce704c46371e6eef9b" - integrity sha512-vwIVdXG+j+FOpkwqHRcBgHLYNL7XMkufrlaFvL9o6Ai9sJn9+PdyIL5qa0XzTZw084c+u9LOls53eoZWP/W5WQ== +"@babel/types@^7.25.7", "@babel/types@^7.25.8", "@babel/types@^7.4.4": + version "7.25.8" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" + integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== dependencies: "@babel/helper-string-parser" "^7.25.7" "@babel/helper-validator-identifier" "^7.25.7" @@ -1165,6 +1032,18 @@ resolved "https://registry.yarnpkg.com/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz#4a2868d75d6d6963e423bcf90b7fd1be343409d3" integrity sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA== +"@isaacs/cliui@^8.0.2": + version "8.0.2" + resolved "https://registry.yarnpkg.com/@isaacs/cliui/-/cliui-8.0.2.tgz#b37667b7bc181c168782259bab42474fbf52b550" + integrity sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA== + dependencies: + string-width "^5.1.2" + string-width-cjs "npm:string-width@^4.2.0" + strip-ansi "^7.0.1" + strip-ansi-cjs "npm:strip-ansi@^6.0.1" + wrap-ansi "^8.1.0" + wrap-ansi-cjs "npm:wrap-ansi@^7.0.0" + "@jridgewell/gen-mapping@^0.3.5": version "0.3.5" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz#dcce6aff74bdf6dad1a95802b69b04a2fcb1fb36" @@ -1893,6 +1772,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-regex@^6.0.1: + version "6.1.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-6.1.0.tgz#95ec409c69619d6cb1b8b34f14b660ef28ebd654" + integrity sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -1907,6 +1791,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +ansi-styles@^6.1.0: + version "6.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-6.2.1.tgz#0e62320cf99c21afff3b3012192546aacbfb05c5" + integrity sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug== + anymatch@^3.0.0, anymatch@^3.1.1, anymatch@~3.1.2: version "3.1.3" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.3.tgz#790c58b19ba1720a84205b57c618d5ad8524973e" @@ -2571,7 +2460,7 @@ create-react-context@^0.3.0: gud "^1.0.0" warning "^4.0.3" -cross-spawn@^7.0.2, cross-spawn@^7.0.3: +cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== @@ -2781,14 +2670,14 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -dnd-core@14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-14.0.0.tgz#973ab3470d0a9ac5a0fa9021c4feba93ad12347d" - integrity sha512-wTDYKyjSqWuYw3ZG0GJ7k+UIfzxTNoZLjDrut37PbcPGNfwhlKYlPUqjAKUjOOv80izshUiqusaKgJPItXSevA== +dnd-core@14.0.1: + version "14.0.1" + resolved "https://registry.yarnpkg.com/dnd-core/-/dnd-core-14.0.1.tgz#76d000e41c494983210fb20a48b835f81a203c2e" + integrity sha512-+PVS2VPTgKFPYWo3vAFEA8WPbTf7/xo43TifH9G8S1KqnrQu0o77A3unrF5yOugy4mIz7K5wAVFHUcha7wsz6A== dependencies: "@react-dnd/asap" "^4.0.0" "@react-dnd/invariant" "^2.0.0" - redux "^4.0.5" + redux "^4.1.1" dnd-multi-backend@^6.0.0: version "6.0.0" @@ -2882,6 +2771,11 @@ dotenv@^16.0.3: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.4.5.tgz#cdd3b3b604cb327e286b4762e13502f717cb099f" integrity sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg== +eastasianwidth@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" + integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== + electron-to-chromium@^1.5.28: version "1.5.35" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.35.tgz#1d38d386186c72b1fa6e74c3a7de5f888b503100" @@ -2897,6 +2791,11 @@ emoji-regex@^8.0.0: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-8.0.0.tgz#e818fd69ce5ccfcb404594f842963bf53164cc37" integrity sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A== +emoji-regex@^9.2.2: + version "9.2.2" + resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-9.2.2.tgz#840c8803b0d8047f4ff0cf963176b32d4ef3ed72" + integrity sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg== + emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -3152,14 +3051,6 @@ eslint-plugin-import@2.31.0: string.prototype.trimend "^1.0.8" tsconfig-paths "^3.15.0" -eslint-plugin-json@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-json/-/eslint-plugin-json-3.1.0.tgz#251108ba1681c332e0a442ef9513bd293619de67" - integrity sha512-MrlG2ynFEHe7wDGwbUuFPsaT2b1uhuEFhJ+W1f1u+1C2EkXmTYJp4B1aAdQQ8M+CC3t//N/oRKiIVw14L2HR1g== - dependencies: - lodash "^4.17.21" - vscode-json-languageservice "^4.1.6" - eslint-plugin-prettier@4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" @@ -3478,12 +3369,12 @@ flatted@^3.2.9: resolved "https://registry.yarnpkg.com/flatted/-/flatted-3.3.1.tgz#21db470729a6734d4997002f439cb308987f567a" integrity sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw== -focus-lock@^0.8.1: - version "0.8.1" - resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.8.1.tgz#bb36968abf77a2063fa173cb6c47b12ac8599d33" - integrity sha512-/LFZOIo82WDsyyv7h7oc0MJF9ACOvDRdx9rWPZ2pgMfNWu/z8hQDBtOchuB/0BVLmuFOZjV02YwUVzNsWx/EzA== +focus-lock@^0.11.6: + version "0.11.6" + resolved "https://registry.yarnpkg.com/focus-lock/-/focus-lock-0.11.6.tgz#e8821e21d218f03e100f7dc27b733f9c4f61e683" + integrity sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg== dependencies: - tslib "^1.9.3" + tslib "^2.0.3" for-each@^0.3.3: version "0.3.3" @@ -3492,6 +3383,14 @@ for-each@^0.3.3: dependencies: is-callable "^1.1.3" +foreground-child@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/foreground-child/-/foreground-child-3.3.0.tgz#0ac8644c06e431439f8561db8ecf29a7b5519c77" + integrity sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg== + dependencies: + cross-spawn "^7.0.0" + signal-exit "^4.0.1" + fork-ts-checker-webpack-plugin@8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-8.0.0.tgz#dae45dfe7298aa5d553e2580096ced79b6179504" @@ -3618,6 +3517,18 @@ glob-to-regexp@^0.4.1: resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz#c75297087c851b9a578bd217dd59a92f59fe546e" integrity sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw== +glob@^11.0.0: + version "11.0.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-11.0.0.tgz#6031df0d7b65eaa1ccb9b29b5ced16cea658e77e" + integrity sha512-9UiX/Bl6J2yaBbxKoEBRm4Cipxgok8kQYcOPEhScPwebu2I0HoQOuYdIO6S3hLuWoZgpDpwQZMzTFxgpkyT76g== + dependencies: + foreground-child "^3.1.0" + jackspeak "^4.0.1" + minimatch "^10.0.0" + minipass "^7.1.2" + package-json-from-dist "^1.0.0" + path-scurry "^2.0.0" + glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: version "7.2.3" resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.3.tgz#b8df0fb802bbfa8e89bd1d938b4e16578ed44f2b" @@ -3630,16 +3541,6 @@ glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@^7.2.3: once "^1.3.0" path-is-absolute "^1.0.0" -glob@^9.2.0: - version "9.3.5" - resolved "https://registry.yarnpkg.com/glob/-/glob-9.3.5.tgz#ca2ed8ca452781a3009685607fdf025a899dfe21" - integrity sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q== - dependencies: - fs.realpath "^1.0.0" - minimatch "^8.0.2" - minipass "^4.2.4" - path-scurry "^1.6.1" - global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -4211,6 +4112,13 @@ iterator.prototype@^1.1.3: reflect.getprototypeof "^1.0.4" set-function-name "^2.0.1" +jackspeak@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/jackspeak/-/jackspeak-4.0.2.tgz#11f9468a3730c6ff6f56823a820d7e3be9bef015" + integrity sha512-bZsjR/iRjl1Nk1UkjGpAzLNfQtzuijhn2g+pbZb98HQ1Gk8vM9hfbxeMBP+M2/UUdwj0RqGG3mlvk2MsAqwvEw== + dependencies: + "@isaacs/cliui" "^8.0.2" + jdu@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/jdu/-/jdu-1.0.0.tgz#28f1e388501785ae0a1d93e93ed0b14dd41e51ce" @@ -4289,11 +4197,6 @@ json5@^2.1.2, json5@^2.2.2, json5@^2.2.3: resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283" integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg== -jsonc-parser@^3.0.0: - version "3.3.1" - resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.3.1.tgz#f2a524b4f7fd11e3d791e559977ad60b98b798b4" - integrity sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ== - jsonfile@^6.0.1: version "6.1.0" resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-6.1.0.tgz#bc55b2634793c679ec6403094eb13698a6ec0aae" @@ -4551,10 +4454,10 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" -lru-cache@^10.2.0: - version "10.4.3" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-10.4.3.tgz#410fc8a17b70e598013df257c2446b7f3383f119" - integrity sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ== +lru-cache@^11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-11.0.1.tgz#3a732fbfedb82c5ba7bca6564ad3f42afcb6e147" + integrity sha512-CgeuL5uom6j/ZVrg7G/+1IXqRY8JXX4Hghfy5YE0EhoYQWvndP1kufu58cmZLNIDKnRhZrXfdS9urVWx98AipQ== lru-cache@^5.1.1: version "5.1.1" @@ -4703,6 +4606,13 @@ minimatch@9.0.3: dependencies: brace-expansion "^2.0.1" +minimatch@^10.0.0: + version "10.0.1" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" + integrity sha512-ethXTt3SGGR+95gudmqJ1eNhRO7eGEGIgYA9vnPatK4/etz2MEVDno5GMCibdMTuBMyElzIlgxMna3K94XDIDQ== + dependencies: + brace-expansion "^2.0.1" + minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -4717,13 +4627,6 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" -minimatch@^8.0.2: - version "8.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-8.0.4.tgz#847c1b25c014d4e9a7f68aaf63dedd668a626229" - integrity sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA== - dependencies: - brace-expansion "^2.0.1" - minimatch@~3.0.4: version "3.0.8" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" @@ -4745,12 +4648,7 @@ minimist@^1.2.0, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== -minipass@^4.2.4: - version "4.2.8" - resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.8.tgz#f0010f64393ecfc1d1ccb5f582bcaf45f48e1a3a" - integrity sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ== - -"minipass@^5.0.0 || ^6.0.2 || ^7.0.0": +minipass@^7.1.2: version "7.1.2" resolved "https://registry.yarnpkg.com/minipass/-/minipass-7.1.2.tgz#93a9626ce5e5e66bd4db86849e7515e92340a707" integrity sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw== @@ -5020,6 +4918,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +package-json-from-dist@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz#4f1471a010827a86f94cfd9b0727e36d267de505" + integrity sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw== + param-case@^3.0.4: version "3.0.4" resolved "https://registry.yarnpkg.com/param-case/-/param-case-3.0.4.tgz#7d17fe4aa12bde34d4a77d91acfb6219caad01c5" @@ -5083,13 +4986,13 @@ path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== -path-scurry@^1.6.1: - version "1.11.1" - resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.11.1.tgz#7960a668888594a0720b12a911d1a742ab9f11d2" - integrity sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA== +path-scurry@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-2.0.0.tgz#9f052289f23ad8bf9397a2a0425e7b8615c58580" + integrity sha512-ypGJsmGtdXUOeM5u93TyeIEfEhM6s+ljAhrk5vAvSx8uyY/02OvrZnA0YNGUrPXfpJMgI1ODd3nwz8Npx4O4cg== dependencies: - lru-cache "^10.2.0" - minipass "^5.0.0 || ^6.0.2 || ^7.0.0" + lru-cache "^11.0.0" + minipass "^7.1.2" path-to-regexp@^1.7.0: version "1.9.0" @@ -5441,7 +5344,7 @@ react-autosuggest@10.1.0: section-iterator "^2.0.0" shallow-equal "^1.2.1" -react-clientside-effect@^1.2.2: +react-clientside-effect@^1.2.6: version "1.2.6" resolved "https://registry.yarnpkg.com/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz#29f9b14e944a376b03fb650eed2a754dd128ea3a" integrity sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg== @@ -5457,12 +5360,12 @@ react-custom-scrollbars-2@4.5.0: prop-types "^15.5.10" raf "^3.1.0" -react-dnd-html5-backend@14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-14.0.0.tgz#28d660a2ad1e07447c34a65cd25f7de8f1657194" - integrity sha512-2wAQqRFC1hbRGmk6+dKhOXsyQQOn3cN8PSZyOUeOun9J8t3tjZ7PS2+aFu7CVu2ujMDwTJR3VTwZh8pj2kCv7g== +react-dnd-html5-backend@14.0.2: + version "14.0.2" + resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-14.0.2.tgz#25019388f6abdeeda3a6fea835dff155abb2085c" + integrity sha512-QgN6rYrOm4UUj6tIvN8ovImu6uP48xBXF2rzVsp6tvj6d5XQ7OjHI4SJ/ZgGobOneRAU3WCX4f8DGCYx0tuhlw== dependencies: - dnd-core "14.0.0" + dnd-core "14.0.1" react-dnd-multi-backend@6.0.2: version "6.0.2" @@ -5480,22 +5383,22 @@ react-dnd-preview@^6.0.2: dependencies: prop-types "^15.7.2" -react-dnd-touch-backend@14.0.0: - version "14.0.0" - resolved "https://registry.yarnpkg.com/react-dnd-touch-backend/-/react-dnd-touch-backend-14.0.0.tgz#f7f144ca4af17946e20cdfd06a766ebadd170d4d" - integrity sha512-fNt3isf9h0xgjj86dIXhBi3dJ7OhC88vKUYdEvsOGypdp3LOFD+TobBAuBu00v26WmJ6II6xqbkhOx+KOcyHxQ== +react-dnd-touch-backend@14.1.1: + version "14.1.1" + resolved "https://registry.yarnpkg.com/react-dnd-touch-backend/-/react-dnd-touch-backend-14.1.1.tgz#d8875ef1cf8dcbf1741a4e03dd5b147c4fbda5e4" + integrity sha512-ITmfzn3fJrkUBiVLO6aJZcnu7T8C+GfwZitFryGsXKn5wYcUv+oQBeh9FYcMychmVbDdeUCfvEtTk9O+DKmAaw== dependencies: "@react-dnd/invariant" "^2.0.0" - dnd-core "14.0.0" + dnd-core "14.0.1" -react-dnd@14.0.2: - version "14.0.2" - resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-14.0.2.tgz#57266baec92b887301f81fa3b77f87168d159733" - integrity sha512-JoEL78sBCg8SzjOKMlkR70GWaPORudhWuTNqJ56lb2P8Vq0eM2+er3ZrMGiSDhOmzaRPuA9SNBz46nHCrjn11A== +react-dnd@14.0.4: + version "14.0.4" + resolved "https://registry.yarnpkg.com/react-dnd/-/react-dnd-14.0.4.tgz#ffb4ea0e2a3a5532f9c6294d565742008a52b8b0" + integrity sha512-AFJJXzUIWp5WAhgvI85ESkDCawM0lhoVvfo/lrseLXwFdH3kEO3v8I2C81QPqBW2UEyJBIPStOhPMGYGFtq/bg== dependencies: "@react-dnd/invariant" "^2.0.0" "@react-dnd/shallowequal" "^2.0.0" - dnd-core "14.0.0" + dnd-core "14.0.1" fast-deep-equal "^3.1.3" hoist-non-react-statics "^3.3.2" @@ -5516,17 +5419,17 @@ react-dom@17.0.2: object-assign "^4.1.1" scheduler "^0.20.2" -react-focus-lock@2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.5.0.tgz#12e3a3940e897c26e2c2a0408cd25ea3c99b3709" - integrity sha512-XLxj6uTXgz0US8TmqNU2jMfnXwZG0mH2r/afQqvPEaX6nyEll5LHVcEXk2XDUQ34RVeLPkO/xK5x6c/qiuSq/A== +react-focus-lock@2.9.4: + version "2.9.4" + resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-2.9.4.tgz#4753f6dcd167c39050c9d84f9c63c71b3ff8462e" + integrity sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg== dependencies: "@babel/runtime" "^7.0.0" - focus-lock "^0.8.1" + focus-lock "^0.11.6" prop-types "^15.6.2" - react-clientside-effect "^1.2.2" - use-callback-ref "^1.2.1" - use-sidecar "^1.0.1" + react-clientside-effect "^1.2.6" + use-callback-ref "^1.3.0" + use-sidecar "^1.1.2" react-google-recaptcha@2.1.0: version "2.1.0" @@ -5626,18 +5529,18 @@ react-slider@1.1.4: resolved "https://registry.yarnpkg.com/react-slider/-/react-slider-1.1.4.tgz#08b55f9be3e04cc10ae00cc3aedb6891dffe9bf3" integrity sha512-lL/MvzFcDue0ztdJItwLqas2lOy8Gg46eCDGJc4cJGldThmBHcHfGQePgBgyY1SEN95OwsWAakd3SuI8RyixDQ== -react-tabs@3.2.2: - version "3.2.2" - resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-3.2.2.tgz#07bdc3cdb17bdffedd02627f32a93cd4b3d6e4d0" - integrity sha512-/o52eGKxFHRa+ssuTEgSM8qORnV4+k7ibW+aNQzKe+5gifeVz8nLxCrsI9xdRhfb0wCLdgIambIpb1qCxaMN+A== +react-tabs@4.3.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/react-tabs/-/react-tabs-4.3.0.tgz#9f4db0fd209ba4ab2c1e78993ff964435f84af62" + integrity sha512-2GfoG+f41kiBIIyd3gF+/GRCCYtamC8/2zlAcD8cqQmqI9Q+YVz7fJLHMmU9pXDVYYHpJeCgUSBJju85vu5q8Q== dependencies: clsx "^1.1.0" prop-types "^15.5.0" -react-text-truncate@0.18.0: - version "0.18.0" - resolved "https://registry.yarnpkg.com/react-text-truncate/-/react-text-truncate-0.18.0.tgz#c65f4be660d24734badb903a4832467eddcf8058" - integrity sha512-0cc07CRPRPm3cTloVbPicVTSosJNauwVcmJb5FPa71u4KtDVgrRPJoxVvLBubl3gLyx1pVUozgREYMHpHM16jg== +react-text-truncate@0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/react-text-truncate/-/react-text-truncate-0.19.0.tgz#60bc5ecf29a03ebc256f31f90a2d8402176aac91" + integrity sha512-QxHpZABfGG0Z3WEYbRTZ+rXdZn50Zvp+sWZXgVAd7FCKAMzv/kcwctTpNmWgXDTpAoHhMjOVwmgRtX3x5yeF4w== dependencies: prop-types "^15.5.7" @@ -5668,10 +5571,10 @@ react-virtualized@9.21.1: prop-types "^15.6.0" react-lifecycles-compat "^3.0.4" -react-window@1.8.9: - version "1.8.9" - resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.9.tgz#24bc346be73d0468cdf91998aac94e32bc7fa6a8" - integrity sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q== +react-window@1.8.10: + version "1.8.10" + resolved "https://registry.yarnpkg.com/react-window/-/react-window-1.8.10.tgz#9e6b08548316814b443f7002b1cf8fd3a1bdde03" + integrity sha512-Y0Cx+dnU6NLa5/EvoHukUD0BklJ8qITCtVEPY1C/nL8wwoZ0b5aEw8Ff1dOVHw7fCzMt55XfJDd8S8W8LCaUCg== dependencies: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" @@ -5785,12 +5688,12 @@ redux-localstorage@0.4.1: resolved "https://registry.yarnpkg.com/redux-localstorage/-/redux-localstorage-0.4.1.tgz#faf6d719c581397294d811473ffcedee065c933c" integrity sha512-dUha0YoH+BSZ2q15pakB+JWeqiuXUf3Ir4rObOpNrZ96HEdciGAjkL10k3KGdLI7qvQw/c096asw/SQ6TPjU/A== -redux-thunk@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.3.0.tgz#51c2c19a185ed5187aaa9a2d08b666d0d6467622" - integrity sha512-km6dclyFnmcvxhAcrQV2AkZmPQjzPDjgVlQtR0EQjxZPyJ0BnMf3in1ryuR8A2qU0HldVRfxYXbFSKlI3N7Slw== +redux-thunk@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b" + integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q== -redux@4.2.1, redux@^4.0.0, redux@^4.0.5: +redux@4.2.1, redux@^4.0.0, redux@^4.1.1: version "4.2.1" resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197" integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w== @@ -5969,12 +5872,13 @@ rgb@~0.1.0: resolved "https://registry.yarnpkg.com/rgb/-/rgb-0.1.0.tgz#be27b291e8feffeac1bd99729721bfa40fc037b5" integrity sha512-F49dXX73a92N09uQkfCp2QjwXpmJcn9/i9PvjmwsSIXUGqRLCf/yx5Q9gRxuLQTq248kakqQuc8GX/U/CxSqlA== -rimraf@4.4.1: - version "4.4.1" - resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.4.1.tgz#bd33364f67021c5b79e93d7f4fa0568c7c21b755" - integrity sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og== +rimraf@6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-6.0.1.tgz#ffb8ad8844dd60332ab15f52bc104bc3ed71ea4e" + integrity sha512-9dkvaxAsk/xNXSJzMgFqqMCuFgt2+KsOFek3TMLfo8NCPfWpBmqwyNn5Y+NX56QUYfCtsyhF3ayiboEoUmJk/A== dependencies: - glob "^9.2.0" + glob "^11.0.0" + package-json-from-dist "^1.0.0" rimraf@^3.0.2: version "3.0.2" @@ -6280,7 +6184,7 @@ string-template@~0.2.1: resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" integrity sha512-Yptehjogou2xm4UJbxJ4CxgZx12HBfeystp0y3x7s4Dj32ltVVG1Gg8YhKjHZkHicuKpZX/ffilA8505VbUbpw== -string-width@^4.2.3: +"string-width-cjs@npm:string-width@^4.2.0": version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -6289,6 +6193,24 @@ string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^4.1.0, string-width@^4.2.3: + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^5.0.1, string-width@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" + integrity sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA== + dependencies: + eastasianwidth "^0.2.0" + emoji-regex "^9.2.2" + strip-ansi "^7.0.1" + string.prototype.matchall@^4.0.11: version "4.0.11" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz#1092a72c59268d2abaad76582dccc687c0297e0a" @@ -6362,13 +6284,27 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" -strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== dependencies: ansi-regex "^5.0.1" +strip-ansi@^6.0.0, strip-ansi@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^7.0.1: + version "7.1.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" + integrity sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ== + dependencies: + ansi-regex "^6.0.1" + strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -6681,11 +6617,6 @@ tsconfig-paths@^4.1.2: minimist "^1.2.6" strip-bom "^3.0.0" -tslib@^1.9.3: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - tslib@^2.0.0, tslib@^2.0.3, tslib@^2.3.0: version "2.7.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.7.0.tgz#d9b40c5c40ab59e8738f297df3087bf1a2690c01" @@ -6874,14 +6805,14 @@ url-parse@^1.5.3: querystringify "^2.1.1" requires-port "^1.0.0" -use-callback-ref@^1.2.1: +use-callback-ref@^1.3.0: version "1.3.2" resolved "https://registry.yarnpkg.com/use-callback-ref/-/use-callback-ref-1.3.2.tgz#6134c7f6ff76e2be0b56c809b17a650c942b1693" integrity sha512-elOQwe6Q8gqZgDA8mrh44qRTQqpIHDcZ3hXTLjBe1i4ph8XpNJnO+aQf3NaG+lriLopI4HMx9VjQLfPQ6vhnoA== dependencies: tslib "^2.0.0" -use-sidecar@^1.0.1: +use-sidecar@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/use-sidecar/-/use-sidecar-1.1.2.tgz#2f43126ba2d7d7e117aa5855e5d8f0276dfe73c2" integrity sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw== @@ -6917,37 +6848,6 @@ value-equal@^1.0.1: resolved "https://registry.yarnpkg.com/value-equal/-/value-equal-1.0.1.tgz#1e0b794c734c5c0cade179c437d356d931a34d6c" integrity sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw== -vscode-json-languageservice@^4.1.6: - version "4.2.1" - resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.2.1.tgz#94b6f471ece193bf4a1ef37f6ab5cce86d50a8b4" - integrity sha512-xGmv9QIWs2H8obGbWg+sIPI/3/pFgj/5OWBhNzs00BkYQ9UaB2F6JJaGB/2/YOZJ3BvLXQTC4Q7muqU25QgAhA== - dependencies: - jsonc-parser "^3.0.0" - vscode-languageserver-textdocument "^1.0.3" - vscode-languageserver-types "^3.16.0" - vscode-nls "^5.0.0" - vscode-uri "^3.0.3" - -vscode-languageserver-textdocument@^1.0.3: - version "1.0.12" - resolved "https://registry.yarnpkg.com/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.12.tgz#457ee04271ab38998a093c68c2342f53f6e4a631" - integrity sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA== - -vscode-languageserver-types@^3.16.0: - version "3.17.5" - resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz#3273676f0cf2eab40b3f44d085acbb7f08a39d8a" - integrity sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg== - -vscode-nls@^5.0.0: - version "5.2.0" - resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-5.2.0.tgz#3cb6893dd9bd695244d8a024bdf746eea665cc3f" - integrity sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng== - -vscode-uri@^3.0.3: - version "3.0.8" - resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-3.0.8.tgz#1770938d3e72588659a172d0fd4642780083ff9f" - integrity sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw== - warning@^4.0.2, warning@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/warning/-/warning-4.0.3.tgz#16e9e077eb8a86d6af7d64aa1e05fd85b4678ca3" @@ -7144,6 +7044,24 @@ worker-loader@3.0.8: loader-utils "^2.0.0" schema-utils "^3.0.0" +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + +wrap-ansi@^8.1.0: + version "8.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214" + integrity sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ== + dependencies: + ansi-styles "^6.1.0" + string-width "^5.0.1" + strip-ansi "^7.0.1" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" From 0049922ab6809be48e96726a4f4006d711051b7d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 21:17:20 +0300 Subject: [PATCH 010/579] Include exception message in SkyHook failure message --- frontend/src/AddMovie/AddNewMovie/AddNewMovie.js | 4 +++- src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js index 29bdaa3130..c49a50a4e2 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js @@ -131,7 +131,9 @@ class AddNewMovie extends Component {
{translate('FailedLoadingSearchResults')}
- {getErrorMessage(error)} + + {getErrorMessage(error)} +
{translate('WhySearchesCouldBeFailing')} diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 6428b1e1f0..23adbfe6a8 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -534,17 +534,17 @@ public List SearchForNewMovie(string title) catch (HttpException ex) { _logger.Warn(ex); - throw new SkyHookException("Search for '{0}' failed. Unable to communicate with RadarrAPI.", ex, title); + throw new SkyHookException("Search for '{0}' failed. Unable to communicate with RadarrAPI. {1}", ex, title, ex.Message); } catch (WebException ex) { _logger.Warn(ex); - throw new SkyHookException("Search for '{0}' failed. Unable to communicate with RadarrAPI.", ex, title, ex.Message); + throw new SkyHookException("Search for '{0}' failed. Unable to communicate with RadarrAPI. {1}", ex, title, ex.Message); } catch (Exception ex) { _logger.Warn(ex); - throw new SkyHookException("Search for '{0}' failed. Invalid response received from RadarrAPI.", ex, title); + throw new SkyHookException("Search for '{0}' failed. Invalid response received from RadarrAPI. {1}", ex, title, ex.Message); } } From 889d0710046e34c7173b64067ecdd0a9ee5b177a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 22:39:11 +0300 Subject: [PATCH 011/579] New: Display items tags on import lists index --- .../ImportLists/ImportLists/ImportList.js | 18 ++++++++++++++---- .../ImportLists/ImportLists/ImportLists.js | 3 +++ .../ImportLists/ImportListsConnector.js | 9 ++++++++- 3 files changed, 25 insertions(+), 5 deletions(-) diff --git a/frontend/src/Settings/ImportLists/ImportLists/ImportList.js b/frontend/src/Settings/ImportLists/ImportLists/ImportList.js index bc51823938..6a8a3a4740 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/ImportList.js +++ b/frontend/src/Settings/ImportLists/ImportLists/ImportList.js @@ -3,6 +3,7 @@ import React, { Component } from 'react'; import Card from 'Components/Card'; import Label from 'Components/Label'; import ConfirmModal from 'Components/Modal/ConfirmModal'; +import TagList from 'Components/TagList'; import { kinds } from 'Helpers/Props'; import formatShortTimeSpan from 'Utilities/Date/formatShortTimeSpan'; import translate from 'Utilities/String/translate'; @@ -58,6 +59,8 @@ class ImportList extends Component { name, enabled, enableAuto, + tags, + tagList, minRefreshInterval } = this.props; @@ -72,7 +75,6 @@ class ImportList extends Component {
- { enabled ? : + null }
+ +
-
@@ -126,6 +134,8 @@ ImportList.propTypes = { name: PropTypes.string.isRequired, enabled: PropTypes.bool.isRequired, enableAuto: PropTypes.bool.isRequired, + tags: PropTypes.arrayOf(PropTypes.number).isRequired, + tagList: PropTypes.arrayOf(PropTypes.object).isRequired, minRefreshInterval: PropTypes.string.isRequired, onConfirmDeleteImportList: PropTypes.func.isRequired }; diff --git a/frontend/src/Settings/ImportLists/ImportLists/ImportLists.js b/frontend/src/Settings/ImportLists/ImportLists/ImportLists.js index 11fcceb541..b6f6e58377 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/ImportLists.js +++ b/frontend/src/Settings/ImportLists/ImportLists/ImportLists.js @@ -49,6 +49,7 @@ class ImportLists extends Component { render() { const { items, + tagList, onConfirmDeleteImportList, ...otherProps } = this.props; @@ -71,6 +72,7 @@ class ImportLists extends Component { ); @@ -109,6 +111,7 @@ ImportLists.propTypes = { isFetching: PropTypes.bool.isRequired, error: PropTypes.object, items: PropTypes.arrayOf(PropTypes.object).isRequired, + tagList: PropTypes.arrayOf(PropTypes.object).isRequired, onConfirmDeleteImportList: PropTypes.func.isRequired }; diff --git a/frontend/src/Settings/ImportLists/ImportLists/ImportListsConnector.js b/frontend/src/Settings/ImportLists/ImportLists/ImportListsConnector.js index 017467e535..633d4f2f7d 100644 --- a/frontend/src/Settings/ImportLists/ImportLists/ImportListsConnector.js +++ b/frontend/src/Settings/ImportLists/ImportLists/ImportListsConnector.js @@ -5,13 +5,20 @@ import { createSelector } from 'reselect'; import { fetchRootFolders } from 'Store/Actions/rootFolderActions'; import { deleteImportList, fetchImportLists } from 'Store/Actions/settingsActions'; import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; +import createTagsSelector from 'Store/Selectors/createTagsSelector'; import sortByProp from 'Utilities/Array/sortByProp'; import ImportLists from './ImportLists'; function createMapStateToProps() { return createSelector( createSortedSectionSelector('settings.importLists', sortByProp('name')), - (importLists) => importLists + createTagsSelector(), + (importLists, tagList) => { + return { + ...importLists, + tagList + }; + } ); } From 4f47bb39ac62b14e315eae5efb87624168b1dacf Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Oct 2024 18:58:59 +0300 Subject: [PATCH 012/579] Bump version to 5.13.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 60bc575251..1a085eb528 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.12.2' + majorVersion: '5.13.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 0761e27cfa73c68e18866a091066b517fa2ab780 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Oct 2024 19:15:21 +0300 Subject: [PATCH 013/579] New: Parse ES as Spanish --- .../ParserTests/LanguageParserFixture.cs | 3 +++ src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 10 ++++++++-- 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 724d0961e1..913221fb92 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -76,6 +76,9 @@ public void should_parse_language_french_english(string postTitle) [TestCase("Movie Title (2016) [UHDRemux 2160p SDR] [Castellano DD 5.1 - Inglés DTS-HD MA 5.1 Subs]")] [TestCase("Movie Title 2022 [HDTV 720p][Cap.101][AC3 5.1 Castellano][www.pctnew.ORG]")] [TestCase("Movie Title 2022 [HDTV 720p][Cap.206][AC3 5.1 Español Castellano]")] + [TestCase("Movie Title 2022 [Remux-1080p 8-bit h264 DTS-HD MA 2.0][ES.EN]-HiFi")] + [TestCase("Movie Title 2022 [BDRemux 1080p AVC ES DTS-HD MA 5.1 Subs][HDO].mkv")] + [TestCase("Movie.Name.2022.BluRay.1080p.H264.DTS[EN+ES].[EN+ES+IT]")] public void should_parse_language_spanish(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs index b4cdf77919..c226bdc53d 100644 --- a/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/ParserFixture.cs @@ -258,6 +258,7 @@ public void should_parse_tmdb_id(string postTitle, int tmdbId) [TestCase("The.Good.German.2006.720p.HDTV.x264-TVP", Description = "The Good German is hardcoded not to match")] [TestCase("German.Lancers.2019.720p.BluRay.x264-UNiVERSUM", Description = "German at the beginning is never matched")] [TestCase("The.German.2019.720p.BluRay.x264-UNiVERSUM", Description = "The German is hardcoded not to match")] + [TestCase("Movie Name (2016) BluRay 1080p DTS-ES AC3 x264-3Li", Description = "DTS-ES should not match ES (Spanish)")] public void should_not_parse_wrong_language_in_title(string postTitle) { var parsed = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 06fcc5ae07..4248779ccf 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -39,8 +39,9 @@ public static class LanguageParser private static readonly Regex CaseSensitiveLanguageRegex = new Regex(@"(?:(?i)(?\bLT\b)| (?\bCZ\b)| (?\bPL\b)| - (?\bBG\b))(?:(?i)(?![\W|_|^]SUB))| - (?\bSK\b)", + (?\bBG\b)| + (?\bSK\b)| + (?\b(? ParseLanguages(string title) { languages.Add(Language.Slovak); } + + if (match.Groups["spanish"].Captures.Any()) + { + languages.Add(Language.Spanish); + } } var matches = LanguageRegex.Matches(title); From 3287e7cdecbba2cec8bb58ce9aa1dd07bb2aa1fa Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 10 Oct 2024 15:27:11 +0300 Subject: [PATCH 014/579] Bump dotnet to 6.0.35 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1a085eb528..afe7c821a1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -15,7 +15,7 @@ variables: buildName: '$(Build.SourceBranchName).$(radarrVersion)' sentryOrg: 'servarr' sentryUrl: 'https://sentry.servarr.com' - dotnetVersion: '6.0.424' + dotnetVersion: '6.0.427' nodeVersion: '20.X' innoVersion: '6.2.2' windowsImage: 'windows-2022' From fb7656be5638bd5cf5b01bb9c06df39a14854040 Mon Sep 17 00:00:00 2001 From: costaht <50637431+costaht@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:59:42 -0300 Subject: [PATCH 015/579] New: Parse pt-BR releases as Brazilian Portuguese (#10554) * New: Match releases with pt-BR (BPC-47) with Portuguese Brazilian --- src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 913221fb92..50830ac953 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -191,6 +191,7 @@ public void should_parse_language_bulgarian(string postTitle) [TestCase("Movie.Title.1994.Dublado.1080p.XviD-LOL")] [TestCase("Movie.Title.2.2019.1080p.Bluray.Dublado.WWW.TPF.GRATIS")] [TestCase("Movie.Title.2014.1080p.Bluray.Brazilian.WWW.TPF.GRATIS")] + [TestCase("Movie.Title.2014.1080p.AMZN.WEB-DL.DDP2.0.H.264.pt-BR.ENG-LCD")] public void should_parse_language_brazilian_portuguese(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 4248779ccf..0abdc249c7 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -20,7 +20,7 @@ public static class LanguageParser (?flemish)| (?bgaudio)| (?rodubbed)| - (?dublado)| + (?\b(dublado|pt-BR)\b)| (?greek)| (?\b(?:FR|VO|VF|VFF|VFQ|VFI|VF2|TRUEFRENCH|FRENCH|FRE|FRA)\b)| (?\b(?:rus|ru)\b)| From db70c06b8ba68e736470bc9a130dcf9da8e0345d Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 16 Oct 2024 01:06:42 +0000 Subject: [PATCH 016/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Co-authored-by: Buloni Co-authored-by: Havok Dan Co-authored-by: JoseFilipeFerreira Co-authored-by: Kuzmich55 Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/cs.json | 3 ++- src/NzbDrone.Core/Localization/Core/hr.json | 10 +++++++++- src/NzbDrone.Core/Localization/Core/nb_NO.json | 4 +++- src/NzbDrone.Core/Localization/Core/pt.json | 13 +++++++++---- src/NzbDrone.Core/Localization/Core/pt_BR.json | 6 +++--- src/NzbDrone.Core/Localization/Core/sk.json | 4 +++- 6 files changed, 29 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index c332a3f5db..7382eefa6d 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1201,5 +1201,6 @@ "ShowPhysicalReleaseHelpText": "Zobrazit datum vydání pod plakátem", "ShowDigitalRelease": "Zobrazit datum vydání kina", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Několik kořenových adresářů chybí pro seznamy importu: {rootFoldersInfo}", - "FolderNameTokens": "Tokeny názvů souborů" + "FolderNameTokens": "Tokeny názvů souborů", + "Letterboxd": "Letterboxd" } diff --git a/src/NzbDrone.Core/Localization/Core/hr.json b/src/NzbDrone.Core/Localization/Core/hr.json index aba89e925b..70031a2e3b 100644 --- a/src/NzbDrone.Core/Localization/Core/hr.json +++ b/src/NzbDrone.Core/Localization/Core/hr.json @@ -354,5 +354,13 @@ "AddDelayProfileError": "Neuspješno dodavanje profila odgode, molimo pokušaj ponovno.", "AddDownloadClientError": "Nesupješno dodavanje klijenta za preuzimanje, molimo pokušaj ponovno.", "Any": "BIlo koji", - "AppUpdatedVersion": "{appName} je ažuriran na verziju '{version}', kako bi najnovije promjene bile aktivne potrebno je ponovno učitati {appName}" + "AppUpdatedVersion": "{appName} je ažuriran na verziju '{version}', kako bi najnovije promjene bile aktivne potrebno je ponovno učitati {appName}", + "UnableToLoadRootFolders": "Neuspješno dodavanje korijenske mape", + "EditReleaseProfile": "Dodaj profil verzije", + "EditDownloadClientImplementation": "Dodaj Klijenta za Preuzimanje- {implementationName}", + "EditImportListImplementation": "Dodaj Listu Za Uvoz - {implementationName}", + "EditIndexerImplementation": "Dodaj Indexer - {implementationName}", + "EditConnectionImplementation": "Dodaj Vezu - {implementationName}", + "EditConditionImplementation": "Dodaj Vezu - {implementationName}", + "DownloadFailed": "Ponovno preuzimanje neuspješno" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index a3cd16e3b1..76d54a8978 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -315,5 +315,7 @@ "DeleteMovieFolderCountConfirmation": "Er du sikker på at du vil slette formattaggen {0}?", "DeleteSelectedImportListExclusionsMessageText": "Er du sikker på at du vil slette denne ekskluderingen av importlister?", "DeleteSelectedCustomFormats": "Klon egendefinert format", - "DeleteSelectedCustomFormatsMessageText": "Er du sikker på at du vil slette formattaggen {0}?" + "DeleteSelectedCustomFormatsMessageText": "Er du sikker på at du vil slette formattaggen {0}?", + "Discord": "Discord", + "TMDb": "TMDb" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 059f002f4f..0d0a9f258e 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -483,8 +483,8 @@ "NegateHelpText": "Se marcada, o formato personalizado não se aplicará caso a condição corresponda a {0}.", "ImportCustomFormat": "Importar formato personalizado", "ExportCustomFormat": "Exportar formato personalizado", - "CustomFormatUnknownConditionOption": "Opção \"{0}\" desconhecida para a condição \"{1}\"", - "CustomFormatUnknownCondition": "Condição de formato personalizado \"{0}\" desconhecida", + "CustomFormatUnknownConditionOption": "Opção \"{key}\" desconhecida para a condição \"{implementation}\"", + "CustomFormatUnknownCondition": "Condição de formato personalizado \"{implementation}\" desconhecida", "CloneCustomFormat": "Clonar formato personalizado", "AutomaticSearch": "Pesquisa automática", "IndexersLoadError": "Não foi possível carregar os indexadores", @@ -1123,7 +1123,7 @@ "CountImportListsSelected": "{count} importar lista(s) selecionada(s)", "Default": "Predefinição", "AppUpdatedVersion": "{appName} foi atualizado para a versão `{version}`, para obter as alterações mais recentes, você precisará recarregar {appName}", - "AutoTaggingRequiredHelpText": "Esta condição {0} tem de corresponder para que a regra de marcação automática seja aplicada. Caso contrário, uma única correspondência {0} é suficiente.", + "AutoTaggingRequiredHelpText": "Esta condição {implementationName} tem de corresponder para que a regra de marcação automática seja aplicada. Caso contrário, uma única correspondência {implementationName} é suficiente.", "BypassDelayIfAboveCustomFormatScoreHelpText": "Ativar o desvio quando a versão tem uma pontuação superior à pontuação mínima configurada para o formato personalizado", "EditImportListImplementation": "Editar Lista de Importação - {implementationName}", "AutoRedownloadFailed": "Falha na transferência", @@ -1261,5 +1261,10 @@ "ShowPhysicalRelease": "Data da versão física", "ShowPhysicalReleaseHelpText": "Mostrar data de lançamento abaixo do cartaz", "SmartReplaceHint": "Traço ou Espaço e Traço, dependendo do nome", - "FolderNameTokens": "Tokens de nome do ficheiro" + "FolderNameTokens": "Tokens de nome do ficheiro", + "BlackholeWatchFolderHelpText": "Pasta de onde {appName} deve importar os downloads completos", + "CountCustomFormatsSelected": "{count} formatos selecionados", + "BlackholeFolderHelpText": "Pasta em que {appName} guardará o ficheiro {extension}.", + "AnnouncedMovieAvailabilityDescription": "Filmes estão disponíveis assim que forem adicionados a {appName}.", + "CountVotes": "{votes} votos" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 3a413b33c6..22ebe4532f 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1707,7 +1707,7 @@ "Underscore": "Sublinhar", "ListQualityProfileHelpText": "Os itens da lista de Perfil de Qualidade que serão adicionados com", "AddAutoTagError": "Não foi possível adicionar uma nova etiqueta automática, tente novamente.", - "DeleteReleaseProfileMessageText": "Tem certeza de que deseja excluir este perfil de lançamento '{name}'?", + "DeleteReleaseProfileMessageText": "Tem certeza de que deseja excluir o perfil de lançamento '{name}'?", "DeleteSpecificationHelpText": "Tem certeza de que deseja excluir a especificação '{name}'?", "ConditionUsingRegularExpressions": "Esta condição corresponde ao uso de Expressões Regulares. Observe que os caracteres `\\^$.|?*+()[{` têm significados especiais e precisam escape com um `\\`", "DelayProfileMovieTagsHelpText": "Aplica-se a filmes com pelo menos uma etiqueta correspondente", @@ -1820,7 +1820,7 @@ "Logout": "Sair", "NoBlocklistItems": "Sem itens na lista de bloqueio", "LastSearched": "Última Pesquisa", - "NotificationsGotifySettingsMetadataLinks": "Links de Metadados", + "NotificationsGotifySettingsMetadataLinks": "Links de metadados", "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Adicione links aos metadados da série ao enviar notificações", "SkipFreeSpaceCheckHelpText": "Usar quando {appName} não consegue detectar espaço livre em sua pasta raiz", "MinimumCustomFormatScoreIncrementHelpText": "Melhoria mínima necessária da pontuação do formato personalizado entre versões existentes e novas antes que {appName} considere isso uma atualização", @@ -1836,5 +1836,5 @@ "ReleasedMovieAvailabilityDescription": "Filmes são considerados como disponíveis assim que é lançado em Blu-Ray ou no streaming.", "SmartReplace": "Substituição inteligente", "SmartReplaceHint": "Traço ou Espaço e Traço, dependendo do nome", - "FolderNameTokens": "Tokens de nome de arquivo" + "FolderNameTokens": "Tokens de Nome de Pasta" } diff --git a/src/NzbDrone.Core/Localization/Core/sk.json b/src/NzbDrone.Core/Localization/Core/sk.json index d7024e3909..786cf80adb 100644 --- a/src/NzbDrone.Core/Localization/Core/sk.json +++ b/src/NzbDrone.Core/Localization/Core/sk.json @@ -293,5 +293,7 @@ "AddDelayProfileError": "Nie je možné pridať novú podmienku, skúste to znova.", "AddQualityProfileError": "Nie je možné pridať novú podmienku, skúste to znova.", "DeleteSelectedImportListExclusionsMessageText": "Naozaj chcete toto vylúčenie importného zoznamu zmazať?", - "DeleteSelectedCustomFormats": "Klonovať vlastný formát" + "DeleteSelectedCustomFormats": "Klonovať vlastný formát", + "Discord": "Discord", + "TMDb": "TMDb" } From ff38afd198e4078dd1c29fa777403c9c2e52a6d6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 18 Oct 2024 07:19:09 +0300 Subject: [PATCH 017/579] Fixed: Add only movies with release dates from monitored collections --- src/NzbDrone.Core/Movies/RefreshCollectionService.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Movies/RefreshCollectionService.cs b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs index 4608225a49..1f983b5c47 100644 --- a/src/NzbDrone.Core/Movies/RefreshCollectionService.cs +++ b/src/NzbDrone.Core/Movies/RefreshCollectionService.cs @@ -125,10 +125,14 @@ private void SyncCollectionMovies(MovieCollection collection) { if (collection.Monitored) { + var collectionMovies = _movieMetadataService + .GetMoviesByCollectionTmdbId(collection.TmdbId) + .Where(m => m.Status is MovieStatusType.InCinemas or MovieStatusType.Released) + .ToList(); + var existingMovies = _movieService.AllMovieTmdbIds(); - var collectionMovies = _movieMetadataService.GetMoviesByCollectionTmdbId(collection.TmdbId); var excludedMovies = _importListExclusionService.All().Select(e => e.TmdbId); - var moviesToAdd = collectionMovies.Where(m => !existingMovies.Contains(m.TmdbId)).Where(m => !excludedMovies.Contains(m.TmdbId)); + var moviesToAdd = collectionMovies.Where(m => !existingMovies.Contains(m.TmdbId)).Where(m => !excludedMovies.Contains(m.TmdbId)).ToList(); if (moviesToAdd.Any()) { From d90ee3ae11bb54f79a00fc94ecfedae37d13e056 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 18 Oct 2024 00:49:00 +0300 Subject: [PATCH 018/579] Fixed: Release Year mandatory to generate valid file formats --- .../Organizer/FileNameBuilder.cs | 4 +- .../Organizer/FileNameValidation.cs | 53 ++++++++++++++++--- .../Organizer/FileNameValidationService.cs | 2 +- .../ApiTests/NamingConfigFixture.cs | 2 +- 4 files changed, 50 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index c600e2c69e..b499da390d 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -41,7 +41,9 @@ public class FileNameBuilder : IBuildFileNames private static readonly Regex TitleRegex = new Regex(@"(?\{(?:imdb-|edition-))?\{(?[- ._\[(]*)(?(?:[a-z0-9]+)(?:(?[- ._]+)(?:[a-z0-9]+))?)(?::(?[ ,a-z0-9|+-]+(?[-} ._)\]]*)\}", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - public static readonly Regex MovieTitleRegex = new Regex(@"(?\{(?:(?:Movie)(?[- ._])(?:Clean)?(?:OriginalTitle|Title(?:The)?)(?::(?[a-z0-9|-]+))?|Original[- ._](?:Title|Filename))\})", + public static readonly Regex ReleaseYearRegex = new Regex(@"\{Release[- ._]Year\}", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + public static readonly Regex MovieTitleRegex = new Regex(@"(?\{(?:Movie)(?[- ._])(?:Clean)?(?:OriginalTitle|Title(?:The)?)(?::(?[a-z0-9|-]+))?\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); private static readonly Regex FileNameCleanupRegex = new Regex(@"([- ._])(\1)+", RegexOptions.Compiled); diff --git a/src/NzbDrone.Core/Organizer/FileNameValidation.cs b/src/NzbDrone.Core/Organizer/FileNameValidation.cs index b7682407bc..fe49d9f317 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidation.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidation.cs @@ -1,5 +1,6 @@ using System.IO; using System.Linq; +using System.Text.RegularExpressions; using FluentValidation; using FluentValidation.Validators; using NzbDrone.Common.Extensions; @@ -8,20 +9,56 @@ namespace NzbDrone.Core.Organizer { public static class FileNameValidation { - public static IRuleBuilderOptions ValidMovieFolderFormat(this IRuleBuilder ruleBuilder) - { - ruleBuilder.SetValidator(new NotEmptyValidator(null)); - ruleBuilder.SetValidator(new IllegalCharactersValidator()); - - return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title"); - } + internal static readonly Regex OriginalTokenRegex = new (@"(\{Original[- ._](?:Title|Filename)\})", + RegexOptions.Compiled | RegexOptions.IgnoreCase); public static IRuleBuilderOptions ValidMovieFormat(this IRuleBuilder ruleBuilder) { ruleBuilder.SetValidator(new NotEmptyValidator(null)); ruleBuilder.SetValidator(new IllegalCharactersValidator()); - return ruleBuilder.SetValidator(new RegularExpressionValidator(FileNameBuilder.MovieTitleRegex)).WithMessage("Must contain movie title"); + return ruleBuilder.SetValidator(new ValidMovieFormatValidator()); + } + + public static IRuleBuilderOptions ValidMovieFolderFormat(this IRuleBuilder ruleBuilder) + { + ruleBuilder.SetValidator(new NotEmptyValidator(null)); + ruleBuilder.SetValidator(new IllegalCharactersValidator()); + + return ruleBuilder.SetValidator(new ValidMovieFolderFormatValidator()); + } + } + + public class ValidMovieFormatValidator : PropertyValidator + { + protected override string GetDefaultMessageTemplate() => "Must contain movie title and release year OR Original Title"; + + protected override bool IsValid(PropertyValidatorContext context) + { + if (context.PropertyValue is not string value) + { + return false; + } + + return (FileNameBuilder.MovieTitleRegex.IsMatch(value) && FileNameBuilder.ReleaseYearRegex.IsMatch(value)) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); + } + } + + public class ValidMovieFolderFormatValidator : PropertyValidator + { + protected override string GetDefaultMessageTemplate() => "Must contain movie title"; + + protected override bool IsValid(PropertyValidatorContext context) + { + if (context.PropertyValue is not string value) + { + return false; + } + + // TODO: Deprecate OriginalTokenRegex use for Movie Folder Format + return FileNameBuilder.MovieTitleRegex.IsMatch(value) || + FileNameValidation.OriginalTokenRegex.IsMatch(value); } } diff --git a/src/NzbDrone.Core/Organizer/FileNameValidationService.cs b/src/NzbDrone.Core/Organizer/FileNameValidationService.cs index c0ab89ad72..2829d99784 100644 --- a/src/NzbDrone.Core/Organizer/FileNameValidationService.cs +++ b/src/NzbDrone.Core/Organizer/FileNameValidationService.cs @@ -13,7 +13,7 @@ public class FileNameValidationService : IFilenameValidationService public ValidationFailure ValidateMovieFilename(SampleResult sampleResult) { - var validationFailure = new ValidationFailure("MovieFormat", ERROR_MESSAGE); + var validationFailure = new ValidationFailure("StandardMovieFormat", ERROR_MESSAGE); var parsedMovieInfo = Parser.Parser.ParseMovieTitle(sampleResult.FileName); if (parsedMovieInfo == null) diff --git a/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs index 361e1e00f5..47c0e82035 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs @@ -25,7 +25,7 @@ public void should_be_able_to_update() { var config = NamingConfig.GetSingle(); config.RenameMovies = false; - config.StandardMovieFormat = "{Movie Title}"; + config.StandardMovieFormat = "{Movie Title} {Release Year}"; var result = NamingConfig.Put(config); result.RenameMovies.Should().BeFalse(); From a06792b9231c068a65d5832e9c2df7cee7e651c7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 18 Oct 2024 23:02:42 +0300 Subject: [PATCH 019/579] New: Sync updates to UI for providers (#10550) --- frontend/src/Components/SignalRConnector.js | 42 ++++++++++++++++++- .../DownloadClientController.cs | 5 ++- .../ImportLists/ImportListController.cs | 8 +++- .../Indexers/IndexerController.cs | 7 +++- .../Metadata/MetadataController.cs | 24 ++++++++++- .../Notifications/NotificationController.cs | 5 ++- src/Radarr.Api.V3/ProviderControllerBase.cs | 31 +++++++++++++- 7 files changed, 109 insertions(+), 13 deletions(-) diff --git a/frontend/src/Components/SignalRConnector.js b/frontend/src/Components/SignalRConnector.js index 6c22be4681..4f2fc7ac58 100644 --- a/frontend/src/Components/SignalRConnector.js +++ b/frontend/src/Components/SignalRConnector.js @@ -168,7 +168,7 @@ class SignalRConnector extends Component { const status = resource.status; // Both successful and failed commands need to be - // completed, otherwise they spin until they timeout. + // completed, otherwise they spin until they time out. if (status === 'completed' || status === 'failed') { this.props.dispatchFinishCommand(resource); @@ -192,10 +192,50 @@ class SignalRConnector extends Component { } }; + handleDownloadclient = ({ action, resource }) => { + const section = 'settings.downloadClients'; + + if (action === 'created' || action === 'updated') { + this.props.dispatchUpdateItem({ section, ...resource }); + } else if (action === 'deleted') { + this.props.dispatchRemoveItem({ section, id: resource.id }); + } + }; + handleHealth = () => { this.props.dispatchFetchHealth(); }; + handleImportlist = ({ action, resource }) => { + const section = 'settings.importLists'; + + if (action === 'created' || action === 'updated') { + this.props.dispatchUpdateItem({ section, ...resource }); + } else if (action === 'deleted') { + this.props.dispatchRemoveItem({ section, id: resource.id }); + } + }; + + handleIndexer = ({ action, resource }) => { + const section = 'settings.indexers'; + + if (action === 'created' || action === 'updated') { + this.props.dispatchUpdateItem({ section, ...resource }); + } else if (action === 'deleted') { + this.props.dispatchRemoveItem({ section, id: resource.id }); + } + }; + + handleNotification = ({ action, resource }) => { + const section = 'settings.notifications'; + + if (action === 'created' || action === 'updated') { + this.props.dispatchUpdateItem({ section, ...resource }); + } else if (action === 'deleted') { + this.props.dispatchRemoveItem({ section, id: resource.id }); + } + }; + handleMovie = (body) => { const action = body.action; const section = 'movies'; diff --git a/src/Radarr.Api.V3/DownloadClient/DownloadClientController.cs b/src/Radarr.Api.V3/DownloadClient/DownloadClientController.cs index e83932c624..532f736136 100644 --- a/src/Radarr.Api.V3/DownloadClient/DownloadClientController.cs +++ b/src/Radarr.Api.V3/DownloadClient/DownloadClientController.cs @@ -1,4 +1,5 @@ using NzbDrone.Core.Download; +using NzbDrone.SignalR; using Radarr.Http; namespace Radarr.Api.V3.DownloadClient @@ -9,8 +10,8 @@ public class DownloadClientController : ProviderControllerBase c.MinimumAvailability).NotNull(); diff --git a/src/Radarr.Api.V3/Indexers/IndexerController.cs b/src/Radarr.Api.V3/Indexers/IndexerController.cs index 8833021130..a7cb313e78 100644 --- a/src/Radarr.Api.V3/Indexers/IndexerController.cs +++ b/src/Radarr.Api.V3/Indexers/IndexerController.cs @@ -1,5 +1,6 @@ using NzbDrone.Core.Indexers; using NzbDrone.Core.Validation; +using NzbDrone.SignalR; using Radarr.Http; namespace Radarr.Api.V3.Indexers @@ -10,8 +11,10 @@ public class IndexerController : ProviderControllerBase c.DownloadClientId).SetValidator(downloadClientExistsValidator); } diff --git a/src/Radarr.Api.V3/Metadata/MetadataController.cs b/src/Radarr.Api.V3/Metadata/MetadataController.cs index 938878d0b1..6302b170cb 100644 --- a/src/Radarr.Api.V3/Metadata/MetadataController.cs +++ b/src/Radarr.Api.V3/Metadata/MetadataController.cs @@ -1,6 +1,8 @@ using System; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Extras.Metadata; +using NzbDrone.Core.ThingiProvider.Events; +using NzbDrone.SignalR; using Radarr.Http; namespace Radarr.Api.V3.Metadata @@ -11,8 +13,8 @@ public class MetadataController : ProviderControllerBase message) + { + throw new NotImplementedException(); + } + + [NonAction] + public override void Handle(ProviderUpdatedEvent message) + { + throw new NotImplementedException(); + } + + [NonAction] + public override void Handle(ProviderDeletedEvent message) + { + throw new NotImplementedException(); + } } } diff --git a/src/Radarr.Api.V3/Notifications/NotificationController.cs b/src/Radarr.Api.V3/Notifications/NotificationController.cs index 310b6f92b6..03bdaa3cb2 100644 --- a/src/Radarr.Api.V3/Notifications/NotificationController.cs +++ b/src/Radarr.Api.V3/Notifications/NotificationController.cs @@ -1,6 +1,7 @@ using System; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Notifications; +using NzbDrone.SignalR; using Radarr.Http; namespace Radarr.Api.V3.Notifications @@ -11,8 +12,8 @@ public class NotificationController : ProviderControllerBase : RestController + public abstract class ProviderControllerBase : RestControllerWithSignalR, + IHandle>, + IHandle>, + IHandle> where TProviderDefinition : ProviderDefinition, new() where TProvider : IProvider where TProviderResource : ProviderResource, new() @@ -22,11 +29,13 @@ public abstract class ProviderControllerBase _resourceMapper; private readonly ProviderBulkResourceMapper _bulkResourceMapper; - protected ProviderControllerBase(IProviderFactory providerFactory, string resource, ProviderResourceMapper resourceMapper, ProviderBulkResourceMapper bulkResourceMapper) + : base(signalRBroadcaster) { _providerFactory = providerFactory; _resourceMapper = resourceMapper; @@ -263,6 +272,24 @@ public IActionResult RequestAction([FromRoute] string name, [FromBody] TProvider return Content(data.ToJson(), "application/json"); } + [NonAction] + public virtual void Handle(ProviderAddedEvent message) + { + BroadcastResourceChange(ModelAction.Created, message.Definition.Id); + } + + [NonAction] + public virtual void Handle(ProviderUpdatedEvent message) + { + BroadcastResourceChange(ModelAction.Updated, message.Definition.Id); + } + + [NonAction] + public virtual void Handle(ProviderDeletedEvent message) + { + BroadcastResourceChange(ModelAction.Deleted, message.ProviderId); + } + private void Validate(TProviderDefinition definition, bool includeWarnings) { var validationResult = definition.Settings.Validate(); From adb27123df33380f74acfa3a213daa8f38c5f873 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 12 Oct 2024 20:59:52 +0300 Subject: [PATCH 020/579] Natural sorting for tags list in the UI (cherry picked from commit 09d3ae969281715a26ffd374c148cafe17a8f438) --- frontend/src/Settings/Tags/TagsConnector.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/frontend/src/Settings/Tags/TagsConnector.js b/frontend/src/Settings/Tags/TagsConnector.js index 2b5f7ab8fc..1ff551837c 100644 --- a/frontend/src/Settings/Tags/TagsConnector.js +++ b/frontend/src/Settings/Tags/TagsConnector.js @@ -4,11 +4,13 @@ import { connect } from 'react-redux'; import { createSelector } from 'reselect'; import { fetchDelayProfiles, fetchDownloadClients, fetchImportLists, fetchIndexers, fetchNotifications, fetchReleaseProfiles } from 'Store/Actions/settingsActions'; import { fetchTagDetails, fetchTags } from 'Store/Actions/tagActions'; +import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; +import sortByProp from 'Utilities/Array/sortByProp'; import Tags from './Tags'; function createMapStateToProps() { return createSelector( - (state) => state.tags, + createSortedSectionSelector('tags', sortByProp('label')), (tags) => { const isFetching = tags.isFetching || tags.details.isFetching; const error = tags.error || tags.details.error; From 84b507faf3c6f28b649479a0d5412007a220f7e8 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 18 Oct 2024 12:12:20 +0300 Subject: [PATCH 021/579] New: Romania and India added to list of Certification Countries --- frontend/src/Settings/Metadata/Options/MetadataOptions.js | 8 +++++--- .../MetadataSource/SkyHook/Resource/TMDbCountryCode.cs | 4 +++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/frontend/src/Settings/Metadata/Options/MetadataOptions.js b/frontend/src/Settings/Metadata/Options/MetadataOptions.js index cfbbb9b19e..83752c065a 100644 --- a/frontend/src/Settings/Metadata/Options/MetadataOptions.js +++ b/frontend/src/Settings/Metadata/Options/MetadataOptions.js @@ -13,17 +13,19 @@ import translate from 'Utilities/String/translate'; // Note: Do Not Translate Certification Countries export const certificationCountryOptions = [ + { key: 'us', value: 'United States' }, { key: 'au', value: 'Australia' }, { key: 'br', value: 'Brazil' }, { key: 'ca', value: 'Canada' }, { key: 'fr', value: 'France' }, { key: 'de', value: 'Germany' }, { key: 'gb', value: 'Great Britain' }, + { key: 'in', value: 'India' }, { key: 'ie', value: 'Ireland' }, { key: 'it', value: 'Italy' }, - { key: 'es', value: 'Spain' }, - { key: 'us', value: 'United States' }, - { key: 'nz', value: 'New Zealand' } + { key: 'nz', value: 'New Zealand' }, + { key: 'ro', value: 'Romania' }, + { key: 'es', value: 'Spain' } ]; function MetadataOptions(props) { diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs index 15a8c8024c..edacfe9085 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/Resource/TMDbCountryCode.cs @@ -8,10 +8,12 @@ public enum TMDbCountryCode FR, // France DE, // Germany GB, // Great Britain + IN, // India IE, // Ireland IT, // Italy + NZ, // New Zealand + RO, // Romania ES, // Spain US, // United States - NZ // New Zealand } } From f900d623dc46b18a4d33c98fecf24a980ac45b39 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 14 Jul 2024 16:42:35 -0700 Subject: [PATCH 022/579] New: Allow major version updates to be installed (cherry picked from commit 0e95ba2021b23cc65bce0a0620dd48e355250dab) --- frontend/src/App/AppRoutes.js | 4 +- frontend/src/App/State/SystemAppState.ts | 3 + frontend/src/System/Updates/UpdateChanges.js | 52 --- frontend/src/System/Updates/UpdateChanges.tsx | 43 +++ frontend/src/System/Updates/Updates.js | 249 -------------- frontend/src/System/Updates/Updates.tsx | 303 ++++++++++++++++++ .../src/System/Updates/UpdatesConnector.js | 98 ------ frontend/src/typings/Update.ts | 20 ++ src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 6 +- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 2 +- .../Commands/ApplicationCheckUpdateCommand.cs | 2 + .../Commands/ApplicationUpdateCommand.cs | 1 + .../Update/InstallUpdateService.cs | 14 +- .../Update/UpdatePackageProvider.cs | 1 + 42 files changed, 419 insertions(+), 435 deletions(-) delete mode 100644 frontend/src/System/Updates/UpdateChanges.js create mode 100644 frontend/src/System/Updates/UpdateChanges.tsx delete mode 100644 frontend/src/System/Updates/Updates.js create mode 100644 frontend/src/System/Updates/Updates.tsx delete mode 100644 frontend/src/System/Updates/UpdatesConnector.js create mode 100644 frontend/src/typings/Update.ts diff --git a/frontend/src/App/AppRoutes.js b/frontend/src/App/AppRoutes.js index c5207e4546..fa293dc226 100644 --- a/frontend/src/App/AppRoutes.js +++ b/frontend/src/App/AppRoutes.js @@ -31,7 +31,7 @@ import LogsTableConnector from 'System/Events/LogsTableConnector'; import Logs from 'System/Logs/Logs'; import Status from 'System/Status/Status'; import Tasks from 'System/Tasks/Tasks'; -import UpdatesConnector from 'System/Updates/UpdatesConnector'; +import Updates from 'System/Updates/Updates'; import getPathWithUrlBase from 'Utilities/getPathWithUrlBase'; import CutoffUnmetConnector from 'Wanted/CutoffUnmet/CutoffUnmetConnector'; import MissingConnector from 'Wanted/Missing/MissingConnector'; @@ -228,7 +228,7 @@ function AppRoutes(props) { ; export type HealthAppState = AppSectionState; export type SystemStatusAppState = AppSectionItemState; export type TaskAppState = AppSectionState; +export type UpdateAppState = AppSectionState; interface SystemAppState { diskSpace: DiskSpaceAppState; health: HealthAppState; status: SystemStatusAppState; tasks: TaskAppState; + updates: UpdateAppState; } export default SystemAppState; diff --git a/frontend/src/System/Updates/UpdateChanges.js b/frontend/src/System/Updates/UpdateChanges.js deleted file mode 100644 index a42e420fa9..0000000000 --- a/frontend/src/System/Updates/UpdateChanges.js +++ /dev/null @@ -1,52 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; -import styles from './UpdateChanges.css'; - -class UpdateChanges extends Component { - - // - // Render - - render() { - const { - title, - changes - } = this.props; - - if (changes.length === 0) { - return null; - } - - const uniqueChanges = [...new Set(changes)]; - - return ( -
-
{title}
-
    - { - uniqueChanges.map((change, index) => { - const checkChange = change.replace(/#\d{4,5}\b/g, (match, contents) => { - return `[${match}](https://github.com/Radarr/Radarr/issues/${match.substring(1)})`; - }); - - return ( -
  • - -
  • - ); - }) - } -
-
- ); - } - -} - -UpdateChanges.propTypes = { - title: PropTypes.string.isRequired, - changes: PropTypes.arrayOf(PropTypes.string) -}; - -export default UpdateChanges; diff --git a/frontend/src/System/Updates/UpdateChanges.tsx b/frontend/src/System/Updates/UpdateChanges.tsx new file mode 100644 index 0000000000..20338d0119 --- /dev/null +++ b/frontend/src/System/Updates/UpdateChanges.tsx @@ -0,0 +1,43 @@ +import React from 'react'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import styles from './UpdateChanges.css'; + +interface UpdateChangesProps { + title: string; + changes: string[]; +} + +function UpdateChanges(props: UpdateChangesProps) { + const { title, changes } = props; + + if (changes.length === 0) { + return null; + } + + const uniqueChanges = [...new Set(changes)]; + + return ( +
+
{title}
+
    + {uniqueChanges.map((change, index) => { + const checkChange = change.replace( + /#\d{4,5}\b/g, + (match) => + `[${match}](https://github.com/Radarr/Radarr/issues/${match.substring( + 1 + )})` + ); + + return ( +
  • + +
  • + ); + })} +
+
+ ); +} + +export default UpdateChanges; diff --git a/frontend/src/System/Updates/Updates.js b/frontend/src/System/Updates/Updates.js deleted file mode 100644 index aae3737656..0000000000 --- a/frontend/src/System/Updates/Updates.js +++ /dev/null @@ -1,249 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component, Fragment } from 'react'; -import Alert from 'Components/Alert'; -import Icon from 'Components/Icon'; -import Label from 'Components/Label'; -import SpinnerButton from 'Components/Link/SpinnerButton'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; -import PageContent from 'Components/Page/PageContent'; -import PageContentBody from 'Components/Page/PageContentBody'; -import { icons, kinds } from 'Helpers/Props'; -import formatDate from 'Utilities/Date/formatDate'; -import formatDateTime from 'Utilities/Date/formatDateTime'; -import translate from 'Utilities/String/translate'; -import UpdateChanges from './UpdateChanges'; -import styles from './Updates.css'; - -class Updates extends Component { - - // - // Render - - render() { - const { - currentVersion, - isFetching, - isPopulated, - updatesError, - generalSettingsError, - items, - isInstallingUpdate, - updateMechanism, - updateMechanismMessage, - shortDateFormat, - longDateFormat, - timeFormat, - onInstallLatestPress - } = this.props; - - const hasError = !!(updatesError || generalSettingsError); - const hasUpdates = isPopulated && !hasError && items.length > 0; - const noUpdates = isPopulated && !hasError && !items.length; - const hasUpdateToInstall = hasUpdates && _.some(items, { installable: true, latest: true }); - const noUpdateToInstall = hasUpdates && !hasUpdateToInstall; - - const externalUpdaterPrefix = translate('UpdateRadarrDirectlyLoadError'); - const externalUpdaterMessages = { - external: translate('ExternalUpdater'), - apt: translate('AptUpdater'), - docker: translate('DockerUpdater') - }; - - return ( - - - { - !isPopulated && !hasError && - - } - - { - noUpdates && - - {translate('NoUpdatesAreAvailable')} - - } - - { - hasUpdateToInstall && -
- { - updateMechanism === 'builtIn' || updateMechanism === 'script' ? - - {translate('InstallLatest')} - : - - - - -
- {externalUpdaterPrefix} -
-
- } - - { - isFetching && - - } -
- } - - { - noUpdateToInstall && -
- -
- {translate('OnLatestVersion')} -
- - { - isFetching && - - } -
- } - - { - hasUpdates && -
- { - items.map((update) => { - const hasChanges = !!update.changes; - - return ( -
-
-
{update.version}
-
-
- {formatDate(update.releaseDate, shortDateFormat)} -
- - { - update.branch === 'master' ? - null : - - } - - { - update.version === currentVersion ? - : - null - } - - { - update.version !== currentVersion && update.installedOn ? - : - null - } -
- - { - !hasChanges && -
- {translate('MaintenanceRelease')} -
- } - - { - hasChanges && -
- - - -
- } -
- ); - }) - } -
- } - - { - !!updatesError && -
- {translate('FailedToFetchUpdates')} -
- } - - { - !!generalSettingsError && -
- {translate('FailedToUpdateSettings')} -
- } -
-
- ); - } - -} - -Updates.propTypes = { - currentVersion: PropTypes.string.isRequired, - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - updatesError: PropTypes.object, - generalSettingsError: PropTypes.object, - items: PropTypes.array.isRequired, - isInstallingUpdate: PropTypes.bool.isRequired, - updateMechanism: PropTypes.string, - updateMechanismMessage: PropTypes.string, - shortDateFormat: PropTypes.string.isRequired, - longDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onInstallLatestPress: PropTypes.func.isRequired -}; - -export default Updates; diff --git a/frontend/src/System/Updates/Updates.tsx b/frontend/src/System/Updates/Updates.tsx new file mode 100644 index 0000000000..df635e5d7f --- /dev/null +++ b/frontend/src/System/Updates/Updates.tsx @@ -0,0 +1,303 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import * as commandNames from 'Commands/commandNames'; +import Alert from 'Components/Alert'; +import Icon from 'Components/Icon'; +import Label from 'Components/Label'; +import SpinnerButton from 'Components/Link/SpinnerButton'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import ConfirmModal from 'Components/Modal/ConfirmModal'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import { icons, kinds } from 'Helpers/Props'; +import { executeCommand } from 'Store/Actions/commandActions'; +import { fetchGeneralSettings } from 'Store/Actions/settingsActions'; +import { fetchUpdates } from 'Store/Actions/systemActions'; +import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector'; +import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector'; +import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; +import { UpdateMechanism } from 'typings/Settings/General'; +import formatDate from 'Utilities/Date/formatDate'; +import formatDateTime from 'Utilities/Date/formatDateTime'; +import translate from 'Utilities/String/translate'; +import UpdateChanges from './UpdateChanges'; +import styles from './Updates.css'; + +const VERSION_REGEX = /\d+\.\d+\.\d+\.\d+/i; + +function createUpdatesSelector() { + return createSelector( + (state: AppState) => state.system.updates, + (state: AppState) => state.settings.general, + (updates, generalSettings) => { + const { error: updatesError, items } = updates; + + const isFetching = updates.isFetching || generalSettings.isFetching; + const isPopulated = updates.isPopulated && generalSettings.isPopulated; + + return { + isFetching, + isPopulated, + updatesError, + generalSettingsError: generalSettings.error, + items, + updateMechanism: generalSettings.item.updateMechanism, + }; + } + ); +} + +function Updates() { + const currentVersion = useSelector((state: AppState) => state.app.version); + const { packageUpdateMechanismMessage } = useSelector( + createSystemStatusSelector() + ); + const { shortDateFormat, longDateFormat, timeFormat } = useSelector( + createUISettingsSelector() + ); + const isInstallingUpdate = useSelector( + createCommandExecutingSelector(commandNames.APPLICATION_UPDATE) + ); + + const { + isFetching, + isPopulated, + updatesError, + generalSettingsError, + items, + updateMechanism, + } = useSelector(createUpdatesSelector()); + + const dispatch = useDispatch(); + const [isMajorUpdateModalOpen, setIsMajorUpdateModalOpen] = useState(false); + const hasError = !!(updatesError || generalSettingsError); + const hasUpdates = isPopulated && !hasError && items.length > 0; + const noUpdates = isPopulated && !hasError && !items.length; + + const externalUpdaterPrefix = translate('UpdateAppDirectlyLoadError'); + const externalUpdaterMessages: Partial> = { + external: translate('ExternalUpdater'), + apt: translate('AptUpdater'), + docker: translate('DockerUpdater'), + }; + + const { isMajorUpdate, hasUpdateToInstall } = useMemo(() => { + const majorVersion = parseInt( + currentVersion.match(VERSION_REGEX)?.[0] ?? '0' + ); + + const latestVersion = items[0]?.version; + const latestMajorVersion = parseInt( + latestVersion?.match(VERSION_REGEX)?.[0] ?? '0' + ); + + return { + isMajorUpdate: latestMajorVersion > majorVersion, + hasUpdateToInstall: items.some( + (update) => update.installable && update.latest + ), + }; + }, [currentVersion, items]); + + const noUpdateToInstall = hasUpdates && !hasUpdateToInstall; + + const handleInstallLatestPress = useCallback(() => { + if (isMajorUpdate) { + setIsMajorUpdateModalOpen(true); + } else { + dispatch(executeCommand({ name: commandNames.APPLICATION_UPDATE })); + } + }, [isMajorUpdate, setIsMajorUpdateModalOpen, dispatch]); + + const handleInstallLatestMajorVersionPress = useCallback(() => { + setIsMajorUpdateModalOpen(false); + + dispatch( + executeCommand({ + name: commandNames.APPLICATION_UPDATE, + installMajorUpdate: true, + }) + ); + }, [setIsMajorUpdateModalOpen, dispatch]); + + const handleCancelMajorVersionPress = useCallback(() => { + setIsMajorUpdateModalOpen(false); + }, [setIsMajorUpdateModalOpen]); + + useEffect(() => { + dispatch(fetchUpdates()); + dispatch(fetchGeneralSettings()); + }, [dispatch]); + + return ( + + + {isPopulated || hasError ? null : } + + {noUpdates ? ( + {translate('NoUpdatesAreAvailable')} + ) : null} + + {hasUpdateToInstall ? ( +
+ {updateMechanism === 'builtIn' || updateMechanism === 'script' ? ( + + {translate('InstallLatest')} + + ) : ( + <> + + +
+ {externalUpdaterPrefix}{' '} + +
+ + )} + + {isFetching ? ( + + ) : null} +
+ ) : null} + + {noUpdateToInstall && ( +
+ +
{translate('OnLatestVersion')}
+ + {isFetching && ( + + )} +
+ )} + + {hasUpdates && ( +
+ {items.map((update) => { + return ( +
+
+
{update.version}
+
+
+ {formatDate(update.releaseDate, shortDateFormat)} +
+ + {update.branch === 'main' ? null : ( + + )} + + {update.version === currentVersion ? ( + + ) : null} + + {update.version !== currentVersion && update.installedOn ? ( + + ) : null} +
+ + {update.changes ? ( +
+ + + +
+ ) : ( +
{translate('MaintenanceRelease')}
+ )} +
+ ); + })} +
+ )} + + {updatesError ? ( + + {translate('FailedToFetchUpdates')} + + ) : null} + + {generalSettingsError ? ( + + {translate('FailedToUpdateSettings')} + + ) : null} + + +
{translate('InstallMajorVersionUpdateMessage')}
+
+ +
+ + } + confirmLabel={translate('Install')} + onConfirm={handleInstallLatestMajorVersionPress} + onCancel={handleCancelMajorVersionPress} + /> +
+
+ ); +} + +export default Updates; diff --git a/frontend/src/System/Updates/UpdatesConnector.js b/frontend/src/System/Updates/UpdatesConnector.js deleted file mode 100644 index 77d75dbdaf..0000000000 --- a/frontend/src/System/Updates/UpdatesConnector.js +++ /dev/null @@ -1,98 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import * as commandNames from 'Commands/commandNames'; -import { executeCommand } from 'Store/Actions/commandActions'; -import { fetchGeneralSettings } from 'Store/Actions/settingsActions'; -import { fetchUpdates } from 'Store/Actions/systemActions'; -import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector'; -import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import Updates from './Updates'; - -function createMapStateToProps() { - return createSelector( - (state) => state.app.version, - createSystemStatusSelector(), - (state) => state.system.updates, - (state) => state.settings.general, - createUISettingsSelector(), - createCommandExecutingSelector(commandNames.APPLICATION_UPDATE), - ( - currentVersion, - status, - updates, - generalSettings, - uiSettings, - isInstallingUpdate - ) => { - const { - error: updatesError, - items - } = updates; - - const isFetching = updates.isFetching || generalSettings.isFetching; - const isPopulated = updates.isPopulated && generalSettings.isPopulated; - - return { - currentVersion, - isFetching, - isPopulated, - updatesError, - generalSettingsError: generalSettings.error, - items, - isInstallingUpdate, - updateMechanism: generalSettings.item.updateMechanism, - updateMechanismMessage: status.packageUpdateMechanismMessage, - shortDateFormat: uiSettings.shortDateFormat, - longDateFormat: uiSettings.longDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -const mapDispatchToProps = { - dispatchFetchUpdates: fetchUpdates, - dispatchFetchGeneralSettings: fetchGeneralSettings, - dispatchExecuteCommand: executeCommand -}; - -class UpdatesConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.dispatchFetchUpdates(); - this.props.dispatchFetchGeneralSettings(); - } - - // - // Listeners - - onInstallLatestPress = () => { - this.props.dispatchExecuteCommand({ name: commandNames.APPLICATION_UPDATE }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -UpdatesConnector.propTypes = { - dispatchFetchUpdates: PropTypes.func.isRequired, - dispatchFetchGeneralSettings: PropTypes.func.isRequired, - dispatchExecuteCommand: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(UpdatesConnector); diff --git a/frontend/src/typings/Update.ts b/frontend/src/typings/Update.ts new file mode 100644 index 0000000000..448b1728d4 --- /dev/null +++ b/frontend/src/typings/Update.ts @@ -0,0 +1,20 @@ +export interface Changes { + new: string[]; + fixed: string[]; +} + +interface Update { + version: string; + branch: string; + releaseDate: string; + fileName: string; + url: string; + installed: boolean; + installedOn: string; + installable: boolean; + latest: boolean; + changes: Changes | null; + hash: string; +} + +export default Update; diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index b437f7316b..018c87cf7f 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -56,7 +56,7 @@ "Unlimited": "غير محدود", "Ungroup": "فك التجميع", "Unavailable": "غير متوفره", - "UpdateRadarrDirectlyLoadError": "تعذر تحديث {appName} مباشرة ،", + "UpdateAppDirectlyLoadError": "تعذر تحديث {appName} مباشرة ،", "UiSettingsLoadError": "تعذر تحميل إعدادات واجهة المستخدم", "CalendarLoadError": "تعذر تحميل التقويم", "TagsLoadError": "تعذر تحميل العلامات", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index b80b1e4019..a8529a0722 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -621,7 +621,7 @@ "UnableToLoadRootFolders": "Не може да се заредят коренови папки", "TagsLoadError": "Не може да се заредят маркери", "CalendarLoadError": "Календарът не може да се зареди", - "UpdateRadarrDirectlyLoadError": "Не може да се актуализира {appName} директно,", + "UpdateAppDirectlyLoadError": "Не може да се актуализира {appName} директно,", "Ungroup": "Разгрупиране", "Unlimited": "Неограничен", "UnmappedFilesOnly": "Само немапирани файлове", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index d84131e642..700a444569 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -909,7 +909,7 @@ "TagsLoadError": "No es poden carregar les etiquetes", "CalendarLoadError": "No es pot carregar el calendari", "UiSettingsLoadError": "No es pot carregar la configuració de la IU", - "UpdateRadarrDirectlyLoadError": "No es pot actualitzar {appName} directament,", + "UpdateAppDirectlyLoadError": "No es pot actualitzar {appName} directament,", "Unreleased": "No disponible", "UnselectAll": "Desseleccioneu-ho tot", "UpdateCheckStartupNotWritableMessage": "L'actualització no es pot instal·lar perquè la carpeta d'inici '{startupFolder}' no té permisos d'escriptura per a l'usuari '{userName}'.", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 7382eefa6d..d6edfbe113 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -901,7 +901,7 @@ "QualityProfilesLoadError": "Nelze načíst profily kvality", "UnableToLoadRootFolders": "Nelze načíst kořenové složky", "CalendarLoadError": "Kalendář nelze načíst", - "UpdateRadarrDirectlyLoadError": "{appName} nelze aktualizovat přímo,", + "UpdateAppDirectlyLoadError": "{appName} nelze aktualizovat přímo,", "UnmappedFilesOnly": "Pouze nezmapované soubory", "UnmappedFolders": "Nezmapované složky", "Unmonitored": "Nemonitorováno", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index e96e44af24..e3deb2e062 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -159,7 +159,7 @@ "TagsSettingsSummary": "Se alle tags og hvordan de bruges. Ubrugte tags kan fjernes", "Time": "Tid", "MediaManagementSettingsLoadError": "Kan ikke indlæse indstillinger for mediestyring", - "UpdateRadarrDirectlyLoadError": "Kan ikke opdatere {appName} direkte,", + "UpdateAppDirectlyLoadError": "Kan ikke opdatere {appName} direkte,", "BindAddressHelpText": "Gyldig IP4-adresse, 'localhost' eller '*' for alle grænseflader", "CreateEmptyMovieFoldersHelpText": "Opret manglende filmmapper under diskscanning", "CouldNotConnectSignalR": "Kunne ikke oprette forbindelse til SignalR, UI opdateres ikke", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index bd21479cad..7e4998d94d 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -774,7 +774,7 @@ "UpgradesAllowed": "Upgrades erlaubt", "UnmappedFilesOnly": "Nur nicht zugeordnete Dateien", "Unlimited": "Unlimitiert", - "UpdateRadarrDirectlyLoadError": "{appName} konnte nicht direkt aktualisiert werden,", + "UpdateAppDirectlyLoadError": "{appName} konnte nicht direkt aktualisiert werden,", "UnableToLoadManualImportItems": "Einträge für manuelles importieren konnten nicht geladen werden", "AlternativeTitlesLoadError": "Alternative Titel konnten nicht geladen werden.", "Trigger": "Auslöser", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 90886d17d2..a0b2e13092 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -893,7 +893,7 @@ "UnableToLoadRootFolders": "Δεν είναι δυνατή η φόρτωση ριζικών φακέλων", "TagsLoadError": "Δεν είναι δυνατή η φόρτωση ετικετών", "CalendarLoadError": "Δεν είναι δυνατή η φόρτωση του ημερολογίου", - "UpdateRadarrDirectlyLoadError": "Δεν είναι δυνατή η απευθείας ενημέρωση του {appName},", + "UpdateAppDirectlyLoadError": "Δεν είναι δυνατή η απευθείας ενημέρωση του {appName},", "Ungroup": "Κατάργηση ομάδας", "Unlimited": "Απεριόριστος", "UnmappedFilesOnly": "Μόνο μη αντιστοιχισμένα αρχεία", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index ae7a54cc5a..a5dc41ce0c 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -795,7 +795,11 @@ "IndexersSettingsSummary": "Indexers and release restrictions", "Info": "Info", "InfoUrl": "Info URL", + "Install": "Install", "InstallLatest": "Install Latest", + "InstallMajorVersionUpdate": "Install Update", + "InstallMajorVersionUpdateMessage": "This update will install a new major version and may not be compatible with your system. Are you sure you want to install this update?", + "InstallMajorVersionUpdateMessageLink": "Please check [{domain}]({url}) for more information.", "InstanceName": "Instance Name", "InstanceNameHelpText": "Instance name in tab and for Syslog app name", "InteractiveImport": "Interactive Import", @@ -1774,6 +1778,7 @@ "UnsavedChanges": "Unsaved Changes", "UnselectAll": "Unselect All", "UpdateAll": "Update All", + "UpdateAppDirectlyLoadError": "Unable to update {appName} directly,", "UpdateAutomaticallyHelpText": "Automatically download and install updates. You will still be able to install from System: Updates", "UpdateAvailableHealthCheckMessage": "New update is available: {version}", "UpdateCheckStartupNotWritableMessage": "Cannot install update because startup folder '{startupFolder}' is not writable by the user '{userName}'.", @@ -1781,7 +1786,6 @@ "UpdateCheckUINotWritableMessage": "Cannot install update because UI folder '{uiFolder}' is not writable by the user '{userName}'.", "UpdateFiltered": "Update Filtered", "UpdateMechanismHelpText": "Use {appName}'s built-in updater or a script", - "UpdateRadarrDirectlyLoadError": "Unable to update {appName} directly,", "UpdateScriptPathHelpText": "Path to a custom script that takes an extracted update package and handle the remainder of the update process", "UpdateSelected": "Update Selected", "UpdaterLogFiles": "Updater Log Files", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 28a509be23..810583bc79 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -926,7 +926,7 @@ "Trigger": "Desencadenar", "Unlimited": "Ilimitado", "UnableToLoadManualImportItems": "No se pueden cargar elementos de importación manual", - "UpdateRadarrDirectlyLoadError": "No se puede actualizar {appName} directamente,", + "UpdateAppDirectlyLoadError": "No se puede actualizar {appName} directamente,", "UnmappedFilesOnly": "Solo archivos sin mapear", "UpgradeUntilCustomFormatScore": "Actualizar hasta la puntuación de formato personalizado", "UpgradeUntil": "Actualizar hasta", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 41d5ac72f6..273289ba9e 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -896,7 +896,7 @@ "UnableToLoadRootFolders": "Juurikansioiden lataus epäonnistui.", "TagsLoadError": "Tunnisteiden lataus ei onnistu", "CalendarLoadError": "Kalenterin lataus epäonnistui.", - "UpdateRadarrDirectlyLoadError": "{appName}ia ei voida päivittää suoraan,", + "UpdateAppDirectlyLoadError": "{appName}ia ei voida päivittää suoraan,", "Ungroup": "Pura ryhmä", "UnmappedFilesOnly": "Vain kohdistamattomat tiedostot", "UnmappedFolders": "Kohdistamattomat kansiot", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 9da523bd0c..00be66ddb8 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -934,7 +934,7 @@ "Trakt": "Trakt", "Trigger": "Déclencheur", "UnableToLoadManualImportItems": "Impossible de charger les éléments d'importation manuelle", - "UpdateRadarrDirectlyLoadError": "Impossible de mettre à jour {appName} directement,", + "UpdateAppDirectlyLoadError": "Impossible de mettre à jour {appName} directement,", "Unlimited": "Illimité", "UnmappedFilesOnly": "Fichiers non mappés uniquement", "UpgradeUntilCustomFormatScore": "Mise à niveau jusqu'au score de format personnalisé", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 774e1d9e17..7f48a470fd 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -898,7 +898,7 @@ "UnableToLoadRootFolders": "לא ניתן לטעון תיקיות שורש", "CalendarLoadError": "לא ניתן לטעון את היומן", "Unlimited": "ללא הגבלה", - "UpdateRadarrDirectlyLoadError": "לא ניתן לעדכן את {appName} ישירות,", + "UpdateAppDirectlyLoadError": "לא ניתן לעדכן את {appName} ישירות,", "Ungroup": "בטל קבוצה", "UnmappedFilesOnly": "קבצים שלא ממופים בלבד", "UnmappedFolders": "תיקיות לא ממופות", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 82e0358987..28b3170d49 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -241,7 +241,7 @@ "QualityProfilesLoadError": "गुणवत्ता प्रोफ़ाइल लोड करने में असमर्थ", "RemotePathMappingsLoadError": "दूरस्थ पथ मैपिंग लोड करने में असमर्थ", "CalendarLoadError": "कैलेंडर लोड करने में असमर्थ", - "UpdateRadarrDirectlyLoadError": "सीधे {appName} अद्यतन करने में असमर्थ,", + "UpdateAppDirectlyLoadError": "सीधे {appName} अद्यतन करने में असमर्थ,", "UnmappedFolders": "बिना मोड़े हुए फोल्डर", "ICalIncludeUnmonitoredMoviesHelpText": "ICal फीड में अनऑमिटर की गई फिल्में शामिल करें", "UnselectAll": "सभी का चयन रद्द", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 360416e1c9..d8b4da1735 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -846,7 +846,7 @@ "UpgradesAllowed": "Frissítések Engedélyezve", "UnmappedFilesOnly": "Kizárólag fel nem térképezett fájlokat", "Unlimited": "korlátlan", - "UpdateRadarrDirectlyLoadError": "Nem lehetséges közvetlenül frissíteni a {appName}-t", + "UpdateAppDirectlyLoadError": "Nem lehetséges közvetlenül frissíteni a {appName}-t", "UnableToLoadManualImportItems": "Nem lehetséges betölteni a manuálisan importált elemeket", "AlternativeTitlesLoadError": "Nem lehetséges betölteni az alternatív címeket.", "Trigger": "Trigger", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index dac8040927..a5dafe8bcc 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -899,7 +899,7 @@ "UnableToLoadRootFolders": "Ekki er hægt að hlaða rótarmöppum", "TagsLoadError": "Ekki er hægt að hlaða merkin", "CalendarLoadError": "Ekki er hægt að hlaða dagatalið", - "UpdateRadarrDirectlyLoadError": "Ekki er hægt að uppfæra {appName} beint,", + "UpdateAppDirectlyLoadError": "Ekki er hægt að uppfæra {appName} beint,", "Ungroup": "Aftengja hópinn", "Unlimited": "Ótakmarkað", "UnmappedFilesOnly": "Aðeins ókortlagðar skrár", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index c766a1979b..77c4e82102 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -932,7 +932,7 @@ "Trigger": "Trigger", "UnableToLoadManualImportItems": "Impossibile caricare gli elementi di importazione manuale", "Unlimited": "Illimitato", - "UpdateRadarrDirectlyLoadError": "Impossibile aggiornare {appName} direttamente,", + "UpdateAppDirectlyLoadError": "Impossibile aggiornare {appName} direttamente,", "UnmappedFilesOnly": "Solo file non mappati", "UpgradeUntilCustomFormatScore": "Aggiorna fino al punteggio formato personalizzato", "UpgradeUntil": "Upgrade fino alla qualità", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index c02ec68e4e..157de467b8 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -896,7 +896,7 @@ "UnableToLoadRootFolders": "ルートフォルダを読み込めません", "TagsLoadError": "タグを読み込めません", "CalendarLoadError": "カレンダーを読み込めません", - "UpdateRadarrDirectlyLoadError": "{appName}を直接更新できません。", + "UpdateAppDirectlyLoadError": "{appName}を直接更新できません。", "Ungroup": "グループ化を解除", "UnmappedFilesOnly": "マップされていないファイルのみ", "UnmappedFolders": "マップされていないフォルダ", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 2d3f8e1853..23456bb358 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -899,7 +899,7 @@ "UnableToLoadRestrictions": "제한을 불러올 수 없습니다.", "UnableToLoadRootFolders": "루트 폴더를 불러올 수 없습니다.", "CalendarLoadError": "달력을 불러올 수 없습니다.", - "UpdateRadarrDirectlyLoadError": "{appName}를 직접 업데이트 할 수 없습니다.", + "UpdateAppDirectlyLoadError": "{appName}를 직접 업데이트 할 수 없습니다.", "Ungroup": "그룹 해제", "UnmappedFilesOnly": "매핑되지 않은 파일 만", "UnmappedFolders": "매핑되지 않은 폴더", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 2f9909b224..8764a475bd 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -934,7 +934,7 @@ "Trakt": "Trakt", "Trigger": "In gang zetten", "UnableToLoadManualImportItems": "Kan items voor handmatig importeren niet laden", - "UpdateRadarrDirectlyLoadError": "Kan {appName} niet rechtstreeks updaten,", + "UpdateAppDirectlyLoadError": "Kan {appName} niet rechtstreeks updaten,", "Unlimited": "Onbeperkt", "UnmappedFilesOnly": "Alleen niet-toegewezen bestanden", "UpgradeUntilCustomFormatScore": "Upgraden tot Score aangepast formaat", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index df6f9aa2c1..5cc125898b 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -901,7 +901,7 @@ "UnableToLoadRootFolders": "Nie można załadować folderów głównych", "TagsLoadError": "Nie można załadować tagów", "CalendarLoadError": "Nie można załadować kalendarza", - "UpdateRadarrDirectlyLoadError": "Nie można bezpośrednio zaktualizować {appName},", + "UpdateAppDirectlyLoadError": "Nie można bezpośrednio zaktualizować {appName},", "Ungroup": "Rozgrupuj", "Unlimited": "Nieograniczony", "Unmonitored": "Niemonitorowane", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 0d0a9f258e..7fb42ff7dc 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -934,7 +934,7 @@ "Trakt": "Trakt", "Trigger": "Acionador", "UnableToLoadManualImportItems": "Não foi possível carregar os itens de importação manual", - "UpdateRadarrDirectlyLoadError": "Não foi possível atualizar o {appName} diretamente,", + "UpdateAppDirectlyLoadError": "Não foi possível atualizar o {appName} diretamente,", "Unlimited": "Ilimitado", "UnmappedFilesOnly": "Somente ficheiros não mapeados", "UpgradeUntilCustomFormatScore": "Atualizar até a pontuação do formato personalizado", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 22ebe4532f..e186610332 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -906,7 +906,7 @@ "Unlimited": "Ilimitado", "Ungroup": "Desagrupar", "Unavailable": "Indisponível", - "UpdateRadarrDirectlyLoadError": "Não foi possível carregar o {appName} diretamente,", + "UpdateAppDirectlyLoadError": "Não foi possível carregar o {appName} diretamente,", "UiSettingsLoadError": "Não foi possível carregar as configurações da interface", "CalendarLoadError": "Não foi possível carregar o calendário", "TagsLoadError": "Não foi possível carregar as tags", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 2e6f09358a..36ea94c6b5 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -912,7 +912,7 @@ "UnableToLoadRootFolders": "Imposibil de încărcat folderele rădăcină", "TagsLoadError": "Nu se pot încărca etichete", "CalendarLoadError": "Calendarul nu poate fi încărcat", - "UpdateRadarrDirectlyLoadError": "Imposibil de actualizat direct {appName},", + "UpdateAppDirectlyLoadError": "Imposibil de actualizat direct {appName},", "Ungroup": "Dezgrupează", "Unlimited": "Nelimitat", "UnmappedFilesOnly": "Numai fișiere nemapate", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 4b5627d5fd..8d134e2ba8 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -720,7 +720,7 @@ "Unlimited": "Неограниченно", "Ungroup": "Разгруппировать", "Unavailable": "Недоступно", - "UpdateRadarrDirectlyLoadError": "Невозможно обновить {appName} напрямую,", + "UpdateAppDirectlyLoadError": "Невозможно обновить {appName} напрямую,", "UiSettingsLoadError": "Не удалось загрузить настройки пользовательского интерфейса", "CalendarLoadError": "Не удалось загрузить календарь", "TagsLoadError": "Невозможно загрузить теги", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index ca7f7d820a..79c6e926bc 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -935,7 +935,7 @@ "UnableToLoadRestrictions": "Det gick inte att ladda begränsningar", "UnableToLoadRootFolders": "Det gick inte att ladda rotmappar", "CalendarLoadError": "Det gick inte att ladda kalendern", - "UpdateRadarrDirectlyLoadError": "Det går inte att uppdatera {appName} direkt,", + "UpdateAppDirectlyLoadError": "Det går inte att uppdatera {appName} direkt,", "UpgradeUntilCustomFormatScore": "Uppgradera tills anpassat formatpoäng", "UpgradeUntil": "Uppgradera tills kvalitet", "UpgradeUntilThisQualityIsMetOrExceeded": "Uppgradera tills den här kvaliteten uppfylls eller överskrids", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 5f350362ae..d701831805 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -907,7 +907,7 @@ "UnableToLoadRestrictions": "ไม่สามารถโหลดข้อ จำกัด", "UnableToLoadRootFolders": "ไม่สามารถโหลดโฟลเดอร์รูท", "CalendarLoadError": "ไม่สามารถโหลดปฏิทิน", - "UpdateRadarrDirectlyLoadError": "ไม่สามารถอัปเดต {appName} ได้โดยตรง", + "UpdateAppDirectlyLoadError": "ไม่สามารถอัปเดต {appName} ได้โดยตรง", "Ungroup": "ยกเลิกการจัดกลุ่ม", "Unlimited": "ไม่ จำกัด", "UnmappedFilesOnly": "ไฟล์ที่ไม่ได้แมปเท่านั้น", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index a3b4c5de6d..97ee048e46 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -338,7 +338,7 @@ "UnableToLoadRestrictions": "Kısıtlamalar yüklenemiyor", "UnableToLoadRootFolders": "Kök klasörler yüklenemiyor", "TagsLoadError": "Etiketler yüklenemiyor", - "UpdateRadarrDirectlyLoadError": "{appName} doğrudan güncellenemiyor,", + "UpdateAppDirectlyLoadError": "{appName} doğrudan güncellenemiyor,", "Ungroup": "Grubu çöz", "Unlimited": "Sınırsız", "UnmappedFilesOnly": "Yalnızca Eşlenmemiş Dosyalar", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 90b7947b09..fc596afd73 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -892,7 +892,7 @@ "QualityDefinitionsLoadError": "Не вдалося завантажити визначення якості", "RemotePathMappingsLoadError": "Неможливо завантажити віддалені відображення шляхів", "UnableToLoadRootFolders": "Не вдалося завантажити кореневі папки", - "UpdateRadarrDirectlyLoadError": "Неможливо оновити {appName} безпосередньо,", + "UpdateAppDirectlyLoadError": "Неможливо оновити {appName} безпосередньо,", "Unavailable": "Недоступний", "Unlimited": "Необмежений", "UnmappedFilesOnly": "Лише незіставлені файли", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 74becaf4ee..6a58934f04 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -912,7 +912,7 @@ "QualityProfilesLoadError": "Không thể tải Hồ sơ chất lượng", "RemotePathMappingsLoadError": "Không thể tải Ánh xạ đường dẫn từ xa", "UnableToLoadRootFolders": "Không thể tải các thư mục gốc", - "UpdateRadarrDirectlyLoadError": "Không thể cập nhật {appName} trực tiếp,", + "UpdateAppDirectlyLoadError": "Không thể cập nhật {appName} trực tiếp,", "Ungroup": "Bỏ nhóm", "Unlimited": "Vô hạn", "UnmappedFilesOnly": "Chỉ các tệp chưa được ánh xạ", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 4a0e1bfc02..059441bb8b 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -127,7 +127,7 @@ "Unmonitored": "未追踪项", "Unlimited": "无限制", "Unavailable": "不可用", - "UpdateRadarrDirectlyLoadError": "无法直接更新{appName}", + "UpdateAppDirectlyLoadError": "无法直接更新{appName}", "UiSettingsLoadError": "无法加载UI设置", "CalendarLoadError": "无法加载日历", "TagsLoadError": "无法加载标签", diff --git a/src/NzbDrone.Core/Update/Commands/ApplicationCheckUpdateCommand.cs b/src/NzbDrone.Core/Update/Commands/ApplicationCheckUpdateCommand.cs index 6987af3faa..86461405f3 100644 --- a/src/NzbDrone.Core/Update/Commands/ApplicationCheckUpdateCommand.cs +++ b/src/NzbDrone.Core/Update/Commands/ApplicationCheckUpdateCommand.cs @@ -7,5 +7,7 @@ public class ApplicationCheckUpdateCommand : Command public override bool SendUpdatesToClient => true; public override string CompletionMessage => null; + + public bool InstallMajorUpdate { get; set; } } } diff --git a/src/NzbDrone.Core/Update/Commands/ApplicationUpdateCommand.cs b/src/NzbDrone.Core/Update/Commands/ApplicationUpdateCommand.cs index 59a827a0b0..6980af7088 100644 --- a/src/NzbDrone.Core/Update/Commands/ApplicationUpdateCommand.cs +++ b/src/NzbDrone.Core/Update/Commands/ApplicationUpdateCommand.cs @@ -4,6 +4,7 @@ namespace NzbDrone.Core.Update.Commands { public class ApplicationUpdateCommand : Command { + public bool InstallMajorUpdate { get; set; } public override bool SendUpdatesToClient => true; public override bool IsExclusive => true; } diff --git a/src/NzbDrone.Core/Update/InstallUpdateService.cs b/src/NzbDrone.Core/Update/InstallUpdateService.cs index 91acb79521..0fe738bb5a 100644 --- a/src/NzbDrone.Core/Update/InstallUpdateService.cs +++ b/src/NzbDrone.Core/Update/InstallUpdateService.cs @@ -231,7 +231,7 @@ private void EnsureAppDataSafety() } } - private UpdatePackage GetUpdatePackage(CommandTrigger updateTrigger) + private UpdatePackage GetUpdatePackage(CommandTrigger updateTrigger, bool installMajorUpdate) { _logger.ProgressDebug("Checking for updates"); @@ -243,7 +243,13 @@ private UpdatePackage GetUpdatePackage(CommandTrigger updateTrigger) return null; } - if (OsInfo.IsNotWindows && !_configFileProvider.UpdateAutomatically && updateTrigger != CommandTrigger.Manual) + if (latestAvailable.Version.Major > BuildInfo.Version.Major && !installMajorUpdate) + { + _logger.ProgressInfo("Unable to install major update, please update update manually from System: Updates"); + return null; + } + + if (!_configFileProvider.UpdateAutomatically && updateTrigger != CommandTrigger.Manual) { _logger.ProgressDebug("Auto-update not enabled, not installing available update."); return null; @@ -272,7 +278,7 @@ private UpdatePackage GetUpdatePackage(CommandTrigger updateTrigger) public void Execute(ApplicationCheckUpdateCommand message) { - if (GetUpdatePackage(message.Trigger) != null) + if (GetUpdatePackage(message.Trigger, true) != null) { _commandQueueManager.Push(new ApplicationUpdateCommand(), trigger: message.Trigger); } @@ -280,7 +286,7 @@ public void Execute(ApplicationCheckUpdateCommand message) public void Execute(ApplicationUpdateCommand message) { - var latestAvailable = GetUpdatePackage(message.Trigger); + var latestAvailable = GetUpdatePackage(message.Trigger, message.InstallMajorUpdate); if (latestAvailable != null) { diff --git a/src/NzbDrone.Core/Update/UpdatePackageProvider.cs b/src/NzbDrone.Core/Update/UpdatePackageProvider.cs index 8d82fefcb6..b0543366fa 100644 --- a/src/NzbDrone.Core/Update/UpdatePackageProvider.cs +++ b/src/NzbDrone.Core/Update/UpdatePackageProvider.cs @@ -42,6 +42,7 @@ public UpdatePackage GetLatestUpdate(string branch, Version currentVersion) .AddQueryParam("runtime", "netcore") .AddQueryParam("runtimeVer", _platformInfo.Version) .AddQueryParam("dbType", _mainDatabase.DatabaseType) + .AddQueryParam("includeMajorVersion", true) .SetSegment("branch", branch); if (_analyticsService.IsEnabled) From 9986d04d3614336395c55b3d00313812662f609b Mon Sep 17 00:00:00 2001 From: Servarr Date: Sat, 19 Oct 2024 06:13:09 +0000 Subject: [PATCH 023/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 30dc950c9b..80b72ce54f 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -12352,11 +12352,13 @@ "fr", "de", "gb", + "in", "ie", "it", + "nz", + "ro", "es", - "us", - "nz" + "us" ], "type": "string" }, From cd29c0c9c84ce05913bbdb69d542717de75dd792 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 20 Oct 2024 04:41:00 +0300 Subject: [PATCH 024/579] Fix stable branch label in update --- frontend/src/System/Updates/Updates.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/System/Updates/Updates.tsx b/frontend/src/System/Updates/Updates.tsx index df635e5d7f..1d2fb5e2c3 100644 --- a/frontend/src/System/Updates/Updates.tsx +++ b/frontend/src/System/Updates/Updates.tsx @@ -208,7 +208,7 @@ function Updates() { {formatDate(update.releaseDate, shortDateFormat)} - {update.branch === 'main' ? null : ( + {update.branch === 'master' ? null : ( )} From dd90bf53dd8c146ebf4ab0a02ec5ee1ac0bbe8bf Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 20 Oct 2024 08:04:41 +0300 Subject: [PATCH 025/579] Bump version to 5.13.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index afe7c821a1..b40be13662 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.13.0' + majorVersion: '5.13.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From abf1b9d6cf0d8e3dfbd71337d7536af050957715 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 21 Oct 2024 09:52:55 +0300 Subject: [PATCH 026/579] Fallback to text searches for FL only if year is defined --- .../Indexers/FileList/FileListRequestGenerator.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/FileList/FileListRequestGenerator.cs b/src/NzbDrone.Core/Indexers/FileList/FileListRequestGenerator.cs index 9f397487d7..d8e737a8fc 100644 --- a/src/NzbDrone.Core/Indexers/FileList/FileListRequestGenerator.cs +++ b/src/NzbDrone.Core/Indexers/FileList/FileListRequestGenerator.cs @@ -26,14 +26,14 @@ public virtual IndexerPageableRequestChain GetSearchRequests(MovieSearchCriteria if (searchCriteria.Movie.MovieMetadata.Value.ImdbId.IsNotNullOrWhiteSpace()) { - pageableRequests.Add(GetRequest("search-torrents", string.Format("&type=imdb&query={0}", searchCriteria.Movie.MovieMetadata.Value.ImdbId))); + pageableRequests.Add(GetRequest("search-torrents", $"&type=imdb&query={searchCriteria.Movie.MovieMetadata.Value.ImdbId}")); } - else + else if (searchCriteria.Movie.Year > 0) { foreach (var queryTitle in searchCriteria.CleanSceneTitles) { - var titleYearSearchQuery = string.Format("{0}+{1}", queryTitle, searchCriteria.Movie.Year); - pageableRequests.Add(GetRequest("search-torrents", string.Format("&type=name&query={0}", titleYearSearchQuery.Trim()))); + var titleYearSearchQuery = $"{queryTitle}+{searchCriteria.Movie.Year}"; + pageableRequests.Add(GetRequest("search-torrents", $"&type=name&query={titleYearSearchQuery.Trim()}")); } } @@ -44,7 +44,7 @@ private IEnumerable GetRequest(string searchType, string paramet { var categoriesQuery = string.Join(",", Settings.Categories.Distinct()); - var baseUrl = string.Format("{0}/api.php?action={1}&category={2}{3}", Settings.BaseUrl.TrimEnd('/'), searchType, categoriesQuery, parameters); + var baseUrl = $"{Settings.BaseUrl.TrimEnd('/')}/api.php?action={searchType}&category={categoriesQuery}{parameters}"; var request = new IndexerRequest(baseUrl, HttpAccept.Json); request.HttpRequest.Credentials = new BasicNetworkCredential(Settings.Username.Trim(), Settings.Passkey.Trim()); From 56a7725e52b7ae9485876e2e1332dbeafcbfc92e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 21 Oct 2024 09:55:28 +0300 Subject: [PATCH 027/579] Improve warning for missing release dates on movie details page when year is not set Towards #10569 --- frontend/src/Movie/Details/MovieDetails.js | 43 +++++++++++-------- .../src/Movie/Details/MovieReleaseDates.tsx | 11 ++++- .../src/Movie/Index/Table/MovieIndexRow.tsx | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 2 +- 4 files changed, 35 insertions(+), 23 deletions(-) diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 33d8c73fe3..758502393c 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -429,26 +429,31 @@ class MovieDetails extends Component { null } - { - year > 0 ? - - - } - position={tooltipPositions.BOTTOM} + + 0 ? ( + year + ) : ( + + ) + } + title={translate('ReleaseDates')} + body={ + - : - null - } + } + position={tooltipPositions.BOTTOM} + /> + { runtime ? diff --git a/frontend/src/Movie/Details/MovieReleaseDates.tsx b/frontend/src/Movie/Details/MovieReleaseDates.tsx index ed5c490ed4..0805026ab3 100644 --- a/frontend/src/Movie/Details/MovieReleaseDates.tsx +++ b/frontend/src/Movie/Details/MovieReleaseDates.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { useSelector } from 'react-redux'; import Icon from 'Components/Icon'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; import { icons } from 'Helpers/Props'; import Movie from 'Movie/Movie'; import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; @@ -11,10 +12,11 @@ import styles from './MovieReleaseDates.css'; type MovieReleaseDatesProps = Pick< Movie, - 'inCinemas' | 'digitalRelease' | 'physicalRelease' + 'tmdbId' | 'inCinemas' | 'digitalRelease' | 'physicalRelease' >; function MovieReleaseDates({ + tmdbId, inCinemas, digitalRelease, physicalRelease, @@ -28,7 +30,12 @@ function MovieReleaseDates({
- {translate('NoMovieReleaseDatesAvailable')} + + ); } diff --git a/frontend/src/Movie/Index/Table/MovieIndexRow.tsx b/frontend/src/Movie/Index/Table/MovieIndexRow.tsx index de6857a1f8..cf4b48c104 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexRow.tsx +++ b/frontend/src/Movie/Index/Table/MovieIndexRow.tsx @@ -236,7 +236,7 @@ function MovieIndexRow(props: MovieIndexRowProps) { if (name === 'year') { return ( - {year} + {year > 0 ? year : null} ); } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index a5dc41ce0c..cf260db725 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1049,7 +1049,7 @@ "NoMinimumForAnyRuntime": "No minimum for any runtime", "NoMoveFilesSelf": " No, I'll Move the Files Myself", "NoMovieFilesToManage": "No movie files to manage.", - "NoMovieReleaseDatesAvailable": "No release dates available on TMDb for this movie.", + "NoMovieReleaseDatesAvailable": "No release dates available on [TMDb]({url}) for this movie.", "NoMoviesExist": "No movies found, to get started you'll want to add a new movie or import some existing ones.", "NoResultsFound": "No results found", "NoTagsHaveBeenAddedYet": "No tags have been added yet", From f8e47fbdc731527aaf60f679477e144c05b23cdf Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 22 Oct 2024 05:57:21 +0300 Subject: [PATCH 028/579] Tooltips for certification and runtime on details page --- frontend/src/Movie/Details/MovieDetails.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 758502393c..8aadf60fd3 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -423,7 +423,7 @@ class MovieDetails extends Component {
{ certification ? - + {certification} : null @@ -457,7 +457,7 @@ class MovieDetails extends Component { { runtime ? - + {formatRuntime(runtime, movieRuntimeFormat)} : null From dc29526961c3f1a5bc37d0127b68b82e85a4d9d8 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Wed, 24 Jul 2024 16:39:01 -0700 Subject: [PATCH 029/579] Convert App to TypeScript (cherry picked from commit d6d90a64a39d3b9d3a95fb6b265517693a70fdd7) Closes #10233 --- frontend/src/App/{App.js => App.tsx} | 18 +- .../src/App/{AppRoutes.js => AppRoutes.tsx} | 181 ++++-------------- frontend/src/App/AppUpdatedModal.js | 30 --- frontend/src/App/AppUpdatedModal.tsx | 28 +++ frontend/src/App/AppUpdatedModalConnector.js | 12 -- frontend/src/App/AppUpdatedModalContent.js | 139 -------------- frontend/src/App/AppUpdatedModalContent.tsx | 145 ++++++++++++++ .../App/AppUpdatedModalContentConnector.js | 78 -------- ...iredContext.js => ColorImpairedContext.ts} | 0 ...onLostModal.js => ConnectionLostModal.tsx} | 43 ++--- .../src/App/ConnectionLostModalConnector.js | 12 -- frontend/src/App/State/AppState.ts | 1 + frontend/src/Components/Page/Page.js | 8 +- package.json | 1 + yarn.lock | 7 + 15 files changed, 253 insertions(+), 450 deletions(-) rename frontend/src/App/{App.js => App.tsx} (68%) rename frontend/src/App/{AppRoutes.js => AppRoutes.tsx} (50%) delete mode 100644 frontend/src/App/AppUpdatedModal.js create mode 100644 frontend/src/App/AppUpdatedModal.tsx delete mode 100644 frontend/src/App/AppUpdatedModalConnector.js delete mode 100644 frontend/src/App/AppUpdatedModalContent.js create mode 100644 frontend/src/App/AppUpdatedModalContent.tsx delete mode 100644 frontend/src/App/AppUpdatedModalContentConnector.js rename frontend/src/App/{ColorImpairedContext.js => ColorImpairedContext.ts} (100%) rename frontend/src/App/{ConnectionLostModal.js => ConnectionLostModal.tsx} (54%) delete mode 100644 frontend/src/App/ConnectionLostModalConnector.js diff --git a/frontend/src/App/App.js b/frontend/src/App/App.tsx similarity index 68% rename from frontend/src/App/App.js rename to frontend/src/App/App.tsx index 5715dd3e33..166bf5dec5 100644 --- a/frontend/src/App/App.js +++ b/frontend/src/App/App.tsx @@ -1,20 +1,25 @@ -import { ConnectedRouter } from 'connected-react-router'; -import PropTypes from 'prop-types'; +import { ConnectedRouter, ConnectedRouterProps } from 'connected-react-router'; import React from 'react'; import DocumentTitle from 'react-document-title'; import { Provider } from 'react-redux'; +import { Store } from 'redux'; import PageConnector from 'Components/Page/PageConnector'; import ApplyTheme from './ApplyTheme'; import AppRoutes from './AppRoutes'; -function App({ store, history }) { +interface AppProps { + store: Store; + history: ConnectedRouterProps['history']; +} + +function App({ store, history }: AppProps) { return ( - + @@ -22,9 +27,4 @@ function App({ store, history }) { ); } -App.propTypes = { - store: PropTypes.object.isRequired, - history: PropTypes.object.isRequired -}; - export default App; diff --git a/frontend/src/App/AppRoutes.js b/frontend/src/App/AppRoutes.tsx similarity index 50% rename from frontend/src/App/AppRoutes.js rename to frontend/src/App/AppRoutes.tsx index fa293dc226..f562083f32 100644 --- a/frontend/src/App/AppRoutes.js +++ b/frontend/src/App/AppRoutes.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import { Redirect, Route } from 'react-router-dom'; import Blocklist from 'Activity/Blocklist/Blocklist'; @@ -36,141 +35,85 @@ import getPathWithUrlBase from 'Utilities/getPathWithUrlBase'; import CutoffUnmetConnector from 'Wanted/CutoffUnmet/CutoffUnmetConnector'; import MissingConnector from 'Wanted/Missing/MissingConnector'; -function AppRoutes(props) { - const { - app - } = props; +function RedirectWithUrlBase() { + return ; +} +function AppRoutes() { return ( {/* Movies */} - + - { - window.Radarr.urlBase && - { - return ( - - ); - }} - /> - } + {window.Radarr.urlBase && ( + + )} - + - + - + - + - + {/* Calendar */} - + {/* Activity */} - + - + - + {/* Wanted */} - + - + {/* Settings */} - + - + - + - + - + - + - + - + - + {/* System */} - + - + - + - + - + - + {/* Not Found */} - + ); } -AppRoutes.propTypes = { - app: PropTypes.func.isRequired -}; - export default AppRoutes; diff --git a/frontend/src/App/AppUpdatedModal.js b/frontend/src/App/AppUpdatedModal.js deleted file mode 100644 index abc7f8832f..0000000000 --- a/frontend/src/App/AppUpdatedModal.js +++ /dev/null @@ -1,30 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import AppUpdatedModalContentConnector from './AppUpdatedModalContentConnector'; - -function AppUpdatedModal(props) { - const { - isOpen, - onModalClose - } = props; - - return ( - - - - ); -} - -AppUpdatedModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default AppUpdatedModal; diff --git a/frontend/src/App/AppUpdatedModal.tsx b/frontend/src/App/AppUpdatedModal.tsx new file mode 100644 index 0000000000..696d36fb24 --- /dev/null +++ b/frontend/src/App/AppUpdatedModal.tsx @@ -0,0 +1,28 @@ +import React, { useCallback } from 'react'; +import Modal from 'Components/Modal/Modal'; +import AppUpdatedModalContent from './AppUpdatedModalContent'; + +interface AppUpdatedModalProps { + isOpen: boolean; + onModalClose: (...args: unknown[]) => unknown; +} + +function AppUpdatedModal(props: AppUpdatedModalProps) { + const { isOpen, onModalClose } = props; + + const handleModalClose = useCallback(() => { + location.reload(); + }, []); + + return ( + + + + ); +} + +export default AppUpdatedModal; diff --git a/frontend/src/App/AppUpdatedModalConnector.js b/frontend/src/App/AppUpdatedModalConnector.js deleted file mode 100644 index a21afbc5aa..0000000000 --- a/frontend/src/App/AppUpdatedModalConnector.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from 'react-redux'; -import AppUpdatedModal from './AppUpdatedModal'; - -function createMapDispatchToProps(dispatch, props) { - return { - onModalClose() { - location.reload(); - } - }; -} - -export default connect(null, createMapDispatchToProps)(AppUpdatedModal); diff --git a/frontend/src/App/AppUpdatedModalContent.js b/frontend/src/App/AppUpdatedModalContent.js deleted file mode 100644 index 8cce1bc16c..0000000000 --- a/frontend/src/App/AppUpdatedModalContent.js +++ /dev/null @@ -1,139 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Button from 'Components/Link/Button'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import { kinds } from 'Helpers/Props'; -import UpdateChanges from 'System/Updates/UpdateChanges'; -import translate from 'Utilities/String/translate'; -import styles from './AppUpdatedModalContent.css'; - -function mergeUpdates(items, version, prevVersion) { - let installedIndex = items.findIndex((u) => u.version === version); - let installedPreviouslyIndex = items.findIndex((u) => u.version === prevVersion); - - if (installedIndex === -1) { - installedIndex = 0; - } - - if (installedPreviouslyIndex === -1) { - installedPreviouslyIndex = items.length; - } else if (installedPreviouslyIndex === installedIndex && items.length) { - installedPreviouslyIndex += 1; - } - - const appliedUpdates = items.slice(installedIndex, installedPreviouslyIndex); - - if (!appliedUpdates.length) { - return null; - } - - const appliedChanges = { new: [], fixed: [] }; - appliedUpdates.forEach((u) => { - if (u.changes) { - appliedChanges.new.push(... u.changes.new); - appliedChanges.fixed.push(... u.changes.fixed); - } - }); - - const mergedUpdate = Object.assign({}, appliedUpdates[0], { changes: appliedChanges }); - - if (!appliedChanges.new.length && !appliedChanges.fixed.length) { - mergedUpdate.changes = null; - } - - return mergedUpdate; -} - -function AppUpdatedModalContent(props) { - const { - version, - prevVersion, - isPopulated, - error, - items, - onSeeChangesPress, - onModalClose - } = props; - - const update = mergeUpdates(items, version, prevVersion); - - return ( - - - {translate('AppUpdated')} - - - -
- -
- - { - isPopulated && !error && !!update && -
- { - !update.changes && -
{translate('MaintenanceRelease')}
- } - - { - !!update.changes && -
-
- {translate('WhatsNew')} -
- - - - -
- } -
- } - - { - !isPopulated && !error && - - } -
- - - - - - -
- ); -} - -AppUpdatedModalContent.propTypes = { - version: PropTypes.string.isRequired, - prevVersion: PropTypes.string, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - onSeeChangesPress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default AppUpdatedModalContent; diff --git a/frontend/src/App/AppUpdatedModalContent.tsx b/frontend/src/App/AppUpdatedModalContent.tsx new file mode 100644 index 0000000000..6031f748fd --- /dev/null +++ b/frontend/src/App/AppUpdatedModalContent.tsx @@ -0,0 +1,145 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import Button from 'Components/Link/Button'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { kinds } from 'Helpers/Props'; +import { fetchUpdates } from 'Store/Actions/systemActions'; +import UpdateChanges from 'System/Updates/UpdateChanges'; +import Update from 'typings/Update'; +import translate from 'Utilities/String/translate'; +import AppState from './State/AppState'; +import styles from './AppUpdatedModalContent.css'; + +function mergeUpdates(items: Update[], version: string, prevVersion?: string) { + let installedIndex = items.findIndex((u) => u.version === version); + let installedPreviouslyIndex = items.findIndex( + (u) => u.version === prevVersion + ); + + if (installedIndex === -1) { + installedIndex = 0; + } + + if (installedPreviouslyIndex === -1) { + installedPreviouslyIndex = items.length; + } else if (installedPreviouslyIndex === installedIndex && items.length) { + installedPreviouslyIndex += 1; + } + + const appliedUpdates = items.slice(installedIndex, installedPreviouslyIndex); + + if (!appliedUpdates.length) { + return null; + } + + const appliedChanges: Update['changes'] = { new: [], fixed: [] }; + + appliedUpdates.forEach((u: Update) => { + if (u.changes) { + appliedChanges.new.push(...u.changes.new); + appliedChanges.fixed.push(...u.changes.fixed); + } + }); + + const mergedUpdate: Update = Object.assign({}, appliedUpdates[0], { + changes: appliedChanges, + }); + + if (!appliedChanges.new.length && !appliedChanges.fixed.length) { + mergedUpdate.changes = null; + } + + return mergedUpdate; +} + +interface AppUpdatedModalContentProps { + onModalClose: () => void; +} + +function AppUpdatedModalContent(props: AppUpdatedModalContentProps) { + const dispatch = useDispatch(); + const { version, prevVersion } = useSelector((state: AppState) => state.app); + const { isPopulated, error, items } = useSelector( + (state: AppState) => state.system.updates + ); + const previousVersion = usePrevious(version); + + const { onModalClose } = props; + + const update = mergeUpdates(items, version, prevVersion); + + const handleSeeChangesPress = useCallback(() => { + window.location.href = `${window.Radarr.urlBase}/system/updates`; + }, []); + + useEffect(() => { + dispatch(fetchUpdates()); + }, [dispatch]); + + useEffect(() => { + if (version !== previousVersion) { + dispatch(fetchUpdates()); + } + }, [version, previousVersion, dispatch]); + + return ( + + {translate('AppUpdated')} + + +
+ +
+ + {isPopulated && !error && !!update ? ( +
+ {update.changes ? ( +
+ {translate('MaintenanceRelease')} +
+ ) : null} + + {update.changes ? ( +
+
{translate('WhatsNew')}
+ + + + +
+ ) : null} +
+ ) : null} + + {!isPopulated && !error ? : null} +
+ + + + + + +
+ ); +} + +export default AppUpdatedModalContent; diff --git a/frontend/src/App/AppUpdatedModalContentConnector.js b/frontend/src/App/AppUpdatedModalContentConnector.js deleted file mode 100644 index 6f81170b27..0000000000 --- a/frontend/src/App/AppUpdatedModalContentConnector.js +++ /dev/null @@ -1,78 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchUpdates } from 'Store/Actions/systemActions'; -import AppUpdatedModalContent from './AppUpdatedModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.app.version, - (state) => state.app.prevVersion, - (state) => state.system.updates, - (version, prevVersion, updates) => { - const { - isPopulated, - error, - items - } = updates; - - return { - version, - prevVersion, - isPopulated, - error, - items - }; - } - ); -} - -function createMapDispatchToProps(dispatch, props) { - return { - dispatchFetchUpdates() { - dispatch(fetchUpdates()); - }, - - onSeeChangesPress() { - window.location = `${window.Radarr.urlBase}/system/updates`; - } - }; -} - -class AppUpdatedModalContentConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.dispatchFetchUpdates(); - } - - componentDidUpdate(prevProps) { - if (prevProps.version !== this.props.version) { - this.props.dispatchFetchUpdates(); - } - } - - // - // Render - - render() { - const { - dispatchFetchUpdates, - ...otherProps - } = this.props; - - return ( - - ); - } -} - -AppUpdatedModalContentConnector.propTypes = { - version: PropTypes.string.isRequired, - dispatchFetchUpdates: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, createMapDispatchToProps)(AppUpdatedModalContentConnector); diff --git a/frontend/src/App/ColorImpairedContext.js b/frontend/src/App/ColorImpairedContext.ts similarity index 100% rename from frontend/src/App/ColorImpairedContext.js rename to frontend/src/App/ColorImpairedContext.ts diff --git a/frontend/src/App/ConnectionLostModal.js b/frontend/src/App/ConnectionLostModal.tsx similarity index 54% rename from frontend/src/App/ConnectionLostModal.js rename to frontend/src/App/ConnectionLostModal.tsx index 5c08f491f4..f08f2c0e20 100644 --- a/frontend/src/App/ConnectionLostModal.js +++ b/frontend/src/App/ConnectionLostModal.tsx @@ -1,5 +1,4 @@ -import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useCallback } from 'react'; import Button from 'Components/Link/Button'; import Modal from 'Components/Modal/Modal'; import ModalBody from 'Components/Modal/ModalBody'; @@ -10,36 +9,31 @@ import { kinds } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import styles from './ConnectionLostModal.css'; -function ConnectionLostModal(props) { - const { - isOpen, - onModalClose - } = props; +interface ConnectionLostModalProps { + isOpen: boolean; +} + +function ConnectionLostModal(props: ConnectionLostModalProps) { + const { isOpen } = props; + + const handleModalClose = useCallback(() => { + location.reload(); + }, []); return ( - - - - {translate('ConnectionLost')} - + + + {translate('ConnectionLost')} -
- {translate('ConnectionLostToBackend')} -
+
{translate('ConnectionLostToBackend')}
{translate('ConnectionLostReconnect')}
- @@ -48,9 +42,4 @@ function ConnectionLostModal(props) { ); } -ConnectionLostModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - export default ConnectionLostModal; diff --git a/frontend/src/App/ConnectionLostModalConnector.js b/frontend/src/App/ConnectionLostModalConnector.js deleted file mode 100644 index 8ab8e3cd07..0000000000 --- a/frontend/src/App/ConnectionLostModalConnector.js +++ /dev/null @@ -1,12 +0,0 @@ -import { connect } from 'react-redux'; -import ConnectionLostModal from './ConnectionLostModal'; - -function createMapDispatchToProps(dispatch, props) { - return { - onModalClose() { - location.reload(); - } - }; -} - -export default connect(undefined, createMapDispatchToProps)(ConnectionLostModal); diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index 6d60772e0f..a1011b6c17 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -50,6 +50,7 @@ export interface AppSectionState { isConnected: boolean; isReconnecting: boolean; version: string; + prevVersion?: string; dimensions: { isSmallScreen: boolean; width: number; diff --git a/frontend/src/Components/Page/Page.js b/frontend/src/Components/Page/Page.js index aa23f4d88f..c2e3688273 100644 --- a/frontend/src/Components/Page/Page.js +++ b/frontend/src/Components/Page/Page.js @@ -1,8 +1,8 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; -import AppUpdatedModalConnector from 'App/AppUpdatedModalConnector'; +import AppUpdatedModal from 'App/AppUpdatedModal'; import ColorImpairedContext from 'App/ColorImpairedContext'; -import ConnectionLostModalConnector from 'App/ConnectionLostModalConnector'; +import ConnectionLostModal from 'App/ConnectionLostModal'; import SignalRConnector from 'Components/SignalRConnector'; import AuthenticationRequiredModal from 'FirstRun/AuthenticationRequiredModal'; import locationShape from 'Helpers/Props/Shapes/locationShape'; @@ -102,12 +102,12 @@ class Page extends Component { {children}
- - diff --git a/package.json b/package.json index e2de8190b1..3003d67653 100644 --- a/package.json +++ b/package.json @@ -95,6 +95,7 @@ "@babel/preset-react": "7.25.7", "@babel/preset-typescript": "7.25.7", "@types/lodash": "4.14.195", + "@types/react-document-title": "2.0.10", "@types/react-lazyload": "3.2.3", "@types/react-router-dom": "5.3.3", "@types/react-text-truncate": "0.19.0", diff --git a/yarn.lock b/yarn.lock index 8e2abbbd8e..d99e3dc9a5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1323,6 +1323,13 @@ resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.13.tgz#2af91918ee12d9d32914feb13f5326658461b451" integrity sha512-hCZTSvwbzWGvhqxp/RqVqwU999pBf2vp7hzIjiYOsl8wqOmUxkQ6ddw1cV3l8811+kdUFus/q4d1Y3E3SyEifA== +"@types/react-document-title@2.0.10": + version "2.0.10" + resolved "https://registry.yarnpkg.com/@types/react-document-title/-/react-document-title-2.0.10.tgz#f9c4563744b735750d84519ba1bc7099e1b2d1d0" + integrity sha512-a5RYXFccVqVhc429yXUn9zjJvaQwdx3Kueb8v8pEymUyExHoatHv0iS8BlOE3YuS+csA2pHbL2Hatnp7QEtLxQ== + dependencies: + "@types/react" "*" + "@types/react-dom@18.2.25": version "18.2.25" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.25.tgz#2946a30081f53e7c8d585eb138277245caedc521" From d99a7e9b8aa9ce67dffa5bd4802b12b33c609ff6 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 28 Jul 2024 22:31:16 -0700 Subject: [PATCH 030/579] Convert Components to TypeScript (cherry picked from commit e1cbc4a78249881de96160739a50c0a399ea4313) Closes #10378 Fixed: Links tooltip closing too quickly (cherry picked from commit 0b9a212f33381d07ff67e2453753aaab64cc8041) Closes #10400 Fixed: Movie links not opening on iOS (cherry picked from commit f20ac9dc348e1f5ded635f12ab925d982b1b8957) Closes #10425 --- frontend/src/Activity/Queue/QueueStatus.tsx | 2 +- frontend/src/App/State/AppSectionState.ts | 2 +- frontend/src/App/State/AppState.ts | 2 + frontend/src/App/State/MoviesAppState.ts | 2 +- frontend/src/App/State/PathsAppState.ts | 29 ++ frontend/src/Components/Alert.js | 34 --- frontend/src/Components/Alert.tsx | 18 ++ frontend/src/Components/Card.js | 60 ----- frontend/src/Components/Card.tsx | 39 +++ .../DescriptionList/DescriptionList.js | 33 --- .../DescriptionList/DescriptionList.tsx | 15 ++ .../DescriptionList/DescriptionListItem.js | 46 ---- .../DescriptionList/DescriptionListItem.tsx | 34 +++ .../DescriptionListItemDescription.js | 27 -- .../DescriptionListItemDescription.tsx | 17 ++ .../DescriptionListItemTitle.js | 27 -- .../DescriptionListItemTitle.tsx | 15 ++ frontend/src/Components/DragPreviewLayer.js | 22 -- frontend/src/Components/DragPreviewLayer.tsx | 21 ++ .../src/Components/Error/ErrorBoundary.js | 62 ----- .../src/Components/Error/ErrorBoundary.tsx | 46 ++++ frontend/src/Components/FieldSet.js | 41 --- frontend/src/Components/FieldSet.tsx | 29 ++ .../FileBrowser/FileBrowserModal.js | 39 --- .../FileBrowser/FileBrowserModal.tsx | 23 ++ .../FileBrowser/FileBrowserModalContent.js | 250 ------------------ .../FileBrowser/FileBrowserModalContent.tsx | 237 +++++++++++++++++ .../FileBrowserModalContentConnector.js | 119 --------- .../Components/FileBrowser/FileBrowserRow.js | 62 ----- .../Components/FileBrowser/FileBrowserRow.tsx | 49 ++++ .../FileBrowser/createPathsSelector.ts | 36 +++ .../Components/Loading/LoadingIndicator.js | 51 ---- .../Components/Loading/LoadingIndicator.tsx | 36 +++ .../{LoadingMessage.js => LoadingMessage.tsx} | 22 +- .../src/Components/Markdown/InlineMarkdown.js | 74 ------ .../Components/Markdown/InlineMarkdown.tsx | 75 ++++++ .../src/Components/MonitorToggleButton.js | 79 ------ .../src/Components/MonitorToggleButton.tsx | 65 +++++ .../Components/{NotFound.js => NotFound.tsx} | 21 +- .../src/Components/Page/PageContentBody.tsx | 3 +- frontend/src/Components/Portal.js | 18 -- frontend/src/Components/Portal.tsx | 20 ++ frontend/src/Components/Router/Switch.js | 44 --- frontend/src/Components/Router/Switch.tsx | 38 +++ .../Components/Scroller/OverlayScroller.js | 179 ------------- .../Components/Scroller/OverlayScroller.tsx | 127 +++++++++ frontend/src/Components/Scroller/Scroller.tsx | 6 +- frontend/src/Components/SpinnerIcon.tsx | 4 +- frontend/src/Components/Tooltip/Popover.js | 43 --- frontend/src/Components/Tooltip/Popover.tsx | 26 ++ frontend/src/Components/Tooltip/Tooltip.js | 235 ---------------- frontend/src/Components/Tooltip/Tooltip.tsx | 226 ++++++++++++++++ frontend/src/Helpers/Props/ScrollDirection.ts | 8 - frontend/src/Helpers/Props/SortDirection.ts | 6 - frontend/src/Helpers/Props/TooltipPosition.ts | 3 - frontend/src/Helpers/Props/align.ts | 2 + ...crollDirections.js => scrollDirections.ts} | 2 + .../{sortDirections.js => sortDirections.ts} | 2 + ...ooltipPositions.js => tooltipPositions.ts} | 9 +- .../src/Movie/Details/MovieDetailsLinks.css | 7 + .../Movie/Index/Menus/MovieIndexSortMenu.tsx | 2 +- frontend/src/Movie/Index/MovieIndex.tsx | 4 +- .../Movie/Index/Posters/MovieIndexPosters.tsx | 2 +- .../src/Movie/Index/Table/MovieIndexTable.tsx | 8 +- .../Index/Table/MovieIndexTableHeader.tsx | 2 +- .../ManageCustomFormatsModalContent.tsx | 2 +- .../ManageDownloadClientsModalContent.tsx | 2 +- .../Manage/ManageIndexersModalContent.tsx | 2 +- frontend/src/typings/callbacks.ts | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 3 + 70 files changed, 1280 insertions(+), 1618 deletions(-) create mode 100644 frontend/src/App/State/PathsAppState.ts delete mode 100644 frontend/src/Components/Alert.js create mode 100644 frontend/src/Components/Alert.tsx delete mode 100644 frontend/src/Components/Card.js create mode 100644 frontend/src/Components/Card.tsx delete mode 100644 frontend/src/Components/DescriptionList/DescriptionList.js create mode 100644 frontend/src/Components/DescriptionList/DescriptionList.tsx delete mode 100644 frontend/src/Components/DescriptionList/DescriptionListItem.js create mode 100644 frontend/src/Components/DescriptionList/DescriptionListItem.tsx delete mode 100644 frontend/src/Components/DescriptionList/DescriptionListItemDescription.js create mode 100644 frontend/src/Components/DescriptionList/DescriptionListItemDescription.tsx delete mode 100644 frontend/src/Components/DescriptionList/DescriptionListItemTitle.js create mode 100644 frontend/src/Components/DescriptionList/DescriptionListItemTitle.tsx delete mode 100644 frontend/src/Components/DragPreviewLayer.js create mode 100644 frontend/src/Components/DragPreviewLayer.tsx delete mode 100644 frontend/src/Components/Error/ErrorBoundary.js create mode 100644 frontend/src/Components/Error/ErrorBoundary.tsx delete mode 100644 frontend/src/Components/FieldSet.js create mode 100644 frontend/src/Components/FieldSet.tsx delete mode 100644 frontend/src/Components/FileBrowser/FileBrowserModal.js create mode 100644 frontend/src/Components/FileBrowser/FileBrowserModal.tsx delete mode 100644 frontend/src/Components/FileBrowser/FileBrowserModalContent.js create mode 100644 frontend/src/Components/FileBrowser/FileBrowserModalContent.tsx delete mode 100644 frontend/src/Components/FileBrowser/FileBrowserModalContentConnector.js delete mode 100644 frontend/src/Components/FileBrowser/FileBrowserRow.js create mode 100644 frontend/src/Components/FileBrowser/FileBrowserRow.tsx create mode 100644 frontend/src/Components/FileBrowser/createPathsSelector.ts delete mode 100644 frontend/src/Components/Loading/LoadingIndicator.js create mode 100644 frontend/src/Components/Loading/LoadingIndicator.tsx rename frontend/src/Components/Loading/{LoadingMessage.js => LoadingMessage.tsx} (63%) delete mode 100644 frontend/src/Components/Markdown/InlineMarkdown.js create mode 100644 frontend/src/Components/Markdown/InlineMarkdown.tsx delete mode 100644 frontend/src/Components/MonitorToggleButton.js create mode 100644 frontend/src/Components/MonitorToggleButton.tsx rename frontend/src/Components/{NotFound.js => NotFound.tsx} (61%) delete mode 100644 frontend/src/Components/Portal.js create mode 100644 frontend/src/Components/Portal.tsx delete mode 100644 frontend/src/Components/Router/Switch.js create mode 100644 frontend/src/Components/Router/Switch.tsx delete mode 100644 frontend/src/Components/Scroller/OverlayScroller.js create mode 100644 frontend/src/Components/Scroller/OverlayScroller.tsx delete mode 100644 frontend/src/Components/Tooltip/Popover.js create mode 100644 frontend/src/Components/Tooltip/Popover.tsx delete mode 100644 frontend/src/Components/Tooltip/Tooltip.js create mode 100644 frontend/src/Components/Tooltip/Tooltip.tsx delete mode 100644 frontend/src/Helpers/Props/ScrollDirection.ts delete mode 100644 frontend/src/Helpers/Props/SortDirection.ts delete mode 100644 frontend/src/Helpers/Props/TooltipPosition.ts rename frontend/src/Helpers/Props/{scrollDirections.js => scrollDirections.ts} (71%) rename frontend/src/Helpers/Props/{sortDirections.js => sortDirections.ts} (68%) rename frontend/src/Helpers/Props/{tooltipPositions.js => tooltipPositions.ts} (50%) diff --git a/frontend/src/Activity/Queue/QueueStatus.tsx b/frontend/src/Activity/Queue/QueueStatus.tsx index 2bd7f6d796..31a28f35c2 100644 --- a/frontend/src/Activity/Queue/QueueStatus.tsx +++ b/frontend/src/Activity/Queue/QueueStatus.tsx @@ -2,7 +2,7 @@ import React from 'react'; import Icon, { IconProps } from 'Components/Icon'; import Popover from 'Components/Tooltip/Popover'; import { icons, kinds } from 'Helpers/Props'; -import TooltipPosition from 'Helpers/Props/TooltipPosition'; +import { TooltipPosition } from 'Helpers/Props/tooltipPositions'; import { QueueTrackedDownloadState, QueueTrackedDownloadStatus, diff --git a/frontend/src/App/State/AppSectionState.ts b/frontend/src/App/State/AppSectionState.ts index f89eb25f78..27dc78aa18 100644 --- a/frontend/src/App/State/AppSectionState.ts +++ b/frontend/src/App/State/AppSectionState.ts @@ -1,5 +1,5 @@ import Column from 'Components/Table/Column'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { SortDirection } from 'Helpers/Props/sortDirections'; import { FilterBuilderProp, PropertyFilter } from './AppState'; export interface Error { diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index a1011b6c17..f33fcc6920 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -8,6 +8,7 @@ import MovieCreditAppState from './MovieCreditAppState'; import MovieFilesAppState from './MovieFilesAppState'; import MoviesAppState, { MovieIndexAppState } from './MoviesAppState'; import ParseAppState from './ParseAppState'; +import PathsAppState from './PathsAppState'; import QueueAppState from './QueueAppState'; import RootFolderAppState from './RootFolderAppState'; import SettingsAppState from './SettingsAppState'; @@ -71,6 +72,7 @@ interface AppState { movieIndex: MovieIndexAppState; movies: MoviesAppState; parse: ParseAppState; + paths: PathsAppState; queue: QueueAppState; rootFolders: RootFolderAppState; settings: SettingsAppState; diff --git a/frontend/src/App/State/MoviesAppState.ts b/frontend/src/App/State/MoviesAppState.ts index 20b706c249..13df312217 100644 --- a/frontend/src/App/State/MoviesAppState.ts +++ b/frontend/src/App/State/MoviesAppState.ts @@ -3,7 +3,7 @@ import AppSectionState, { AppSectionSaveState, } from 'App/State/AppSectionState'; import Column from 'Components/Table/Column'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { SortDirection } from 'Helpers/Props/sortDirections'; import Movie from 'Movie/Movie'; import { Filter, FilterBuilderProp } from './AppState'; diff --git a/frontend/src/App/State/PathsAppState.ts b/frontend/src/App/State/PathsAppState.ts new file mode 100644 index 0000000000..068a48dc09 --- /dev/null +++ b/frontend/src/App/State/PathsAppState.ts @@ -0,0 +1,29 @@ +interface BasePath { + name: string; + path: string; + size: number; + lastModified: string; +} + +interface File extends BasePath { + type: 'file'; +} + +interface Folder extends BasePath { + type: 'folder'; +} + +export type PathType = 'file' | 'folder' | 'drive' | 'computer' | 'parent'; +export type Path = File | Folder; + +interface PathsAppState { + currentPath: string; + isFetching: boolean; + isPopulated: boolean; + error: Error; + directories: Folder[]; + files: File[]; + parent: string | null; +} + +export default PathsAppState; diff --git a/frontend/src/Components/Alert.js b/frontend/src/Components/Alert.js deleted file mode 100644 index 418cbf5e64..0000000000 --- a/frontend/src/Components/Alert.js +++ /dev/null @@ -1,34 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { kinds } from 'Helpers/Props'; -import styles from './Alert.css'; - -function Alert(props) { - const { className, kind, children, ...otherProps } = props; - - return ( -
- {children} -
- ); -} - -Alert.propTypes = { - className: PropTypes.string, - kind: PropTypes.oneOf(kinds.all), - children: PropTypes.node.isRequired -}; - -Alert.defaultProps = { - className: styles.alert, - kind: kinds.INFO -}; - -export default Alert; diff --git a/frontend/src/Components/Alert.tsx b/frontend/src/Components/Alert.tsx new file mode 100644 index 0000000000..92c89e7413 --- /dev/null +++ b/frontend/src/Components/Alert.tsx @@ -0,0 +1,18 @@ +import classNames from 'classnames'; +import React from 'react'; +import { Kind } from 'Helpers/Props/kinds'; +import styles from './Alert.css'; + +interface AlertProps { + className?: string; + kind?: Extract; + children: React.ReactNode; +} + +function Alert(props: AlertProps) { + const { className = styles.alert, kind = 'info', children } = props; + + return
{children}
; +} + +export default Alert; diff --git a/frontend/src/Components/Card.js b/frontend/src/Components/Card.js deleted file mode 100644 index c5a4d164c1..0000000000 --- a/frontend/src/Components/Card.js +++ /dev/null @@ -1,60 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Link from 'Components/Link/Link'; -import styles from './Card.css'; - -class Card extends Component { - - // - // Render - - render() { - const { - className, - overlayClassName, - overlayContent, - children, - onPress - } = this.props; - - if (overlayContent) { - return ( -
- - -
- {children} -
-
- ); - } - - return ( - - {children} - - ); - } -} - -Card.propTypes = { - className: PropTypes.string.isRequired, - overlayClassName: PropTypes.string.isRequired, - overlayContent: PropTypes.bool.isRequired, - children: PropTypes.node.isRequired, - onPress: PropTypes.func.isRequired -}; - -Card.defaultProps = { - className: styles.card, - overlayClassName: styles.overlay, - overlayContent: false -}; - -export default Card; diff --git a/frontend/src/Components/Card.tsx b/frontend/src/Components/Card.tsx new file mode 100644 index 0000000000..24588c841c --- /dev/null +++ b/frontend/src/Components/Card.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import Link, { LinkProps } from 'Components/Link/Link'; +import styles from './Card.css'; + +interface CardProps extends Pick { + // TODO: Consider using different properties for classname depending if it's overlaying content or not + className?: string; + overlayClassName?: string; + overlayContent?: boolean; + children: React.ReactNode; +} + +function Card(props: CardProps) { + const { + className = styles.card, + overlayClassName = styles.overlay, + overlayContent = false, + children, + onPress, + } = props; + + if (overlayContent) { + return ( +
+ + +
{children}
+
+ ); + } + + return ( + + {children} + + ); +} + +export default Card; diff --git a/frontend/src/Components/DescriptionList/DescriptionList.js b/frontend/src/Components/DescriptionList/DescriptionList.js deleted file mode 100644 index be2c87c550..0000000000 --- a/frontend/src/Components/DescriptionList/DescriptionList.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import styles from './DescriptionList.css'; - -class DescriptionList extends Component { - - // - // Render - - render() { - const { - className, - children - } = this.props; - - return ( -
- {children} -
- ); - } -} - -DescriptionList.propTypes = { - className: PropTypes.string.isRequired, - children: PropTypes.node -}; - -DescriptionList.defaultProps = { - className: styles.descriptionList -}; - -export default DescriptionList; diff --git a/frontend/src/Components/DescriptionList/DescriptionList.tsx b/frontend/src/Components/DescriptionList/DescriptionList.tsx new file mode 100644 index 0000000000..6deee77e5e --- /dev/null +++ b/frontend/src/Components/DescriptionList/DescriptionList.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import styles from './DescriptionList.css'; + +interface DescriptionListProps { + className?: string; + children?: React.ReactNode; +} + +function DescriptionList(props: DescriptionListProps) { + const { className = styles.descriptionList, children } = props; + + return
{children}
; +} + +export default DescriptionList; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItem.js b/frontend/src/Components/DescriptionList/DescriptionListItem.js deleted file mode 100644 index 9315570458..0000000000 --- a/frontend/src/Components/DescriptionList/DescriptionListItem.js +++ /dev/null @@ -1,46 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import DescriptionListItemDescription from './DescriptionListItemDescription'; -import DescriptionListItemTitle from './DescriptionListItemTitle'; - -class DescriptionListItem extends Component { - - // - // Render - - render() { - const { - className, - titleClassName, - descriptionClassName, - title, - data - } = this.props; - - return ( -
- - {title} - - - - {data} - -
- ); - } -} - -DescriptionListItem.propTypes = { - className: PropTypes.string, - titleClassName: PropTypes.string, - descriptionClassName: PropTypes.string, - title: PropTypes.string, - data: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.node]) -}; - -export default DescriptionListItem; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItem.tsx b/frontend/src/Components/DescriptionList/DescriptionListItem.tsx new file mode 100644 index 0000000000..13a7efdd03 --- /dev/null +++ b/frontend/src/Components/DescriptionList/DescriptionListItem.tsx @@ -0,0 +1,34 @@ +import React from 'react'; +import DescriptionListItemDescription, { + DescriptionListItemDescriptionProps, +} from './DescriptionListItemDescription'; +import DescriptionListItemTitle, { + DescriptionListItemTitleProps, +} from './DescriptionListItemTitle'; + +interface DescriptionListItemProps { + className?: string; + titleClassName?: DescriptionListItemTitleProps['className']; + descriptionClassName?: DescriptionListItemDescriptionProps['className']; + title?: DescriptionListItemTitleProps['children']; + data?: DescriptionListItemDescriptionProps['children']; +} + +function DescriptionListItem(props: DescriptionListItemProps) { + const { className, titleClassName, descriptionClassName, title, data } = + props; + + return ( +
+ + {title} + + + + {data} + +
+ ); +} + +export default DescriptionListItem; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItemDescription.js b/frontend/src/Components/DescriptionList/DescriptionListItemDescription.js deleted file mode 100644 index 4ef3c015e6..0000000000 --- a/frontend/src/Components/DescriptionList/DescriptionListItemDescription.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import styles from './DescriptionListItemDescription.css'; - -function DescriptionListItemDescription(props) { - const { - className, - children - } = props; - - return ( -
- {children} -
- ); -} - -DescriptionListItemDescription.propTypes = { - className: PropTypes.string.isRequired, - children: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.node]) -}; - -DescriptionListItemDescription.defaultProps = { - className: styles.description -}; - -export default DescriptionListItemDescription; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItemDescription.tsx b/frontend/src/Components/DescriptionList/DescriptionListItemDescription.tsx new file mode 100644 index 0000000000..e08c117dc8 --- /dev/null +++ b/frontend/src/Components/DescriptionList/DescriptionListItemDescription.tsx @@ -0,0 +1,17 @@ +import React, { ReactNode } from 'react'; +import styles from './DescriptionListItemDescription.css'; + +export interface DescriptionListItemDescriptionProps { + className?: string; + children?: ReactNode; +} + +function DescriptionListItemDescription( + props: DescriptionListItemDescriptionProps +) { + const { className = styles.description, children } = props; + + return
{children}
; +} + +export default DescriptionListItemDescription; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItemTitle.js b/frontend/src/Components/DescriptionList/DescriptionListItemTitle.js deleted file mode 100644 index e1632c1cfe..0000000000 --- a/frontend/src/Components/DescriptionList/DescriptionListItemTitle.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import styles from './DescriptionListItemTitle.css'; - -function DescriptionListItemTitle(props) { - const { - className, - children - } = props; - - return ( -
- {children} -
- ); -} - -DescriptionListItemTitle.propTypes = { - className: PropTypes.string.isRequired, - children: PropTypes.string -}; - -DescriptionListItemTitle.defaultProps = { - className: styles.title -}; - -export default DescriptionListItemTitle; diff --git a/frontend/src/Components/DescriptionList/DescriptionListItemTitle.tsx b/frontend/src/Components/DescriptionList/DescriptionListItemTitle.tsx new file mode 100644 index 0000000000..59ea6955c0 --- /dev/null +++ b/frontend/src/Components/DescriptionList/DescriptionListItemTitle.tsx @@ -0,0 +1,15 @@ +import React, { ReactNode } from 'react'; +import styles from './DescriptionListItemTitle.css'; + +export interface DescriptionListItemTitleProps { + className?: string; + children?: ReactNode; +} + +function DescriptionListItemTitle(props: DescriptionListItemTitleProps) { + const { className = styles.title, children } = props; + + return
{children}
; +} + +export default DescriptionListItemTitle; diff --git a/frontend/src/Components/DragPreviewLayer.js b/frontend/src/Components/DragPreviewLayer.js deleted file mode 100644 index a111df70e4..0000000000 --- a/frontend/src/Components/DragPreviewLayer.js +++ /dev/null @@ -1,22 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import styles from './DragPreviewLayer.css'; - -function DragPreviewLayer({ children, ...otherProps }) { - return ( -
- {children} -
- ); -} - -DragPreviewLayer.propTypes = { - children: PropTypes.node, - className: PropTypes.string -}; - -DragPreviewLayer.defaultProps = { - className: styles.dragLayer -}; - -export default DragPreviewLayer; diff --git a/frontend/src/Components/DragPreviewLayer.tsx b/frontend/src/Components/DragPreviewLayer.tsx new file mode 100644 index 0000000000..2e578504bc --- /dev/null +++ b/frontend/src/Components/DragPreviewLayer.tsx @@ -0,0 +1,21 @@ +import React from 'react'; +import styles from './DragPreviewLayer.css'; + +interface DragPreviewLayerProps { + className?: string; + children?: React.ReactNode; +} + +function DragPreviewLayer({ + className = styles.dragLayer, + children, + ...otherProps +}: DragPreviewLayerProps) { + return ( +
+ {children} +
+ ); +} + +export default DragPreviewLayer; diff --git a/frontend/src/Components/Error/ErrorBoundary.js b/frontend/src/Components/Error/ErrorBoundary.js deleted file mode 100644 index 88412ad19a..0000000000 --- a/frontend/src/Components/Error/ErrorBoundary.js +++ /dev/null @@ -1,62 +0,0 @@ -import * as sentry from '@sentry/browser'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; - -class ErrorBoundary extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - error: null, - info: null - }; - } - - componentDidCatch(error, info) { - this.setState({ - error, - info - }); - - sentry.captureException(error); - } - - // - // Render - - render() { - const { - children, - errorComponent: ErrorComponent, - ...otherProps - } = this.props; - - const { - error, - info - } = this.state; - - if (error) { - return ( - - ); - } - - return children; - } -} - -ErrorBoundary.propTypes = { - children: PropTypes.node.isRequired, - errorComponent: PropTypes.elementType.isRequired -}; - -export default ErrorBoundary; diff --git a/frontend/src/Components/Error/ErrorBoundary.tsx b/frontend/src/Components/Error/ErrorBoundary.tsx new file mode 100644 index 0000000000..6b27f7a093 --- /dev/null +++ b/frontend/src/Components/Error/ErrorBoundary.tsx @@ -0,0 +1,46 @@ +import * as sentry from '@sentry/browser'; +import React, { Component, ErrorInfo } from 'react'; + +interface ErrorBoundaryProps { + children: React.ReactNode; + errorComponent: React.ElementType; +} + +interface ErrorBoundaryState { + error: Error | null; + info: ErrorInfo | null; +} + +// Class component until componentDidCatch is supported in functional components +class ErrorBoundary extends Component { + constructor(props: ErrorBoundaryProps) { + super(props); + + this.state = { + error: null, + info: null, + }; + } + + componentDidCatch(error: Error, info: ErrorInfo) { + this.setState({ + error, + info, + }); + + sentry.captureException(error); + } + + render() { + const { children, errorComponent: ErrorComponent } = this.props; + const { error, info } = this.state; + + if (error) { + return ; + } + + return children; + } +} + +export default ErrorBoundary; diff --git a/frontend/src/Components/FieldSet.js b/frontend/src/Components/FieldSet.js deleted file mode 100644 index 8243fd00c9..0000000000 --- a/frontend/src/Components/FieldSet.js +++ /dev/null @@ -1,41 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { sizes } from 'Helpers/Props'; -import styles from './FieldSet.css'; - -class FieldSet extends Component { - - // - // Render - - render() { - const { - size, - legend, - children - } = this.props; - - return ( -
- - {legend} - - {children} -
- ); - } - -} - -FieldSet.propTypes = { - size: PropTypes.oneOf(sizes.all).isRequired, - legend: PropTypes.oneOfType([PropTypes.node, PropTypes.string]), - children: PropTypes.node -}; - -FieldSet.defaultProps = { - size: sizes.MEDIUM -}; - -export default FieldSet; diff --git a/frontend/src/Components/FieldSet.tsx b/frontend/src/Components/FieldSet.tsx new file mode 100644 index 0000000000..c2ff03a7f5 --- /dev/null +++ b/frontend/src/Components/FieldSet.tsx @@ -0,0 +1,29 @@ +import classNames from 'classnames'; +import React, { ComponentProps } from 'react'; +import { sizes } from 'Helpers/Props'; +import { Size } from 'Helpers/Props/sizes'; +import styles from './FieldSet.css'; + +interface FieldSetProps { + size?: Size; + legend?: ComponentProps<'legend'>['children']; + children?: React.ReactNode; +} + +function FieldSet({ size = sizes.MEDIUM, legend, children }: FieldSetProps) { + return ( +
+ + {legend} + + {children} +
+ ); +} + +export default FieldSet; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModal.js b/frontend/src/Components/FileBrowser/FileBrowserModal.js deleted file mode 100644 index 6b58dbb8c2..0000000000 --- a/frontend/src/Components/FileBrowser/FileBrowserModal.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Modal from 'Components/Modal/Modal'; -import FileBrowserModalContentConnector from './FileBrowserModalContentConnector'; -import styles from './FileBrowserModal.css'; - -class FileBrowserModal extends Component { - - // - // Render - - render() { - const { - isOpen, - onModalClose, - ...otherProps - } = this.props; - - return ( - - - - ); - } -} - -FileBrowserModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default FileBrowserModal; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModal.tsx b/frontend/src/Components/FileBrowser/FileBrowserModal.tsx new file mode 100644 index 0000000000..0925890de2 --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserModal.tsx @@ -0,0 +1,23 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import FileBrowserModalContent, { + FileBrowserModalContentProps, +} from './FileBrowserModalContent'; +import styles from './FileBrowserModal.css'; + +interface FileBrowserModalProps extends FileBrowserModalContentProps { + isOpen: boolean; + onModalClose: () => void; +} + +function FileBrowserModal(props: FileBrowserModalProps) { + const { isOpen, onModalClose, ...otherProps } = props; + + return ( + + + + ); +} + +export default FileBrowserModal; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModalContent.js b/frontend/src/Components/FileBrowser/FileBrowserModalContent.js deleted file mode 100644 index 4241bdf6dd..0000000000 --- a/frontend/src/Components/FileBrowser/FileBrowserModalContent.js +++ /dev/null @@ -1,250 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import PathInput from 'Components/Form/PathInput'; -import Button from 'Components/Link/Button'; -import Link from 'Components/Link/Link'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import Scroller from 'Components/Scroller/Scroller'; -import Table from 'Components/Table/Table'; -import TableBody from 'Components/Table/TableBody'; -import { kinds, scrollDirections } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import FileBrowserRow from './FileBrowserRow'; -import styles from './FileBrowserModalContent.css'; - -const columns = [ - { - name: 'type', - label: () => translate('Type'), - isVisible: true - }, - { - name: 'name', - label: () => translate('Name'), - isVisible: true - } -]; - -class FileBrowserModalContent extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this._scrollerRef = React.createRef(); - - this.state = { - isFileBrowserModalOpen: false, - currentPath: props.value - }; - } - - componentDidUpdate(prevProps, prevState) { - const { - currentPath - } = this.props; - - if ( - currentPath !== this.state.currentPath && - currentPath !== prevState.currentPath - ) { - this.setState({ currentPath }); - this._scrollerRef.current.scrollTop = 0; - } - } - - // - // Listeners - - onPathInputChange = ({ value }) => { - this.setState({ currentPath: value }); - }; - - onRowPress = (path) => { - this.props.onFetchPaths(path); - }; - - onOkPress = () => { - this.props.onChange({ - name: this.props.name, - value: this.state.currentPath - }); - - this.props.onClearPaths(); - this.props.onModalClose(); - }; - - // - // Render - - render() { - const { - isFetching, - isPopulated, - error, - parent, - directories, - files, - isWindowsService, - onModalClose, - ...otherProps - } = this.props; - - const emptyParent = parent === ''; - - return ( - - - File Browser - - - - { - isWindowsService && - - - {translate('MappedDrivesRunningAsService')} - . - - } - - - - - { - !!error && -
- {translate('ErrorLoadingContents')} -
- } - - { - isPopulated && !error && - - - { - emptyParent && - - } - - { - !emptyParent && parent && - - } - - { - directories.map((directory) => { - return ( - - ); - }) - } - - { - files.map((file) => { - return ( - - ); - }) - } - -
- } -
-
- - - { - isFetching && - - } - - - - - -
- ); - } -} - -FileBrowserModalContent.propTypes = { - name: PropTypes.string.isRequired, - value: PropTypes.string.isRequired, - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - parent: PropTypes.string, - currentPath: PropTypes.string.isRequired, - directories: PropTypes.arrayOf(PropTypes.object).isRequired, - files: PropTypes.arrayOf(PropTypes.object).isRequired, - isWindowsService: PropTypes.bool.isRequired, - onFetchPaths: PropTypes.func.isRequired, - onClearPaths: PropTypes.func.isRequired, - onChange: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default FileBrowserModalContent; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModalContent.tsx b/frontend/src/Components/FileBrowser/FileBrowserModalContent.tsx new file mode 100644 index 0000000000..03fd575fdf --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserModalContent.tsx @@ -0,0 +1,237 @@ +import React, { useCallback, useEffect, useRef, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import Alert from 'Components/Alert'; +import PathInput from 'Components/Form/PathInput'; +import Button from 'Components/Link/Button'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import Scroller from 'Components/Scroller/Scroller'; +import Column from 'Components/Table/Column'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { kinds, scrollDirections } from 'Helpers/Props'; +import { clearPaths, fetchPaths } from 'Store/Actions/pathActions'; +import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector'; +import { InputChanged } from 'typings/inputs'; +import translate from 'Utilities/String/translate'; +import createPathsSelector from './createPathsSelector'; +import FileBrowserRow from './FileBrowserRow'; +import styles from './FileBrowserModalContent.css'; + +const columns: Column[] = [ + { + name: 'type', + label: () => translate('Type'), + isVisible: true, + }, + { + name: 'name', + label: () => translate('Name'), + isVisible: true, + }, +]; + +const handleClearPaths = () => {}; + +export interface FileBrowserModalContentProps { + name: string; + value: string; + includeFiles?: boolean; + onChange: (args: InputChanged) => unknown; + onModalClose: () => void; +} + +function FileBrowserModalContent(props: FileBrowserModalContentProps) { + const { name, value, includeFiles = true, onChange, onModalClose } = props; + + const dispatch = useDispatch(); + + const { isWindows, mode } = useSelector(createSystemStatusSelector()); + const { isFetching, isPopulated, error, parent, directories, files, paths } = + useSelector(createPathsSelector()); + + const [currentPath, setCurrentPath] = useState(value); + const scrollerRef = useRef(null); + const previousValue = usePrevious(value); + + const emptyParent = parent === ''; + const isWindowsService = isWindows && mode === 'service'; + + const handlePathInputChange = useCallback( + ({ value }: InputChanged) => { + setCurrentPath(value); + }, + [] + ); + + const handleRowPress = useCallback( + (path: string) => { + setCurrentPath(path); + + dispatch( + fetchPaths({ + path, + allowFoldersWithoutTrailingSlashes: true, + includeFiles, + }) + ); + }, + [includeFiles, dispatch, setCurrentPath] + ); + + const handleOkPress = useCallback(() => { + onChange({ + name, + value: currentPath, + }); + + dispatch(clearPaths()); + onModalClose(); + }, [name, currentPath, dispatch, onChange, onModalClose]); + + const handleFetchPaths = useCallback( + (path: string) => { + dispatch( + fetchPaths({ + path, + allowFoldersWithoutTrailingSlashes: true, + includeFiles, + }) + ); + }, + [includeFiles, dispatch] + ); + + useEffect(() => { + if (value !== previousValue && value !== currentPath) { + setCurrentPath(value); + } + }, [value, previousValue, currentPath, setCurrentPath]); + + useEffect( + () => { + dispatch( + fetchPaths({ + path: currentPath, + allowFoldersWithoutTrailingSlashes: true, + includeFiles, + }) + ); + + return () => { + dispatch(clearPaths()); + }; + }, + // This should only run once when the component mounts, + // so we don't need to include the other dependencies. + // eslint-disable-next-line react-hooks/exhaustive-deps + [dispatch] + ); + + return ( + + {translate('FileBrowser')} + + + {isWindowsService ? ( + + + + ) : null} + + + + + {error ?
{translate('ErrorLoadingContents')}
: null} + + {isPopulated && !error ? ( + + + {emptyParent ? ( + + ) : null} + + {!emptyParent && parent ? ( + + ) : null} + + {directories.map((directory) => { + return ( + + ); + })} + + {files.map((file) => { + return ( + + ); + })} + +
+ ) : null} +
+
+ + + {isFetching ? ( + + ) : null} + + + + + +
+ ); +} + +export default FileBrowserModalContent; diff --git a/frontend/src/Components/FileBrowser/FileBrowserModalContentConnector.js b/frontend/src/Components/FileBrowser/FileBrowserModalContentConnector.js deleted file mode 100644 index 1a3a41ef0a..0000000000 --- a/frontend/src/Components/FileBrowser/FileBrowserModalContentConnector.js +++ /dev/null @@ -1,119 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { clearPaths, fetchPaths } from 'Store/Actions/pathActions'; -import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector'; -import FileBrowserModalContent from './FileBrowserModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.paths, - createSystemStatusSelector(), - (paths, systemStatus) => { - const { - isFetching, - isPopulated, - error, - parent, - currentPath, - directories, - files - } = paths; - - const filteredPaths = _.filter([...directories, ...files], ({ path }) => { - return path.toLowerCase().startsWith(currentPath.toLowerCase()); - }); - - return { - isFetching, - isPopulated, - error, - parent, - currentPath, - directories, - files, - paths: filteredPaths, - isWindowsService: systemStatus.isWindows && systemStatus.mode === 'service' - }; - } - ); -} - -const mapDispatchToProps = { - dispatchFetchPaths: fetchPaths, - dispatchClearPaths: clearPaths -}; - -class FileBrowserModalContentConnector extends Component { - - // Lifecycle - - componentDidMount() { - const { - value, - includeFiles, - dispatchFetchPaths - } = this.props; - - dispatchFetchPaths({ - path: value, - allowFoldersWithoutTrailingSlashes: true, - includeFiles - }); - } - - // - // Listeners - - onFetchPaths = (path) => { - const { - includeFiles, - dispatchFetchPaths - } = this.props; - - dispatchFetchPaths({ - path, - allowFoldersWithoutTrailingSlashes: true, - includeFiles - }); - }; - - onClearPaths = () => { - // this.props.dispatchClearPaths(); - }; - - onModalClose = () => { - this.props.dispatchClearPaths(); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -FileBrowserModalContentConnector.propTypes = { - value: PropTypes.string, - includeFiles: PropTypes.bool.isRequired, - dispatchFetchPaths: PropTypes.func.isRequired, - dispatchClearPaths: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -FileBrowserModalContentConnector.defaultProps = { - includeFiles: false -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(FileBrowserModalContentConnector); diff --git a/frontend/src/Components/FileBrowser/FileBrowserRow.js b/frontend/src/Components/FileBrowser/FileBrowserRow.js deleted file mode 100644 index 06bb3029dd..0000000000 --- a/frontend/src/Components/FileBrowser/FileBrowserRow.js +++ /dev/null @@ -1,62 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Icon from 'Components/Icon'; -import TableRowCell from 'Components/Table/Cells/TableRowCell'; -import TableRowButton from 'Components/Table/TableRowButton'; -import { icons } from 'Helpers/Props'; -import styles from './FileBrowserRow.css'; - -function getIconName(type) { - switch (type) { - case 'computer': - return icons.COMPUTER; - case 'drive': - return icons.DRIVE; - case 'file': - return icons.FILE; - case 'parent': - return icons.PARENT; - default: - return icons.FOLDER; - } -} - -class FileBrowserRow extends Component { - - // - // Listeners - - onPress = () => { - this.props.onPress(this.props.path); - }; - - // - // Render - - render() { - const { - type, - name - } = this.props; - - return ( - - - - - - {name} - - ); - } - -} - -FileBrowserRow.propTypes = { - type: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - path: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired -}; - -export default FileBrowserRow; diff --git a/frontend/src/Components/FileBrowser/FileBrowserRow.tsx b/frontend/src/Components/FileBrowser/FileBrowserRow.tsx new file mode 100644 index 0000000000..fe47f1664f --- /dev/null +++ b/frontend/src/Components/FileBrowser/FileBrowserRow.tsx @@ -0,0 +1,49 @@ +import React, { useCallback } from 'react'; +import { PathType } from 'App/State/PathsAppState'; +import Icon from 'Components/Icon'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import TableRowButton from 'Components/Table/TableRowButton'; +import { icons } from 'Helpers/Props'; +import styles from './FileBrowserRow.css'; + +function getIconName(type: PathType) { + switch (type) { + case 'computer': + return icons.COMPUTER; + case 'drive': + return icons.DRIVE; + case 'file': + return icons.FILE; + case 'parent': + return icons.PARENT; + default: + return icons.FOLDER; + } +} + +interface FileBrowserRowProps { + type: PathType; + name: string; + path: string; + onPress: (path: string) => void; +} + +function FileBrowserRow(props: FileBrowserRowProps) { + const { type, name, path, onPress } = props; + + const handlePress = useCallback(() => { + onPress(path); + }, [path, onPress]); + + return ( + + + + + + {name} + + ); +} + +export default FileBrowserRow; diff --git a/frontend/src/Components/FileBrowser/createPathsSelector.ts b/frontend/src/Components/FileBrowser/createPathsSelector.ts new file mode 100644 index 0000000000..5da830bd5e --- /dev/null +++ b/frontend/src/Components/FileBrowser/createPathsSelector.ts @@ -0,0 +1,36 @@ +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; + +function createPathsSelector() { + return createSelector( + (state: AppState) => state.paths, + (paths) => { + const { + isFetching, + isPopulated, + error, + parent, + currentPath, + directories, + files, + } = paths; + + const filteredPaths = [...directories, ...files].filter(({ path }) => { + return path.toLowerCase().startsWith(currentPath.toLowerCase()); + }); + + return { + isFetching, + isPopulated, + error, + parent, + currentPath, + directories, + files, + paths: filteredPaths, + }; + } + ); +} + +export default createPathsSelector; diff --git a/frontend/src/Components/Loading/LoadingIndicator.js b/frontend/src/Components/Loading/LoadingIndicator.js deleted file mode 100644 index ffed05b1b0..0000000000 --- a/frontend/src/Components/Loading/LoadingIndicator.js +++ /dev/null @@ -1,51 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import styles from './LoadingIndicator.css'; - -function LoadingIndicator({ className, rippleClassName, size }) { - const sizeInPx = `${size}px`; - const width = sizeInPx; - const height = sizeInPx; - - return ( -
-
-
- -
- -
-
-
- ); -} - -LoadingIndicator.propTypes = { - className: PropTypes.string, - rippleClassName: PropTypes.string, - size: PropTypes.number -}; - -LoadingIndicator.defaultProps = { - className: styles.loading, - rippleClassName: styles.ripple, - size: 50 -}; - -export default LoadingIndicator; diff --git a/frontend/src/Components/Loading/LoadingIndicator.tsx b/frontend/src/Components/Loading/LoadingIndicator.tsx new file mode 100644 index 0000000000..06b5ecf3c5 --- /dev/null +++ b/frontend/src/Components/Loading/LoadingIndicator.tsx @@ -0,0 +1,36 @@ +import classNames from 'classnames'; +import React from 'react'; +import styles from './LoadingIndicator.css'; + +interface LoadingIndicatorProps { + className?: string; + rippleClassName?: string; + size?: number; +} + +function LoadingIndicator({ + className = styles.loading, + rippleClassName = styles.ripple, + size = 50, +}: LoadingIndicatorProps) { + const sizeInPx = `${size}px`; + const width = sizeInPx; + const height = sizeInPx; + + return ( +
+
+
+ +
+ +
+
+
+ ); +} + +export default LoadingIndicator; diff --git a/frontend/src/Components/Loading/LoadingMessage.js b/frontend/src/Components/Loading/LoadingMessage.tsx similarity index 63% rename from frontend/src/Components/Loading/LoadingMessage.js rename to frontend/src/Components/Loading/LoadingMessage.tsx index 5ab83c35f0..3bc256a6e5 100644 --- a/frontend/src/Components/Loading/LoadingMessage.js +++ b/frontend/src/Components/Loading/LoadingMessage.tsx @@ -8,21 +8,21 @@ const messages = [ 'Bleep Bloop.', 'Locating the required gigapixels to render...', 'Spinning up the hamster wheel...', - 'At least you\'re not on hold', + "At least you're not on hold", 'Hum something loud while others stare', 'Loading humorous message... Please Wait', - 'I could\'ve been faster in Python', - 'Don\'t forget to rewind your movies', + "I could've been faster in Python", + "Don't forget to rewind your movies", 'Congratulations! You are the 1000th visitor.', - 'HELP! I\'m being held hostage and forced to write these stupid lines!', + "HELP! I'm being held hostage and forced to write these stupid lines!", 'RE-calibrating the internet...', - 'I\'ll be here all week', - 'Don\'t forget to tip your waitress', + "I'll be here all week", + "Don't forget to tip your waitress", 'Apply directly to the forehead', - 'Loading Battlestation' + 'Loading Battlestation', ]; -let message = null; +let message: string | null = null; function LoadingMessage() { if (!message) { @@ -30,11 +30,7 @@ function LoadingMessage() { message = messages[index]; } - return ( -
- {message} -
- ); + return
{message}
; } export default LoadingMessage; diff --git a/frontend/src/Components/Markdown/InlineMarkdown.js b/frontend/src/Components/Markdown/InlineMarkdown.js deleted file mode 100644 index 993bb241e8..0000000000 --- a/frontend/src/Components/Markdown/InlineMarkdown.js +++ /dev/null @@ -1,74 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Link from 'Components/Link/Link'; - -class InlineMarkdown extends Component { - - // - // Render - - render() { - const { - className, - data, - blockClassName - } = this.props; - - // For now only replace links or code blocks (not both) - const markdownBlocks = []; - if (data) { - const linkRegex = RegExp(/\[(.+?)\]\((.+?)\)/g); - - let endIndex = 0; - let match = null; - - while ((match = linkRegex.exec(data)) !== null) { - if (match.index > endIndex) { - markdownBlocks.push(data.substr(endIndex, match.index - endIndex)); - } - - markdownBlocks.push({match[1]}); - endIndex = match.index + match[0].length; - } - - if (endIndex !== data.length && markdownBlocks.length > 0) { - markdownBlocks.push(data.substr(endIndex, data.length - endIndex)); - } - - const codeRegex = RegExp(/(?=`)`(?!`)[^`]*(?=`)`(?!`)/g); - - endIndex = 0; - match = null; - let matchedCode = false; - - while ((match = codeRegex.exec(data)) !== null) { - matchedCode = true; - - if (match.index > endIndex) { - markdownBlocks.push(data.substr(endIndex, match.index - endIndex)); - } - - markdownBlocks.push({match[0].substring(1, match[0].length - 1)}); - endIndex = match.index + match[0].length; - } - - if (endIndex !== data.length && markdownBlocks.length > 0 && matchedCode) { - markdownBlocks.push(data.substr(endIndex, data.length - endIndex)); - } - - if (markdownBlocks.length === 0) { - markdownBlocks.push(data); - } - } - - return {markdownBlocks}; - } -} - -InlineMarkdown.propTypes = { - className: PropTypes.string, - data: PropTypes.string, - blockClassName: PropTypes.string -}; - -export default InlineMarkdown; diff --git a/frontend/src/Components/Markdown/InlineMarkdown.tsx b/frontend/src/Components/Markdown/InlineMarkdown.tsx new file mode 100644 index 0000000000..80e99336a1 --- /dev/null +++ b/frontend/src/Components/Markdown/InlineMarkdown.tsx @@ -0,0 +1,75 @@ +import React, { ReactElement } from 'react'; +import Link from 'Components/Link/Link'; + +interface InlineMarkdownProps { + className?: string; + data?: string; + blockClassName?: string; +} + +function InlineMarkdown(props: InlineMarkdownProps) { + const { className, data, blockClassName } = props; + + // For now only replace links or code blocks (not both) + const markdownBlocks: (ReactElement | string)[] = []; + + if (data) { + const linkRegex = RegExp(/\[(.+?)\]\((.+?)\)/g); + + let endIndex = 0; + let match = null; + + while ((match = linkRegex.exec(data)) !== null) { + if (match.index > endIndex) { + markdownBlocks.push(data.substr(endIndex, match.index - endIndex)); + } + + markdownBlocks.push( + + {match[1]} + + ); + endIndex = match.index + match[0].length; + } + + if (endIndex !== data.length && markdownBlocks.length > 0) { + markdownBlocks.push(data.substr(endIndex, data.length - endIndex)); + } + + const codeRegex = RegExp(/(?=`)`(?!`)[^`]*(?=`)`(?!`)/g); + + endIndex = 0; + match = null; + let matchedCode = false; + + while ((match = codeRegex.exec(data)) !== null) { + matchedCode = true; + + if (match.index > endIndex) { + markdownBlocks.push(data.substr(endIndex, match.index - endIndex)); + } + + markdownBlocks.push( + + {match[0].substring(1, match[0].length - 1)} + + ); + endIndex = match.index + match[0].length; + } + + if (endIndex !== data.length && markdownBlocks.length > 0 && matchedCode) { + markdownBlocks.push(data.substr(endIndex, data.length - endIndex)); + } + + if (markdownBlocks.length === 0) { + markdownBlocks.push(data); + } + } + + return {markdownBlocks}; +} + +export default InlineMarkdown; diff --git a/frontend/src/Components/MonitorToggleButton.js b/frontend/src/Components/MonitorToggleButton.js deleted file mode 100644 index 442010df86..0000000000 --- a/frontend/src/Components/MonitorToggleButton.js +++ /dev/null @@ -1,79 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; -import { icons } from 'Helpers/Props'; -import styles from './MonitorToggleButton.css'; - -function getTooltip(monitored, isDisabled) { - if (isDisabled) { - return 'Cannot toggle monitored state when movie is unmonitored'; - } - - if (monitored) { - return 'Monitored, click to unmonitor'; - } - - return 'Unmonitored, click to monitor'; -} - -class MonitorToggleButton extends Component { - - // - // Listeners - - onPress = (event) => { - const shiftKey = event.nativeEvent.shiftKey; - - this.props.onPress(!this.props.monitored, { shiftKey }); - }; - - // - // Render - - render() { - const { - className, - monitored, - isDisabled, - isSaving, - size, - ...otherProps - } = this.props; - - const iconName = monitored ? icons.MONITORED : icons.UNMONITORED; - - return ( - - ); - } -} - -MonitorToggleButton.propTypes = { - className: PropTypes.string.isRequired, - monitored: PropTypes.bool.isRequired, - size: PropTypes.number, - isDisabled: PropTypes.bool.isRequired, - isSaving: PropTypes.bool.isRequired, - onPress: PropTypes.func.isRequired -}; - -MonitorToggleButton.defaultProps = { - className: styles.toggleButton, - isDisabled: false, - isSaving: false -}; - -export default MonitorToggleButton; diff --git a/frontend/src/Components/MonitorToggleButton.tsx b/frontend/src/Components/MonitorToggleButton.tsx new file mode 100644 index 0000000000..721bd87e19 --- /dev/null +++ b/frontend/src/Components/MonitorToggleButton.tsx @@ -0,0 +1,65 @@ +import classNames from 'classnames'; +import React, { SyntheticEvent, useCallback, useMemo } from 'react'; +import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; +import { icons } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; +import styles from './MonitorToggleButton.css'; + +interface MonitorToggleButtonProps { + className?: string; + monitored: boolean; + size?: number; + isDisabled?: boolean; + isSaving?: boolean; + onPress: (value: boolean, options: { shiftKey: boolean }) => unknown; +} + +function MonitorToggleButton(props: MonitorToggleButtonProps) { + const { + className = styles.toggleButton, + monitored, + isDisabled = false, + isSaving = false, + size, + onPress, + ...otherProps + } = props; + + const iconName = monitored ? icons.MONITORED : icons.UNMONITORED; + + const title = useMemo(() => { + if (isDisabled) { + return 'Cannot toggle monitored state when movie is unmonitored'; + } + + if (monitored) { + return translate('ToggleMonitoredToUnmonitored'); + } + + return translate('ToggleUnmonitoredToMonitored'); + }, [monitored, isDisabled]); + + const handlePress = useCallback( + (event: SyntheticEvent) => { + const shiftKey = event.nativeEvent.shiftKey; + + onPress(!monitored, { shiftKey }); + }, + [monitored, onPress] + ); + + return ( + + ); +} + +export default MonitorToggleButton; diff --git a/frontend/src/Components/NotFound.js b/frontend/src/Components/NotFound.tsx similarity index 61% rename from frontend/src/Components/NotFound.js rename to frontend/src/Components/NotFound.tsx index cd424ce099..991fc91bb2 100644 --- a/frontend/src/Components/NotFound.js +++ b/frontend/src/Components/NotFound.tsx @@ -1,16 +1,19 @@ -import PropTypes from 'prop-types'; import React from 'react'; import PageContent from 'Components/Page/PageContent'; import translate from 'Utilities/String/translate'; import styles from './NotFound.css'; -function NotFound({ message }) { +interface NotFoundProps { + message?: string; +} + +function NotFound(props: NotFoundProps) { + const { message = translate('DefaultNotFoundMessage') } = props; + return (
-
- {message} -
+
{message}
{children}
diff --git a/frontend/src/Components/Portal.js b/frontend/src/Components/Portal.js deleted file mode 100644 index 2e5237093a..0000000000 --- a/frontend/src/Components/Portal.js +++ /dev/null @@ -1,18 +0,0 @@ -import PropTypes from 'prop-types'; -import ReactDOM from 'react-dom'; - -function Portal(props) { - const { children, target } = props; - return ReactDOM.createPortal(children, target); -} - -Portal.propTypes = { - children: PropTypes.node.isRequired, - target: PropTypes.object.isRequired -}; - -Portal.defaultProps = { - target: document.getElementById('portal-root') -}; - -export default Portal; diff --git a/frontend/src/Components/Portal.tsx b/frontend/src/Components/Portal.tsx new file mode 100644 index 0000000000..1cc1c7da6f --- /dev/null +++ b/frontend/src/Components/Portal.tsx @@ -0,0 +1,20 @@ +import ReactDOM from 'react-dom'; + +interface PortalProps { + children: Parameters[0]; + target?: Parameters[1]; +} + +const defaultTarget = document.getElementById('portal-root'); + +function Portal(props: PortalProps) { + const { children, target = defaultTarget } = props; + + if (!target) { + return null; + } + + return ReactDOM.createPortal(children, target); +} + +export default Portal; diff --git a/frontend/src/Components/Router/Switch.js b/frontend/src/Components/Router/Switch.js deleted file mode 100644 index 6479d52918..0000000000 --- a/frontend/src/Components/Router/Switch.js +++ /dev/null @@ -1,44 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { Switch as RouterSwitch } from 'react-router-dom'; -import { map } from 'Helpers/elementChildren'; -import getPathWithUrlBase from 'Utilities/getPathWithUrlBase'; - -class Switch extends Component { - - // - // Render - - render() { - const { - children - } = this.props; - - return ( - - { - map(children, (child) => { - const { - path: childPath, - addUrlBase = true - } = child.props; - - if (!childPath) { - return child; - } - - const path = addUrlBase ? getPathWithUrlBase(childPath) : childPath; - - return React.cloneElement(child, { path }); - }) - } - - ); - } -} - -Switch.propTypes = { - children: PropTypes.node.isRequired -}; - -export default Switch; diff --git a/frontend/src/Components/Router/Switch.tsx b/frontend/src/Components/Router/Switch.tsx new file mode 100644 index 0000000000..0324716816 --- /dev/null +++ b/frontend/src/Components/Router/Switch.tsx @@ -0,0 +1,38 @@ +import React, { Children, ReactElement, ReactNode } from 'react'; +import { Switch as RouterSwitch } from 'react-router-dom'; +import getPathWithUrlBase from 'Utilities/getPathWithUrlBase'; + +interface ExtendedRoute { + path: string; + addUrlBase?: boolean; +} + +interface SwitchProps { + children: ReactNode; +} + +function Switch({ children }: SwitchProps) { + return ( + + {Children.map(children, (child) => { + if (!React.isValidElement(child)) { + return child; + } + + const elementChild: ReactElement = child; + + const { path: childPath, addUrlBase = true } = elementChild.props; + + if (!childPath) { + return child; + } + + const path = addUrlBase ? getPathWithUrlBase(childPath) : childPath; + + return React.cloneElement(child, { path }); + })} + + ); +} + +export default Switch; diff --git a/frontend/src/Components/Scroller/OverlayScroller.js b/frontend/src/Components/Scroller/OverlayScroller.js deleted file mode 100644 index e590c42b25..0000000000 --- a/frontend/src/Components/Scroller/OverlayScroller.js +++ /dev/null @@ -1,179 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { Scrollbars } from 'react-custom-scrollbars-2'; -import { scrollDirections } from 'Helpers/Props'; -import styles from './OverlayScroller.css'; - -const SCROLLBAR_SIZE = 10; - -class OverlayScroller extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this._scroller = null; - this._isScrolling = false; - } - - componentDidUpdate(prevProps) { - const { - scrollTop - } = this.props; - - if ( - !this._isScrolling && - scrollTop != null && - scrollTop !== prevProps.scrollTop - ) { - this._scroller.scrollTop(scrollTop); - } - } - - // - // Control - - _setScrollRef = (ref) => { - this._scroller = ref; - - if (ref) { - this.props.registerScroller(ref.view); - } - }; - - _renderThumb = (props) => { - return ( -
- ); - }; - - _renderTrackHorizontal = ({ style, props }) => { - const finalStyle = { - ...style, - right: 2, - bottom: 2, - left: 2, - borderRadius: 3, - height: SCROLLBAR_SIZE - }; - - return ( -
- ); - }; - - _renderTrackVertical = ({ style, props }) => { - const finalStyle = { - ...style, - right: 2, - bottom: 2, - top: 2, - borderRadius: 3, - width: SCROLLBAR_SIZE - }; - - return ( -
- ); - }; - - _renderView = (props) => { - return ( -
- ); - }; - - // - // Listers - - onScrollStart = () => { - this._isScrolling = true; - }; - - onScrollStop = () => { - this._isScrolling = false; - }; - - onScroll = (event) => { - const { - scrollTop, - scrollLeft - } = event.currentTarget; - - this._isScrolling = true; - const onScroll = this.props.onScroll; - - if (onScroll) { - onScroll({ scrollTop, scrollLeft }); - } - }; - - // - // Render - - render() { - const { - autoHide, - autoScroll, - children - } = this.props; - - return ( - - {children} - - ); - } - -} - -OverlayScroller.propTypes = { - className: PropTypes.string, - trackClassName: PropTypes.string, - scrollTop: PropTypes.number, - scrollDirection: PropTypes.oneOf([scrollDirections.NONE, scrollDirections.HORIZONTAL, scrollDirections.VERTICAL]).isRequired, - autoHide: PropTypes.bool.isRequired, - autoScroll: PropTypes.bool.isRequired, - children: PropTypes.node, - onScroll: PropTypes.func, - registerScroller: PropTypes.func -}; - -OverlayScroller.defaultProps = { - className: styles.scroller, - trackClassName: styles.thumb, - scrollDirection: scrollDirections.VERTICAL, - autoHide: false, - autoScroll: true, - registerScroller: () => { /* no-op */ } -}; - -export default OverlayScroller; diff --git a/frontend/src/Components/Scroller/OverlayScroller.tsx b/frontend/src/Components/Scroller/OverlayScroller.tsx new file mode 100644 index 0000000000..b242642e87 --- /dev/null +++ b/frontend/src/Components/Scroller/OverlayScroller.tsx @@ -0,0 +1,127 @@ +import React, { ComponentPropsWithoutRef, useCallback, useRef } from 'react'; +import { Scrollbars } from 'react-custom-scrollbars-2'; +import { ScrollDirection } from 'Helpers/Props/scrollDirections'; +import { OnScroll } from './Scroller'; +import styles from './OverlayScroller.css'; + +const SCROLLBAR_SIZE = 10; + +interface OverlayScrollerProps { + className?: string; + trackClassName?: string; + scrollTop?: number; + scrollDirection: ScrollDirection; + autoHide: boolean; + autoScroll: boolean; + children?: React.ReactNode; + onScroll?: (payload: OnScroll) => void; +} + +interface ScrollbarTrackProps { + style: React.CSSProperties; + props: ComponentPropsWithoutRef<'div'>; +} + +function OverlayScroller(props: OverlayScrollerProps) { + const { + autoHide = false, + autoScroll = true, + className = styles.scroller, + trackClassName = styles.thumb, + children, + onScroll, + } = props; + const scrollBarRef = useRef(null); + const isScrolling = useRef(false); + + const handleScrollStart = useCallback(() => { + isScrolling.current = true; + }, []); + const handleScrollStop = useCallback(() => { + isScrolling.current = false; + }, []); + + const handleScroll = useCallback(() => { + if (!scrollBarRef.current) { + return; + } + + const { scrollTop, scrollLeft } = scrollBarRef.current.getValues(); + isScrolling.current = true; + + if (onScroll) { + onScroll({ scrollTop, scrollLeft }); + } + }, [onScroll]); + + const renderThumb = useCallback( + (props: ComponentPropsWithoutRef<'div'>) => { + return
; + }, + [trackClassName] + ); + + const renderTrackHorizontal = useCallback( + ({ style, props: trackProps }: ScrollbarTrackProps) => { + const finalStyle = { + ...style, + right: 2, + bottom: 2, + left: 2, + borderRadius: 3, + height: SCROLLBAR_SIZE, + }; + + return ( +
+ ); + }, + [] + ); + + const renderTrackVertical = useCallback( + ({ style, props: trackProps }: ScrollbarTrackProps) => { + const finalStyle = { + ...style, + right: 2, + bottom: 2, + top: 2, + borderRadius: 3, + width: SCROLLBAR_SIZE, + }; + + return ( +
+ ); + }, + [] + ); + + const renderView = useCallback( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (props: any) => { + return
; + }, + [className] + ); + + return ( + + {children} + + ); +} + +export default OverlayScroller; diff --git a/frontend/src/Components/Scroller/Scroller.tsx b/frontend/src/Components/Scroller/Scroller.tsx index 37b16eebdd..95f85c119b 100644 --- a/frontend/src/Components/Scroller/Scroller.tsx +++ b/frontend/src/Components/Scroller/Scroller.tsx @@ -8,7 +8,7 @@ import React, { useEffect, useRef, } from 'react'; -import ScrollDirection from 'Helpers/Props/ScrollDirection'; +import { ScrollDirection } from 'Helpers/Props/scrollDirections'; import styles from './Scroller.css'; export interface OnScroll { @@ -33,7 +33,7 @@ const Scroller = forwardRef( className, autoFocus = false, autoScroll = true, - scrollDirection = ScrollDirection.Vertical, + scrollDirection = 'vertical', children, scrollTop, initialScrollTop, @@ -59,7 +59,7 @@ const Scroller = forwardRef( currentRef.current.scrollTop = scrollTop; } - if (autoFocus && scrollDirection !== ScrollDirection.None) { + if (autoFocus && scrollDirection !== 'none') { currentRef.current.focus({ preventScroll: true }); } }, [autoFocus, currentRef, scrollDirection, scrollTop]); diff --git a/frontend/src/Components/SpinnerIcon.tsx b/frontend/src/Components/SpinnerIcon.tsx index 27ddadc416..d9124d692b 100644 --- a/frontend/src/Components/SpinnerIcon.tsx +++ b/frontend/src/Components/SpinnerIcon.tsx @@ -10,11 +10,13 @@ export interface SpinnerIconProps extends IconProps { export default function SpinnerIcon({ name, spinningName = icons.SPINNER, + isSpinning, ...otherProps }: SpinnerIconProps) { return ( ); diff --git a/frontend/src/Components/Tooltip/Popover.js b/frontend/src/Components/Tooltip/Popover.js deleted file mode 100644 index 1fe92fcbf6..0000000000 --- a/frontend/src/Components/Tooltip/Popover.js +++ /dev/null @@ -1,43 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import { tooltipPositions } from 'Helpers/Props'; -import Tooltip from './Tooltip'; -import styles from './Popover.css'; - -function Popover(props) { - const { - title, - body, - ...otherProps - } = props; - - return ( - -
- {title} -
- -
- {body} -
-
- } - /> - ); -} - -Popover.propTypes = { - className: PropTypes.string, - bodyClassName: PropTypes.string, - anchor: PropTypes.node.isRequired, - title: PropTypes.string.isRequired, - body: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, - position: PropTypes.oneOf(tooltipPositions.all), - canFlip: PropTypes.bool -}; - -export default Popover; diff --git a/frontend/src/Components/Tooltip/Popover.tsx b/frontend/src/Components/Tooltip/Popover.tsx new file mode 100644 index 0000000000..4c6781343f --- /dev/null +++ b/frontend/src/Components/Tooltip/Popover.tsx @@ -0,0 +1,26 @@ +import React from 'react'; +import Tooltip, { TooltipProps } from './Tooltip'; +import styles from './Popover.css'; + +interface PopoverProps extends Omit { + title: string; + body: React.ReactNode; +} + +function Popover({ title, body, ...otherProps }: PopoverProps) { + return ( + +
{title}
+ +
{body}
+
+ } + /> + ); +} + +export default Popover; diff --git a/frontend/src/Components/Tooltip/Tooltip.js b/frontend/src/Components/Tooltip/Tooltip.js deleted file mode 100644 index 1499e74513..0000000000 --- a/frontend/src/Components/Tooltip/Tooltip.js +++ /dev/null @@ -1,235 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { Manager, Popper, Reference } from 'react-popper'; -import Portal from 'Components/Portal'; -import { kinds, tooltipPositions } from 'Helpers/Props'; -import dimensions from 'Styles/Variables/dimensions'; -import { isMobile as isMobileUtil } from 'Utilities/browser'; -import styles from './Tooltip.css'; - -let maxWidth = null; - -function getMaxWidth() { - const windowWidth = window.innerWidth; - - if (windowWidth >= parseInt(dimensions.breakpointLarge)) { - maxWidth = 800; - } else if (windowWidth >= parseInt(dimensions.breakpointMedium)) { - maxWidth = 650; - } else if (windowWidth >= parseInt(dimensions.breakpointSmall)) { - maxWidth = 500; - } else { - maxWidth = 450; - } - - return maxWidth; -} - -class Tooltip extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this._scheduleUpdate = null; - this._closeTimeout = null; - this._maxWidth = maxWidth || getMaxWidth(); - - this.state = { - isOpen: false - }; - } - - componentDidUpdate() { - if (this._scheduleUpdate && this.state.isOpen) { - this._scheduleUpdate(); - } - } - - componentWillUnmount() { - if (this._closeTimeout) { - this._closeTimeout = clearTimeout(this._closeTimeout); - } - } - - // - // Control - - computeMaxSize = (data) => { - const { - top, - right, - bottom, - left - } = data.offsets.reference; - - const windowWidth = window.innerWidth; - const windowHeight = window.innerHeight; - - if ((/^top/).test(data.placement)) { - data.styles.maxHeight = top - 20; - } else if ((/^bottom/).test(data.placement)) { - data.styles.maxHeight = windowHeight - bottom - 20; - } else if ((/^right/).test(data.placement)) { - data.styles.maxWidth = Math.min(this._maxWidth, windowWidth - right - 20); - data.styles.maxHeight = top - 20; - } else { - data.styles.maxWidth = Math.min(this._maxWidth, left - 20); - data.styles.maxHeight = top - 20; - } - - return data; - }; - - // - // Listeners - - onMeasure = ({ width }) => { - this.setState({ width }); - }; - - onClick = () => { - if (isMobileUtil()) { - this.setState({ isOpen: !this.state.isOpen }); - } - }; - - onMouseEnter = () => { - if (this._closeTimeout) { - this._closeTimeout = clearTimeout(this._closeTimeout); - } - - this.setState({ isOpen: true }); - }; - - onMouseLeave = () => { - this._closeTimeout = setTimeout(() => { - this.setState({ isOpen: false }); - }, 100); - }; - - // - // Render - - render() { - const { - className, - bodyClassName, - anchor, - tooltip, - kind, - position, - canFlip - } = this.props; - - return ( - - - {({ ref }) => ( - - {anchor} - - )} - - - - - {({ ref, style, placement, arrowProps, scheduleUpdate }) => { - this._scheduleUpdate = scheduleUpdate; - - const popperPlacement = placement ? placement.split('-')[0] : position; - const vertical = popperPlacement === 'top' || popperPlacement === 'bottom'; - - return ( -
-
- { - this.state.isOpen ? -
-
- {tooltip} -
-
: - null - } -
- ); - }} - - - - ); - } -} - -Tooltip.propTypes = { - className: PropTypes.string, - bodyClassName: PropTypes.string.isRequired, - anchor: PropTypes.node.isRequired, - tooltip: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired, - kind: PropTypes.oneOf([kinds.DEFAULT, kinds.INVERSE]), - position: PropTypes.oneOf(tooltipPositions.all), - canFlip: PropTypes.bool.isRequired -}; - -Tooltip.defaultProps = { - bodyClassName: styles.body, - kind: kinds.DEFAULT, - position: tooltipPositions.TOP, - canFlip: false -}; - -export default Tooltip; diff --git a/frontend/src/Components/Tooltip/Tooltip.tsx b/frontend/src/Components/Tooltip/Tooltip.tsx new file mode 100644 index 0000000000..43150c755e --- /dev/null +++ b/frontend/src/Components/Tooltip/Tooltip.tsx @@ -0,0 +1,226 @@ +import classNames from 'classnames'; +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { Manager, Popper, Reference } from 'react-popper'; +import Portal from 'Components/Portal'; +import { kinds, tooltipPositions } from 'Helpers/Props'; +import { Kind } from 'Helpers/Props/kinds'; +import dimensions from 'Styles/Variables/dimensions'; +import { isMobile as isMobileUtil } from 'Utilities/browser'; +import styles from './Tooltip.css'; + +export interface TooltipProps { + className?: string; + bodyClassName?: string; + anchor: React.ReactNode; + tooltip: string | React.ReactNode; + kind?: Extract; + position?: (typeof tooltipPositions.all)[number]; + canFlip?: boolean; +} +function Tooltip(props: TooltipProps) { + const { + className, + bodyClassName = styles.body, + anchor, + tooltip, + kind = kinds.DEFAULT, + position = tooltipPositions.TOP, + canFlip = false, + } = props; + + const closeTimeout = useRef>(); + const updater = useRef<(() => void) | null>(null); + const [isOpen, setIsOpen] = useState(false); + + const handleClick = useCallback(() => { + if (!isMobileUtil()) { + return; + } + + setIsOpen((isOpen) => { + return !isOpen; + }); + }, [setIsOpen]); + + const handleMouseEnterAnchor = useCallback(() => { + // Mobile will fire mouse enter and click events rapidly, + // this causes the tooltip not to open on the first press. + // Ignore the mouse enter event on mobile. + + if (isMobileUtil()) { + return; + } + + if (closeTimeout.current) { + clearTimeout(closeTimeout.current); + } + + setIsOpen(true); + }, [setIsOpen]); + + const handleMouseEnterTooltip = useCallback(() => { + if (closeTimeout.current) { + clearTimeout(closeTimeout.current); + } + + setIsOpen(true); + }, [setIsOpen]); + + const handleMouseLeave = useCallback(() => { + // Still listen for mouse leave on mobile to allow clicks outside to close the tooltip. + + clearTimeout(closeTimeout.current); + closeTimeout.current = setTimeout(() => { + setIsOpen(false); + }, 100); + }, [setIsOpen]); + + const maxWidth = useMemo(() => { + const windowWidth = window.innerWidth; + + if (windowWidth >= parseInt(dimensions.breakpointLarge)) { + return 800; + } else if (windowWidth >= parseInt(dimensions.breakpointMedium)) { + return 650; + } else if (windowWidth >= parseInt(dimensions.breakpointSmall)) { + return 500; + } + + return 450; + }, []); + + const computeMaxSize = useCallback( + // eslint-disable-next-line @typescript-eslint/no-explicit-any + (data: any) => { + const { top, right, bottom, left } = data.offsets.reference; + + const windowWidth = window.innerWidth; + const windowHeight = window.innerHeight; + + if (/^top/.test(data.placement)) { + data.styles.maxHeight = top - 20; + } else if (/^bottom/.test(data.placement)) { + data.styles.maxHeight = windowHeight - bottom - 20; + } else if (/^right/.test(data.placement)) { + data.styles.maxWidth = Math.min(maxWidth, windowWidth - right - 20); + data.styles.maxHeight = top - 20; + } else { + data.styles.maxWidth = Math.min(maxWidth, left - 20); + data.styles.maxHeight = top - 20; + } + + return data; + }, + [maxWidth] + ); + + useEffect(() => { + if (updater.current && isOpen) { + updater.current(); + } + }); + + useEffect(() => { + return () => { + if (closeTimeout.current) { + clearTimeout(closeTimeout.current); + } + }; + }, []); + + return ( + + + {({ ref }) => ( + + {anchor} + + )} + + + + + {({ ref, style, placement, arrowProps, scheduleUpdate }) => { + updater.current = scheduleUpdate; + + const popperPlacement = placement + ? placement.split('-')[0] + : position; + const vertical = + popperPlacement === 'top' || popperPlacement === 'bottom'; + + return ( +
+
+ {isOpen ? ( +
+
{tooltip}
+
+ ) : null} +
+ ); + }} + + + + ); +} + +export default Tooltip; diff --git a/frontend/src/Helpers/Props/ScrollDirection.ts b/frontend/src/Helpers/Props/ScrollDirection.ts deleted file mode 100644 index 0da932d220..0000000000 --- a/frontend/src/Helpers/Props/ScrollDirection.ts +++ /dev/null @@ -1,8 +0,0 @@ -enum ScrollDirection { - Horizontal = 'horizontal', - Vertical = 'vertical', - None = 'none', - Both = 'both', -} - -export default ScrollDirection; diff --git a/frontend/src/Helpers/Props/SortDirection.ts b/frontend/src/Helpers/Props/SortDirection.ts deleted file mode 100644 index ac027fadc4..0000000000 --- a/frontend/src/Helpers/Props/SortDirection.ts +++ /dev/null @@ -1,6 +0,0 @@ -enum SortDirection { - Ascending = 'ascending', - Descending = 'descending', -} - -export default SortDirection; diff --git a/frontend/src/Helpers/Props/TooltipPosition.ts b/frontend/src/Helpers/Props/TooltipPosition.ts deleted file mode 100644 index 885c734705..0000000000 --- a/frontend/src/Helpers/Props/TooltipPosition.ts +++ /dev/null @@ -1,3 +0,0 @@ -type TooltipPosition = 'top' | 'right' | 'bottom' | 'left'; - -export default TooltipPosition; diff --git a/frontend/src/Helpers/Props/align.ts b/frontend/src/Helpers/Props/align.ts index f381959c6c..06b19ca11e 100644 --- a/frontend/src/Helpers/Props/align.ts +++ b/frontend/src/Helpers/Props/align.ts @@ -3,3 +3,5 @@ export const CENTER = 'center'; export const RIGHT = 'right'; export const all = [LEFT, CENTER, RIGHT]; + +export type Align = 'left' | 'center' | 'right'; diff --git a/frontend/src/Helpers/Props/scrollDirections.js b/frontend/src/Helpers/Props/scrollDirections.ts similarity index 71% rename from frontend/src/Helpers/Props/scrollDirections.js rename to frontend/src/Helpers/Props/scrollDirections.ts index 1ae61143bd..e82fdfae61 100644 --- a/frontend/src/Helpers/Props/scrollDirections.js +++ b/frontend/src/Helpers/Props/scrollDirections.ts @@ -4,3 +4,5 @@ export const HORIZONTAL = 'horizontal'; export const VERTICAL = 'vertical'; export const all = [NONE, HORIZONTAL, VERTICAL, BOTH]; + +export type ScrollDirection = 'none' | 'both' | 'horizontal' | 'vertical'; diff --git a/frontend/src/Helpers/Props/sortDirections.js b/frontend/src/Helpers/Props/sortDirections.ts similarity index 68% rename from frontend/src/Helpers/Props/sortDirections.js rename to frontend/src/Helpers/Props/sortDirections.ts index ff3b17bb69..f082cfa593 100644 --- a/frontend/src/Helpers/Props/sortDirections.js +++ b/frontend/src/Helpers/Props/sortDirections.ts @@ -2,3 +2,5 @@ export const ASCENDING = 'ascending'; export const DESCENDING = 'descending'; export const all = [ASCENDING, DESCENDING]; + +export type SortDirection = 'ascending' | 'descending'; diff --git a/frontend/src/Helpers/Props/tooltipPositions.js b/frontend/src/Helpers/Props/tooltipPositions.ts similarity index 50% rename from frontend/src/Helpers/Props/tooltipPositions.js rename to frontend/src/Helpers/Props/tooltipPositions.ts index bca3c4ed4f..9dcd543a37 100644 --- a/frontend/src/Helpers/Props/tooltipPositions.js +++ b/frontend/src/Helpers/Props/tooltipPositions.ts @@ -3,9 +3,6 @@ export const RIGHT = 'right'; export const BOTTOM = 'bottom'; export const LEFT = 'left'; -export const all = [ - TOP, - RIGHT, - BOTTOM, - LEFT -]; +export const all = [TOP, RIGHT, BOTTOM, LEFT]; + +export type TooltipPosition = 'top' | 'right' | 'bottom' | 'left'; diff --git a/frontend/src/Movie/Details/MovieDetailsLinks.css b/frontend/src/Movie/Details/MovieDetailsLinks.css index ae160b2c56..aa192ef66e 100644 --- a/frontend/src/Movie/Details/MovieDetailsLinks.css +++ b/frontend/src/Movie/Details/MovieDetailsLinks.css @@ -13,3 +13,10 @@ cursor: pointer; } + +@media only screen and (max-width: $breakpointExtraSmall) { + .links { + display: flex; + flex-flow: column wrap; + } +} diff --git a/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx b/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx index bf740141f4..1b48da4e88 100644 --- a/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx +++ b/frontend/src/Movie/Index/Menus/MovieIndexSortMenu.tsx @@ -3,7 +3,7 @@ import MenuContent from 'Components/Menu/MenuContent'; import SortMenu from 'Components/Menu/SortMenu'; import SortMenuItem from 'Components/Menu/SortMenuItem'; import { align } from 'Helpers/Props'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { SortDirection } from 'Helpers/Props/sortDirections'; import translate from 'Utilities/String/translate'; interface MovieIndexSortMenuProps { diff --git a/frontend/src/Movie/Index/MovieIndex.tsx b/frontend/src/Movie/Index/MovieIndex.tsx index 49eaf4eda4..972e650885 100644 --- a/frontend/src/Movie/Index/MovieIndex.tsx +++ b/frontend/src/Movie/Index/MovieIndex.tsx @@ -22,7 +22,7 @@ import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; import withScrollPosition from 'Components/withScrollPosition'; import { align, icons, kinds } from 'Helpers/Props'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { DESCENDING } from 'Helpers/Props/sortDirections'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import NoMovie from 'Movie/NoMovie'; import { executeCommand } from 'Store/Actions/commandActions'; @@ -211,7 +211,7 @@ const MovieIndex = withScrollPosition((props: MovieIndexProps) => { const order = Object.keys(characters).sort(); // Reverse if sorting descending - if (sortDirection === SortDirection.Descending) { + if (sortDirection === DESCENDING) { order.reverse(); } diff --git a/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx b/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx index 5b2d7b2bf7..cef7ec4617 100644 --- a/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx +++ b/frontend/src/Movie/Index/Posters/MovieIndexPosters.tsx @@ -5,7 +5,7 @@ import { FixedSizeGrid as Grid, GridChildComponentProps } from 'react-window'; import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; import useMeasure from 'Helpers/Hooks/useMeasure'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { SortDirection } from 'Helpers/Props/sortDirections'; import MovieIndexPoster from 'Movie/Index/Posters/MovieIndexPoster'; import Movie from 'Movie/Movie'; import dimensions from 'Styles/Variables/dimensions'; diff --git a/frontend/src/Movie/Index/Table/MovieIndexTable.tsx b/frontend/src/Movie/Index/Table/MovieIndexTable.tsx index 51d84d8df6..b2c6dea4bb 100644 --- a/frontend/src/Movie/Index/Table/MovieIndexTable.tsx +++ b/frontend/src/Movie/Index/Table/MovieIndexTable.tsx @@ -7,8 +7,7 @@ import AppState from 'App/State/AppState'; import Scroller from 'Components/Scroller/Scroller'; import Column from 'Components/Table/Column'; import useMeasure from 'Helpers/Hooks/useMeasure'; -import ScrollDirection from 'Helpers/Props/ScrollDirection'; -import SortDirection from 'Helpers/Props/SortDirection'; +import { SortDirection } from 'Helpers/Props/sortDirections'; import Movie from 'Movie/Movie'; import dimensions from 'Styles/Variables/dimensions'; import getIndexOfFirstCharacter from 'Utilities/Array/getIndexOfFirstCharacter'; @@ -170,10 +169,7 @@ function MovieIndexTable(props: MovieIndexTableProps) { return (
- + Date: Tue, 22 Oct 2024 09:51:40 +0300 Subject: [PATCH 031/579] Rename 'On Import' to 'On File Import' and 'On Upgrade' to 'On File Upgrade' Closes #10164 --- .../src/Settings/Notifications/Notifications/Notification.js | 4 ++-- .../Notifications/Notifications/NotificationEventItems.js | 4 ++-- src/NzbDrone.Core/Localization/Core/en.json | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/frontend/src/Settings/Notifications/Notifications/Notification.js b/frontend/src/Settings/Notifications/Notifications/Notification.js index 3efa17f546..6b5e4c60d6 100644 --- a/frontend/src/Settings/Notifications/Notifications/Notification.js +++ b/frontend/src/Settings/Notifications/Notifications/Notification.js @@ -105,7 +105,7 @@ class Notification extends Component { { supportsOnDownload && onDownload ? : null } @@ -113,7 +113,7 @@ class Notification extends Component { { supportsOnUpgrade && onDownload && onUpgrade ? : null } diff --git a/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js b/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js index 5ca851d64e..aa680f6ebc 100644 --- a/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js +++ b/frontend/src/Settings/Notifications/Notifications/NotificationEventItems.js @@ -66,7 +66,7 @@ function NotificationEventItems(props) { Date: Tue, 22 Oct 2024 08:38:23 +0000 Subject: [PATCH 032/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Co-authored-by: DNArjen Co-authored-by: Fixer Co-authored-by: Havok Dan Co-authored-by: Kuzmich Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 2 -- src/NzbDrone.Core/Localization/Core/bg.json | 2 -- src/NzbDrone.Core/Localization/Core/ca.json | 5 ++- src/NzbDrone.Core/Localization/Core/cs.json | 5 ++- src/NzbDrone.Core/Localization/Core/da.json | 2 -- src/NzbDrone.Core/Localization/Core/de.json | 2 -- src/NzbDrone.Core/Localization/Core/el.json | 2 -- src/NzbDrone.Core/Localization/Core/es.json | 10 +++--- src/NzbDrone.Core/Localization/Core/fi.json | 7 +++-- src/NzbDrone.Core/Localization/Core/fr.json | 13 ++++++-- src/NzbDrone.Core/Localization/Core/he.json | 2 -- src/NzbDrone.Core/Localization/Core/hi.json | 2 -- src/NzbDrone.Core/Localization/Core/hu.json | 2 -- src/NzbDrone.Core/Localization/Core/id.json | 4 ++- src/NzbDrone.Core/Localization/Core/is.json | 2 -- src/NzbDrone.Core/Localization/Core/it.json | 5 ++- src/NzbDrone.Core/Localization/Core/ja.json | 2 -- src/NzbDrone.Core/Localization/Core/ko.json | 6 ++-- src/NzbDrone.Core/Localization/Core/nl.json | 6 ++-- src/NzbDrone.Core/Localization/Core/pl.json | 5 ++- src/NzbDrone.Core/Localization/Core/pt.json | 2 -- .../Localization/Core/pt_BR.json | 10 +++--- src/NzbDrone.Core/Localization/Core/ro.json | 8 ++--- src/NzbDrone.Core/Localization/Core/ru.json | 31 +++++++++++-------- src/NzbDrone.Core/Localization/Core/sv.json | 5 ++- src/NzbDrone.Core/Localization/Core/th.json | 2 -- src/NzbDrone.Core/Localization/Core/tr.json | 2 -- src/NzbDrone.Core/Localization/Core/uk.json | 5 ++- src/NzbDrone.Core/Localization/Core/vi.json | 2 -- .../Localization/Core/zh_CN.json | 7 +++-- .../Localization/Core/zh_TW.json | 5 ++- 31 files changed, 77 insertions(+), 88 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 018c87cf7f..0785c95bbd 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -238,7 +238,6 @@ "OnlyUsenet": "يوزنت فقط", "OnlyTorrent": "فقط تورنت", "OnLatestVersion": "تم بالفعل تثبيت أحدث إصدار من {appName}", - "OnImport": "عند الاستيراد", "OnHealthIssue": "في قضية الصحة", "OnGrab": "عند الاستيلاء", "Ok": "موافق", @@ -954,7 +953,6 @@ "OnMovieDelete": "عند حذف الفيلم", "OnMovieFileDelete": "عند حذف ملف الفيلم", "OnMovieFileDeleteForUpgrade": "عند حذف ملف الفيلم للترقية", - "OnUpgrade": "عند الترقية", "Reddit": "رديت", "More": "أكثر", "Download": "تحميل", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index a8529a0722..b21ba80feb 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -4,7 +4,6 @@ "MovieNaming": "Именуване на филми", "OpenBrowserOnStart": "Отворете браузъра при стартиране", "OnHealthIssue": "По здравен въпрос", - "OnImport": "При импортиране", "OnLatestVersion": "Вече е инсталирана най-новата версия на {appName}", "OnlyTorrent": "Само Торент", "PendingChangesMessage": "Имате незапазени промени. Наистина ли искате да напуснете тази страница?", @@ -953,7 +952,6 @@ "OnMovieDelete": "На Изтриване на филм", "OnMovieFileDelete": "В Изтриване на файл с филм", "OnMovieFileDeleteForUpgrade": "Във филмов файл Изтриване за надстройка", - "OnUpgrade": "При надстройка", "Reddit": "Reddit", "More": "| Повече ▼", "Download": "Изтегли", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 700a444569..c3b99c5ae1 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -640,14 +640,12 @@ "OAuthPopupMessage": "Les finestres emergents estan sent bloquejades pel vostre navegador", "OnApplicationUpdate": "A l'actualitzar de l'aplicació", "OnHealthIssue": "Al detectar incidència", - "OnImport": "Al importar", "OnLatestVersion": "La darrera versió de {appName} ja està instal·lada", "OnlyTorrent": "Només Torrent", "OnlyUsenet": "Només Usenet", "OnMovieFileDelete": "Al suprimir fitxer de pel·lícula", "OnMovieFileDeleteForUpgrade": "Al suprimir el fitxer de pel·lícula per a l'actualització", "OnRename": "Al reanomenar", - "OnUpgrade": "A l'actualitzar", "Options": "Opcions", "Organize": "Organitza", "OrganizeConfirm": "Esteu segur que voleu organitzar tots els fitxers de la(es) {count} pel·lícula(es) seleccionada(es)?", @@ -1386,5 +1384,6 @@ "ShowDigitalRelease": "Mostra la data d'estrena", "ShowDigitalReleaseHelpText": "Mostra la data de llançament sota el cartell", "Logout": "Tanca la sessió", - "FolderNameTokens": "Testimonis de nom de fitxer" + "FolderNameTokens": "Testimonis de nom de fitxer", + "DefaultNotFoundMessage": "Deu estar perdut, no hi ha res a veure aquí." } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index d6edfbe113..dcf34809f8 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -286,7 +286,6 @@ "Tomorrow": "Zítra", "OnGrab": "Chyť", "OnHealthIssue": "K otázce zdraví", - "OnImport": "Při importu", "OnlyTorrent": "Pouze Torrent", "OnlyUsenet": "Pouze Usenet", "OnRename": "Při přejmenování", @@ -953,7 +952,6 @@ "OnMovieDelete": "Při mazání filmu", "OnMovieFileDelete": "Při mazání filmových souborů", "OnMovieFileDeleteForUpgrade": "Na filmovém souboru Odstranit pro upgrade", - "OnUpgrade": "Při upgradu", "Reddit": "Reddit", "More": "Více", "Download": "Stažení", @@ -1202,5 +1200,6 @@ "ShowDigitalRelease": "Zobrazit datum vydání kina", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Několik kořenových adresářů chybí pro seznamy importu: {rootFoldersInfo}", "FolderNameTokens": "Tokeny názvů souborů", - "Letterboxd": "Letterboxd" + "Letterboxd": "Letterboxd", + "DefaultNotFoundMessage": "Asi jsi se ztratil, není tu nic k vidění." } diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index e3deb2e062..50640851cc 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -286,7 +286,6 @@ "MovieFilesTotaling": "Totale filmfiler", "OnGrab": "ved hentning", "OnHealthIssue": "Om sundhedsspørgsmål", - "OnImport": "Ved import", "OnLatestVersion": "Den seneste version af {appName} er allerede installeret", "OnlyTorrent": "Kun Torrent", "OnlyUsenet": "Kun Usenet", @@ -952,7 +951,6 @@ "ShowReleaseDateHelpText": "Vis udgivelsesdato under plakat", "OnMovieFileDelete": "Slet på filmfil", "OnMovieFileDeleteForUpgrade": "På filmfil Slet til opgradering", - "OnUpgrade": "Ved opgradering", "OnMovieDelete": "Ved sletning af film", "Reddit": "Reddit", "More": "Mere", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 7e4998d94d..277d0098e6 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -830,7 +830,6 @@ "OnlyUsenet": "Nur Usenet", "OnlyTorrent": "Nur Torrents", "OnLatestVersion": "Die aktuellste Version ist bereits installiert", - "OnImport": "Beim Import", "OnHealthIssue": "Bei Zustandsproblem", "OnGrab": "Bei Erfassung", "NoResultsFound": "Keine Ergebnisse gefunden", @@ -943,7 +942,6 @@ "OnMovieDelete": "Beim Löschen des Films", "OnMovieFileDelete": "Bei Filmdatei löschen", "OnMovieFileDeleteForUpgrade": "Bei Filmdatei Zum Upgrade löschen", - "OnUpgrade": "Bei Aktualisierung", "Reddit": "Reddit", "More": "Mehr", "Download": "Herunterladen", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index a0b2e13092..045412a6fe 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -271,7 +271,6 @@ "CancelPendingTask": "Είστε βέβαιοι ότι θέλετε να ακυρώσετε αυτήν την εργασία σε εκκρεμότητα;", "OnGrab": "Στο Grab", "OnHealthIssue": "Σχετικά με το θέμα της υγείας", - "OnImport": "Κατά την εισαγωγή", "OnLatestVersion": "Η τελευταία έκδοση του {appName} είναι ήδη εγκατεστημένη", "OnlyTorrent": "Μόνο Torrent", "OnlyUsenet": "Μόνο Usenet", @@ -950,7 +949,6 @@ "ShowCinemaRelease": "Εμφάνιση ημερομηνίας κυκλοφορίας κινηματογράφου", "ShowReleaseDate": "Εμφάνιση ημερομηνίας κυκλοφορίας", "ShowReleaseDateHelpText": "Εμφάνιση ημερομηνίας κυκλοφορίας στην αφίσα", - "OnUpgrade": "Κατά την αναβάθμιση", "OnMovieDelete": "Διαγραφή ταινίας", "OnMovieFileDelete": "Διαγραφή αρχείου ταινίας", "OnMovieFileDeleteForUpgrade": "Διαγραφή αρχείου ταινίας για αναβάθμιση", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 810583bc79..dc93d55824 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -800,7 +800,6 @@ "MovieFilesTotaling": "Totalización de archivos de película", "OnGrab": "Al capturar", "OnHealthIssue": "Al haber un problema de salud", - "OnImport": "Al importar", "OnLatestVersion": "La última versión de {appName} ya está instalada", "OnlyTorrent": "Solo torrent", "OnlyUsenet": "Solo Usenet", @@ -946,7 +945,6 @@ "OnMovieDelete": "Al Eliminar Película", "OnMovieFileDelete": "Al Eliminar Archivo De Película", "OnMovieFileDeleteForUpgrade": "Al Eliminar Archivo De Pelicula Para Mejorar La Calidad", - "OnUpgrade": "Al actualizar", "Reddit": "Reddit", "More": "Más", "Download": "Descargar", @@ -1762,7 +1760,7 @@ "IncludeTrending": "Incluir tendencias", "IncludeTrendingMoviesHelpText": "Incluye películas en tendencia en TMDb", "BlocklistFilterHasNoItems": "El filtro de lista de bloqueo seleccionado no contiene elementos", - "NoMovieReleaseDatesAvailable": "Ninguna fecha de lanzamiento disponible en TMDb para esta película.", + "NoMovieReleaseDatesAvailable": "Ninguna fecha de lanzamiento disponible en [TMDb]({url}) para esta película.", "CutoffUnmetLoadError": "Error cargando elementos con límites no alcanzados", "CutoffUnmetNoItems": "Ningún elemento con límites no alcanzados", "External": "Externa", @@ -1836,5 +1834,9 @@ "ReleasedMovieAvailabilityDescription": "Las películas se consideran disponibles tan pronto como se lanzan la versión en Blu-Ray o en streaming.", "SmartReplaceHint": "Raya o barra espaciadora según el nombre", "SmartReplace": "Reemplazo inteligente", - "FolderNameTokens": "Tokens de nombre de carpeta" + "FolderNameTokens": "Tokens de nombre de carpeta", + "Install": "Instalar", + "InstallMajorVersionUpdate": "Instalar actualización", + "InstallMajorVersionUpdateMessage": "Esta actualización instalará una nueva versión principal y podría no ser compatible con tu sistema. ¿Estás seguro que quieres instalar esta actualización?", + "InstallMajorVersionUpdateMessageLink": "Por favor revisa [{domain}]({url}) para más información." } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 273289ba9e..28d917e9bb 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -213,7 +213,6 @@ "MovieFilesTotaling": "Elokuvatiedostot yhteensä", "OnGrab": "Kun julkaisu kaapataan", "OnHealthIssue": "Vakausongelmat", - "OnImport": "Tuotaessa", "OnLatestVersion": "Uusin {appName}-versio on jo asennettu", "OnlyTorrent": "Vain Torrent", "OnlyUsenet": "Vain Usenet", @@ -950,7 +949,6 @@ "ShowReleaseDate": "Näytä fyysinen julkaisu", "ShowReleaseDateHelpText": "Näytä fyysisen julkaisun päivä julisteen alla.", "OnMovieDelete": "Kun elokuva poistetaan", - "OnUpgrade": "Päivitettäessä", "OnMovieFileDelete": "Kun elokuvatiedosto poistetaan", "OnMovieFileDeleteForUpgrade": "Kun elokuvatiedosto poistetaan päivitystä varten", "Reddit": "Reddit", @@ -1760,5 +1758,8 @@ "Logout": "Kirjaudu ulos", "ShowTraktRatingPosterHelpText": "Näytä Tomato-arvio julisteen alla.", "SmartReplaceHint": "Yhdysmerkki tai välilyönti nimen perusteella", - "FolderNameTokens": "Tiedostonimen muuttujat" + "FolderNameTokens": "Tiedostonimen muuttujat", + "DefaultNotFoundMessage": "Lienet eksyksissä, koska täällä ei ole mitään nähtävää.", + "ToggleMonitoredToUnmonitored": "Valvotaan (lopeta painamalla)", + "ToggleUnmonitoredToMonitored": "Ei valvota (aloita painamalla)" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 00be66ddb8..f213488467 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -857,7 +857,6 @@ "NoResultsFound": "Aucun résultat trouvé", "OnGrab": "Lors de la saisie", "OnHealthIssue": "Lors de problème de santé", - "OnImport": "À l'importation", "OnLatestVersion": "La dernière version de {appName} est déjà installée", "OnlyTorrent": "Uniquement Torrent", "OnlyUsenet": "Uniquement Usenet", @@ -951,7 +950,6 @@ "ShowCinemaRelease": "Afficher la date de sortie du cinéma", "ShowReleaseDate": "Afficher la date de sortie", "ShowReleaseDateHelpText": "Affiche la date de sortie sous l'affiche", - "OnUpgrade": "Lors de la mise à niveau", "OnMovieDelete": "À la suppression d'un film", "OnMovieFileDelete": "À la suppression d'un fichier vidéo", "OnMovieFileDeleteForUpgrade": "À la suppression d'un fichier vidéo pour mise à niveau", @@ -1824,5 +1822,14 @@ "AnnouncedMovieAvailabilityDescription": "Les films sont considérés disponibles dès qu'ils sont ajouté à {appName}.", "CustomFormatsSpecificationExceptLanguage": "Excepté Langue", "CustomFormatsSpecificationExceptLanguageHelpText": "Corresponf si l'autre langue que celle sélectionné est présente", - "FolderNameTokens": "Jetons de nom de fichier" + "FolderNameTokens": "Jetons de nom de fichier", + "Install": "Installer", + "InstallMajorVersionUpdate": "Installer la mise à jour", + "InstallMajorVersionUpdateMessage": "Cette mise à jour installera une nouvelle version majeure et pourrait ne pas être compatible avec votre système. Êtes-vous sûr de vouloir installer cette mise à jour ?", + "InstallMajorVersionUpdateMessageLink": "Veuillez consulter [{domain}]({url}) pour plus d'informations.", + "DefaultNotFoundMessage": "Vous devez être perdu, rien à voir ici.", + "ToggleMonitoredToUnmonitored": "Surveillé, cliquez pour annuler la surveillance", + "ToggleUnmonitoredToMonitored": "Non surveillé, cliquez pour surveiller", + "OnFileImport": "Lors de l'importation du fichier", + "OnFileUpgrade": "Lors de la mise à jour du fichier" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 7f48a470fd..a4a7fadc68 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -291,7 +291,6 @@ "NextExecution": "הביצוע הבא", "NoAlternativeTitles": "אין כותרות חלופיות.", "OnHealthIssue": "בנושא הבריאות", - "OnImport": "בייבוא", "OnLatestVersion": "הגרסה האחרונה של {appName} כבר מותקנת", "OnlyTorrent": "רק סיקור", "OnlyUsenet": "רק Usenet", @@ -952,7 +951,6 @@ "ShowReleaseDate": "הצגת תאריך פרסום", "OnMovieFileDelete": "במחיקת קובץ הסרט", "OnMovieFileDeleteForUpgrade": "במחיקת קובץ הסרט לצורך שדרוג", - "OnUpgrade": "בשדרוג", "OnMovieDelete": "במחיקת סרט", "Reddit": "רדיט", "More": "יותר", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 28b3170d49..59dbbb88ed 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -488,7 +488,6 @@ "NextExecution": "अगला निष्पादन", "NoResultsFound": "कोई परिणाम नहीं मिला", "OnHealthIssue": "स्वास्थ्य के मुद्दे पर", - "OnImport": "आयात पर", "OnLatestVersion": "रेडर का नवीनतम संस्करण पहले से ही स्थापित है", "InCinemas": "सिनेमाघरों में", "MovieFolderFormat": "मूवी फ़ोल्डर प्रारूप", @@ -953,7 +952,6 @@ "OnMovieDelete": "मूवी डिलीट पर", "OnMovieFileDelete": "मूवी फ़ाइल डिलीट पर", "OnMovieFileDeleteForUpgrade": "अपग्रेड के लिए मूवी फ़ाइल हटाएं", - "OnUpgrade": "अपग्रेड पर", "Reddit": "reddit", "More": "अधिक", "Download": "डाउनलोड", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index d8b4da1735..c0205eddd2 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -905,7 +905,6 @@ "OnlyUsenet": "Csak usenet", "OnlyTorrent": "Csak torrent", "OnLatestVersion": "A {appName} legújabb verziója már telepítva van", - "OnImport": "Importálás alatt", "OnGrab": "Kiválasztás alatt", "NoResultsFound": "Nincs találat", "None": "Egyik sem", @@ -953,7 +952,6 @@ "OnMovieDelete": "A film törlésekor", "OnMovieFileDelete": "A filmfájl törléséhez", "OnMovieFileDeleteForUpgrade": "A filmfájl törlése frissítéshez", - "OnUpgrade": "Minőségjavítás alatt", "Reddit": "Reddit", "More": "Több", "Download": "Letöltés", diff --git a/src/NzbDrone.Core/Localization/Core/id.json b/src/NzbDrone.Core/Localization/Core/id.json index c3d71ab850..831b04104b 100644 --- a/src/NzbDrone.Core/Localization/Core/id.json +++ b/src/NzbDrone.Core/Localization/Core/id.json @@ -170,5 +170,7 @@ "DownloadFailed": "Pengunduhan Ulang Gagal", "Months": "Bulan", "File": "File", - "Weeks": "Minggu" + "Weeks": "Minggu", + "ToggleMonitoredToUnmonitored": "Dimonitor, klik untuk berhenti monitor", + "ToggleUnmonitoredToMonitored": "Tidak dimonitor, klik untuk monitor" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index a5dafe8bcc..3612f442c3 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -261,7 +261,6 @@ "MovieFilesTotaling": "Kvikmyndaskrár samtals", "OnGrab": "Á grípa", "OnHealthIssue": "Um heilbrigðismál", - "OnImport": "Við innflutning", "OnLatestVersion": "Nýjasta útgáfan af {appName} er þegar uppsett", "OnlyUsenet": "Aðeins Usenet", "OnRename": "Um Endurnefna", @@ -952,7 +951,6 @@ "ShowReleaseDateHelpText": "Sýnið útgáfudagsetningu undir veggspjaldi", "OnMovieFileDelete": "Á Eyða kvikmyndaskrá", "OnMovieFileDeleteForUpgrade": "Á kvikmyndaskrá eytt til uppfærslu", - "OnUpgrade": "Við uppfærslu", "OnMovieDelete": "Í Eyðingu kvikmyndar", "Reddit": "Reddit", "More": "Meira", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 77c4e82102..351f801f3f 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -818,7 +818,6 @@ "MovieFilesTotaling": "Totale file di film", "OnGrab": "Al Prelievo", "OnHealthIssue": "Quando c'è un problema", - "OnImport": "In importazione", "OnLatestVersion": "L'ultima versione di {appName} è già installata", "OnlyTorrent": "Solo Torrent", "OnlyUsenet": "Solo Usenet", @@ -951,7 +950,6 @@ "OnMovieDelete": "All'eliminazione del filmato", "OnMovieFileDelete": "Su Elimina file filmato", "OnMovieFileDeleteForUpgrade": "Su file filmato Elimina per aggiornamento", - "OnUpgrade": "In aggiornamento", "Reddit": "Reddit", "More": "Altro", "Download": "Scarica", @@ -1471,5 +1469,6 @@ "YesterdayAt": "Ieri alle {time}", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Diverse cartelle principale sono perse per l’importazione: {rootFoldersInfo}", "ShowTraktRatingPosterHelpText": "Mostra valutazione Tomato sotta la locandina", - "FolderNameTokens": "Token nome file" + "FolderNameTokens": "Token nome file", + "DefaultNotFoundMessage": "Ti devi essere perso, non c'è nulla da vedere qui." } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 157de467b8..11a91f95b6 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -239,7 +239,6 @@ "Cancel": "キャンセル", "OnGrab": "グラブで", "OnHealthIssue": "健康問題について", - "OnImport": "インポート時", "OnLatestVersion": "{appName}の最新バージョンはすでにインストールされています", "OnlyTorrent": "トレントのみ", "OnlyUsenet": "Usenetのみ", @@ -951,7 +950,6 @@ "ShowReleaseDate": "リリース日を表示", "ShowReleaseDateHelpText": "ポスターの下にリリース日を表示する", "OnMovieFileDeleteForUpgrade": "アップグレードのためのムービーファイルの削除", - "OnUpgrade": "アップグレード時", "OnMovieDelete": "映画の削除について", "OnMovieFileDelete": "ムービーファイルの削除について", "Reddit": "Reddit", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 23456bb358..a49428160e 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -239,7 +239,6 @@ "CancelPendingTask": "이 보류 중인 작업을 취소하시겠습니까?", "OnGrab": "잡기", "OnHealthIssue": "건강 문제", - "OnImport": "가져올 때", "OnLatestVersion": "최신 버전의 {appName}가 이미 설치되어 있습니다.", "OnlyTorrent": "토렌트 만", "OnlyUsenet": "유즈넷 만", @@ -951,7 +950,6 @@ "ShowCinemaRelease": "영화 개봉일 표시", "ShowReleaseDate": "출시일 표시", "OnMovieFileDeleteForUpgrade": "영화 파일에서 업그레이드를 위해 삭제", - "OnUpgrade": "업그레이드시", "OnMovieDelete": "영화 삭제 시", "OnMovieFileDelete": "영화 파일 삭제", "Reddit": "레딧", @@ -1054,5 +1052,7 @@ "DeleteSelectedMovies": "선택한 동영상 파일 삭제", "DeleteSelectedImportListExclusionsMessageText": "이 가져오기 목록 제외를 삭제하시겠습니까?", "DeleteSelectedCustomFormats": "사용자 지정 형식 삭제", - "ReleaseDate": "출시일" + "ReleaseDate": "출시일", + "MovieFileDeleted": "영화 파일 삭제", + "MovieFileDeletedTooltip": "영화 파일 삭제" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 8764a475bd..8f8be5abc0 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -895,7 +895,6 @@ "OnlyUsenet": "Alleen Usenet", "OnlyTorrent": "Alleen Torrent", "OnLatestVersion": "De nieuwste versie van {appName} is al geïnstalleerd", - "OnImport": "Bij importeren", "OnHealthIssue": "Bij gezondheidsprobleem", "OnGrab": "Bij ophalen", "NoResultsFound": "Geen resultaten gevonden", @@ -954,7 +953,6 @@ "OnMovieDelete": "Op film verwijderen", "OnMovieFileDelete": "Op filmbestand verwijderen", "OnMovieFileDeleteForUpgrade": "Op filmbestand verwijderen voor upgrade", - "OnUpgrade": "Bij Opwaarderen", "Reddit": "Reddit", "More": "Meer", "Download": "Downloaden", @@ -1238,5 +1236,7 @@ "ShowDigitalReleaseHelpText": "Laat releasedatum zien onder poster", "ShowPhysicalRelease": "Fysieke Release Datum", "ShowPhysicalReleaseHelpText": "Laat releasedatum zien onder poster", - "FolderNameTokens": "Bestandsnaam Tokens" + "FolderNameTokens": "Bestandsnaam Tokens", + "CountVotes": "{votes} Stemmen", + "AnnouncedMovieAvailabilityDescription": "Films worden als beschikbaar getoond zodra deze zijn toegevoegd aan {appName}." } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 5cc125898b..db21bc245e 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -254,7 +254,6 @@ "MovieFiles": "Pliki filmowe", "OnGrab": "Na Grab", "OnHealthIssue": "W kwestii zdrowia", - "OnImport": "Przy imporcie", "OpenThisModal": "Otwórz ten modal", "PreferTorrent": "Wolisz Torrent", "PreferUsenet": "Preferuj Usenet", @@ -952,7 +951,6 @@ "OnMovieDelete": "Usuń film", "OnMovieFileDelete": "Usuń plik filmowy", "OnMovieFileDeleteForUpgrade": "W przypadku usunięcia pliku filmowego w celu uaktualnienia", - "OnUpgrade": "Przy aktualizacji", "Reddit": "Reddit", "More": "Jeszcze", "Download": "Ściągnij", @@ -1186,5 +1184,6 @@ "ShowDigitalReleaseHelpText": "Pokaż datę premiery pod plakatem", "ShowPhysicalRelease": "Fizyczna data wydania", "ShowPhysicalReleaseHelpText": "Pokaż datę premiery pod plakatem", - "YesterdayAt": "Wczoraj o {time}" + "YesterdayAt": "Wczoraj o {time}", + "FolderNameTokens": "Tokeny nazw plików" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 7fb42ff7dc..45a6b3c6d4 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -825,7 +825,6 @@ "NoMoviesExist": "Nenhum filme encontrado. Para começar, adiciona um novo filme ou importa alguns já existentes.", "NoResultsFound": "Nenhum resultado encontrado", "OnHealthIssue": "Ao ter problemas no estado de funcionamento", - "OnImport": "Ao importar", "OnLatestVersion": "A versão mais recente do {appName} já está instalada", "OnRename": "Ao renomear", "PreferTorrent": "Preferir torrent", @@ -954,7 +953,6 @@ "OnMovieDelete": "Ao eliminar o filme", "OnMovieFileDelete": "Ao eliminar o ficheiro do filme", "OnMovieFileDeleteForUpgrade": "Ao eliminar o ficheiro do filme para atualização", - "OnUpgrade": "Ao atualizar", "Reddit": "Reddit", "More": "Mais", "Download": "Transferência", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index e186610332..738e63e252 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -859,7 +859,6 @@ "OnlyUsenet": "Só Usenet", "OnlyTorrent": "Só Torrent", "OnLatestVersion": "A versão mais recente do {appName} já está instalada", - "OnImport": "Ao Importar", "OnHealthIssue": "Ao Problema de Saúde", "OnGrab": "Ao obter", "Ok": "Ok", @@ -953,7 +952,6 @@ "ShowReleaseDateHelpText": "Mostrar data de lançamento com base na disponibilidade mínima no pôster", "OnMovieFileDelete": "Ao Excluir Arquivo do Filme", "OnMovieFileDeleteForUpgrade": "Ao Excluir Arquivo do Filme para Atualizar", - "OnUpgrade": "Ao Atualizar", "OnMovieDelete": "Ao Excluir Filme", "Reddit": "Reddit", "More": "Mais", @@ -1762,7 +1760,7 @@ "IncludePopularMoviesHelpText": "Incluir filmes populares no TMDb", "IncludeTrending": "Incluir Tendências", "IncludeTrendingMoviesHelpText": "Incluir filmes populares no TMDb", - "NoMovieReleaseDatesAvailable": "Nenhuma data de lançamento disponível no TMDb para este filme.", + "NoMovieReleaseDatesAvailable": "Nenhuma data de lançamento disponível no [TMDb]({url}) para este filme.", "CutoffUnmetLoadError": "Erro ao carregar itens de corte não atingidos", "CutoffUnmetNoItems": "Nenhum item com limite não atingido", "External": "Externo", @@ -1836,5 +1834,9 @@ "ReleasedMovieAvailabilityDescription": "Filmes são considerados como disponíveis assim que é lançado em Blu-Ray ou no streaming.", "SmartReplace": "Substituição inteligente", "SmartReplaceHint": "Traço ou Espaço e Traço, dependendo do nome", - "FolderNameTokens": "Tokens de Nome de Pasta" + "FolderNameTokens": "Tokens de Nome de Pasta", + "Install": "Instalar", + "InstallMajorVersionUpdate": "Instalar Atualização", + "InstallMajorVersionUpdateMessage": "Esta atualização instalará uma nova versão principal e pode não ser compatível com o seu sistema. Tem certeza de que deseja instalar esta atualização?", + "InstallMajorVersionUpdateMessageLink": "Verifique [{domain}]({url}) para obter mais informações." } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 36ea94c6b5..7cf726c00f 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -257,7 +257,7 @@ "CustomFormatUnknownCondition": "Stare necunoscută pentru formatul personalizat „{0}”", "QualitySettings": "Setări de calitate", "Cutoff": "A tăia calea", - "FileNameTokens": "Jetoane cu nume de fișier", + "FileNameTokens": "Jetoane pentru nume de fișier", "ChownGroupHelpTextWarning": "Acest lucru funcționează numai dacă utilizatorul care rulează {appName} este proprietarul fișierului. Este mai bine să vă asigurați că clientul de descărcare folosește același grup ca {appName}.", "QualitiesHelpText": "Calitățile mai mari din listă sunt mai preferate. Calitățile din același grup sunt egale. Se doresc doar calități verificate", "MovieInfoLanguageHelpTextWarning": "Reîncărcare browser necesară", @@ -351,7 +351,6 @@ "DatabaseMigration": "Migrarea BD", "Manual": "Manual", "OnHealthIssue": "Cu privire la problema sănătății", - "OnImport": "La import", "OnLatestVersion": "Cea mai recentă versiune a {appName} este deja instalată", "OnlyTorrent": "Numai Torrent", "OnlyUsenet": "Doar Usenet", @@ -954,7 +953,6 @@ "OnMovieDelete": "Pe Ștergere film", "OnMovieFileDelete": "Pe Ștergere fișier film", "OnMovieFileDeleteForUpgrade": "Ștergeți fișierul de film pentru actualizare", - "OnUpgrade": "La actualizare", "Reddit": "Reddit", "More": "Mai mult", "Download": "Descarca", @@ -1147,5 +1145,7 @@ "ShowDigitalReleaseHelpText": "Afișați data lansării sub afiș", "ShowPhysicalRelease": "Data de lansare fizică", "ShowPhysicalReleaseHelpText": "Afișați data lansării sub afiș", - "FolderNameTokens": "Jetoane cu nume de fișier" + "FolderNameTokens": "Jetoane pentru nume de folder", + "OnFileImport": "La import fișier", + "OnFileUpgrade": "La actualizare fișier" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 8d134e2ba8..d99970ddc8 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -219,7 +219,7 @@ "AllResultsHiddenFilter": "Все результаты скрыты фильтром", "AddDownloadClient": "Добавить клиент загрузки", "AppDataDirectory": "Каталог AppData", - "AptUpdater": "Используйте apt для установки обновления", + "AptUpdater": "Использовать apt для установки обновления", "AuthForm": "Формы (Страница авторизации)", "BeforeUpdate": "До обновления", "BuiltIn": "Встроено", @@ -290,7 +290,7 @@ "AddCustomFormatError": "Невозможно добавить новый пользовательский формат, попробуйте ещё раз.", "WhatsNew": "Что нового?", "Wiki": "Wiki", - "WouldYouLikeToRestoreBackup": "Желаете восстановить резервную копию {name} ?", + "WouldYouLikeToRestoreBackup": "Хотите восстановить резервную копию '{name}'?", "YesMoveFiles": "Да, перенести файлы", "Logs": "Журналы", "ManualImport": "Ручной импорт", @@ -454,7 +454,6 @@ "OnlyUsenet": "Только Usenet", "OnlyTorrent": "Только торрент", "OnLatestVersion": "Последняя версия {appName} уже установлена", - "OnImport": "При импорте", "OnHealthIssue": "При проблемах с состоянием", "OnGrab": "При захвате", "Ok": "Ок", @@ -610,7 +609,7 @@ "ExtraFileExtensionsHelpText": "Список дополнительных файлов для импорта, разделенных запятыми (.nfo будет импортирован как .nfo-orig)", "ExternalUpdater": "{appName} настроен на использование внешнего механизма обновления", "Extension": "Расширение", - "ErrorRestoringBackup": "Ошибка при восстановлении данных", + "ErrorRestoringBackup": "Восстановить резервную копию", "EnableColorImpairedModeHelpText": "Измененный стиль, позволяющий пользователям с нарушением цвета лучше различать информацию с цветовой кодировкой", "EnableColorImpairedMode": "Включить режим для слабовидящих", "EnableAutomaticSearchHelpText": "Будет использовано при автоматическом поиске через интерфейс или {appName}", @@ -800,7 +799,7 @@ "RestoreBackup": "Восстановить резервную копию", "Restore": "Восстановить", "RestartRequiredHelpTextWarning": "Для применения изменений, требуется перезапуск", - "RestartReloadNote": "Примечание: {appName} автоматически перезапустится и перезагрузит пользовательский интерфейс во время процесса восстановления.", + "RestartReloadNote": "Примечание: {appName} автоматически перезапустится и перезагрузит интерфейс пользователя во время процесса восстановления.", "RestartRadarr": "Перезапустить {appName}", "RestartNow": "Перезапустить сейчас", "Restart": "Перезапустить", @@ -836,7 +835,7 @@ "TimeFormat": "Формат времени", "Time": "Время", "ThisCannotBeCancelled": "Это действие нельзя отменить после запуска без отключения всех ваших индексаторов.", - "TheLogLevelDefault": "По умолчанию уровень журнала равен «Информация», и его можно изменить в [Общие настройки](/settings/general)", + "TheLogLevelDefault": "Уровень журналирования по умолчанию установлен на 'Информация' и может быть изменён в [Общих настройках](/settings/general)", "TestAllLists": "Тестировать все листы", "TestAllIndexers": "Тестировать все индексаторы", "TestAllClients": "Тестировать все клиенты", @@ -953,10 +952,9 @@ "OnMovieDelete": "При удалении фильма", "OnMovieFileDelete": "При удалении файла фильма", "OnMovieFileDeleteForUpgrade": "При удалении файла фильма для обновления", - "OnUpgrade": "При обновлении", "Reddit": "Reddit", "More": "Ещё", - "Download": "Скачать", + "Download": "Загрузить", "DownloadClientCheckDownloadingToRoot": "Клиент загрузки {downloadClientName} помещает загрузки в корневую папку {path}. Вы не должны загружать в корневую папку.", "RemotePathMappingCheckWrongOSPath": "Удалённый клиент загрузки {downloadClientName} загружает файлы в {path}, но это не действительный путь {osName}. Проверьте соответствие удаленных путей и настройки клиента загрузки.", "RemotePathMappingCheckRemoteDownloadClient": "Удалённый клиент загрузки {downloadClientName} сообщил о файлах в {path}, но эта директория, похоже, не существует. Вероятно, отсутствует сопоставление удаленных путей.", @@ -1439,7 +1437,7 @@ "TorrentBlackholeSaveMagnetFilesHelpText": "Сохранить магнет-ссылку, если файл .torrent недоступен (полезно только в случае, если клиент загрузки поддерживает магнет-ссылки, сохранённые в файле)", "TypeOfList": "{typeOfList} список", "UnknownEventTooltip": "Неизвестное событие", - "UpdaterLogFiles": "Фалы журналов обновления", + "UpdaterLogFiles": "Файлы журнала обновления", "UsenetBlackhole": "Usenet Черная дыра", "UsenetBlackholeNzbFolder": "Каталог NZB", "DownloadClientQbittorrentSettingsContentLayout": "Макет контента", @@ -1652,7 +1650,7 @@ "FormatTimeSpanDays": "{days}d {time}", "InfoUrl": "URL-адрес информации", "InvalidUILanguage": "В вашем пользовательском интерфейсе установлен недопустимый язык. Исправьте его и сохраните настройки", - "LogFilesLocation": "Файлы журнала расположены по адресу: {location}", + "LogFilesLocation": "Файлы журнала расположены в: {location}", "NotificationsDiscordSettingsOnImportFields": "Поля импорта", "PreferProtocol": "Предпочитать {preferredProtocol}", "FailedToUpdateSettings": "Не удалось обновить настройки", @@ -1718,7 +1716,7 @@ "NotificationsJoinSettingsDeviceIdsHelpText": "Устарело, вместо этого используйте имена устройств. Список идентификаторов устройств, разделенных запятыми, на которые вы хотите отправлять уведомления. Если параметр не установлен, все устройства будут получать уведомления.", "ReleaseProfileIndexerHelpTextWarning": "Установка определенного индексатора в профиле релиза приведет к тому, что этот профиль будет применяться только к релизам из этого индексатора.", "ReleaseProfileIndexerHelpText": "Укажите, к какому индексатору применяется профиль", - "FailedToFetchUpdates": "Не удалось получить обновления", + "FailedToFetchUpdates": "Не удалось загрузить обновления", "FormatRuntimeMinutes": "{minutes}мин", "FormatRuntimeHours": "{hours}ч", "FormatShortTimeSpanMinutes": "{minutes} минут(ы)", @@ -1770,12 +1768,19 @@ "TodayAt": "Сегодня в{time}", "TomorrowAt": "Завтра в {time}", "YesterdayAt": "Вчера в {time}", - "Logout": "Выйти", + "Logout": "Завершить сеанс", "Menu": "Меню", "LogSizeLimit": "Ограничение размера журнала", "LogSizeLimitHelpText": "Максимальный размер файла журнала в МБ перед архивированием. По умолчанию - 1 МБ.", "ShowTraktRatingPosterHelpText": "Показать рейтинг Tomato под постером", "SmartReplace": "Умная замена", "SmartReplaceHint": "Тире или пробел в зависимости от имени", - "FolderNameTokens": "Токены имени файла" + "FolderNameTokens": "Токены имени файла", + "Install": "Установить", + "InstallMajorVersionUpdateMessageLink": "Пожалуйста, проверьте [{domain}]({url}) для получения дополнительной информации.", + "InstallMajorVersionUpdate": "Установить обновление", + "InstallMajorVersionUpdateMessage": "Это обновление установит новую основную версию и может быть несовместимо с вашей системой. Вы уверены, что хотите установить это обновление?", + "DefaultNotFoundMessage": "Вы, должно быть, заблудились, здесь не на что смотреть.", + "ToggleMonitoredToUnmonitored": "Отслеживается, нажмите, чтобы отключить отслеживание", + "ToggleUnmonitoredToMonitored": "Не отслеживается, нажмите, чтобы отслеживать" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 79c6e926bc..7eeee1d32d 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -456,7 +456,6 @@ "NoLinks": "Inga länkar", "NoLogFiles": "Inga loggfiler", "None": "Ingen", - "OnImport": "Vid import", "MoviesSelectedInterp": "{0} Film(er) markerade", "DeleteSelectedMovieFiles": "Radera markerade filmfiler", "DeleteSelectedMovie": "Radera markerad(e) film(er)", @@ -953,7 +952,6 @@ "OnMovieDelete": "Vid radering av film", "OnMovieFileDelete": "På filmfil Ta bort", "OnMovieFileDeleteForUpgrade": "På filmfil Radera för uppgradering", - "OnUpgrade": "Vid uppgradering", "Reddit": "Reddit", "More": "Mer", "Download": "Ladda ner", @@ -1096,5 +1094,6 @@ "ShowDigitalRelease": "Visa utgivningsdatum för bio", "ShowDigitalReleaseHelpText": "Visa släppdatum under affischen", "ShowPhysicalRelease": "Fysiskt utgivningsdatum", - "ShowPhysicalReleaseHelpText": "Visa släppdatum under affischen" + "ShowPhysicalReleaseHelpText": "Visa släppdatum under affischen", + "FolderNameTokens": "Filnamn tokens" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index d701831805..9dc48eb81b 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -12,7 +12,6 @@ "NoLinks": "ไม่มีลิงค์", "NoMoviesExist": "ไม่พบภาพยนตร์ในการเริ่มต้นคุณจะต้องเพิ่มภาพยนตร์ใหม่หรือนำเข้าภาพยนตร์ที่มีอยู่", "Calendar": "ปฏิทิน", - "OnImport": "ในการนำเข้า", "OpenBrowserOnStart": "เปิดเบราว์เซอร์เมื่อเริ่มต้น", "PendingChangesDiscardChanges": "ยกเลิกการเปลี่ยนแปลงและออก", "ProxyType": "ประเภทพร็อกซี", @@ -953,7 +952,6 @@ "OnMovieDelete": "บน Movie Delete", "OnMovieFileDelete": "บน Movie File Delete", "OnMovieFileDeleteForUpgrade": "ในไฟล์ภาพยนตร์ลบสำหรับการอัปเกรด", - "OnUpgrade": "ในการอัพเกรด", "Reddit": "Reddit", "More": "มากกว่า", "Download": "ดาวน์โหลด", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 97ee048e46..99214201a7 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -475,7 +475,6 @@ "NoResultsFound": "Sonuç bulunamadı", "MovieFilesTotaling": "Film Dosyaları Toplamı", "OnGrab": "Yakalandığında", - "OnImport": "İçe Aktarmada", "OnlyUsenet": "Sadece Usenet", "PendingChangesMessage": "Kaydedilmemiş değişiklikleriniz var, bu sayfadan ayrılmak istediğinizden emin misiniz?", "ProxyType": "Proxy Türü", @@ -953,7 +952,6 @@ "OnMovieDelete": "Film Silindiğinde", "OnMovieFileDelete": "Film Dosyası Silindiğinde", "OnMovieFileDeleteForUpgrade": "Yükseltme İçin Film Dosyası Silindiğinde", - "OnUpgrade": "Yükseltme sırasında", "Reddit": "Reddit", "More": "Daha", "Download": "İndir", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index fc596afd73..d8d57eeced 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -725,11 +725,9 @@ "NotMonitored": "Не контролюється", "OAuthPopupMessage": "Ваш браузер блокує спливаючі вікна", "Ok": "Гаразд", - "OnImport": "При імпорті", "OnLatestVersion": "Остання версія {appName} вже встановлена", "OnlyTorrent": "Тільки торрент", "OnlyUsenet": "Тільки Usenet", - "OnUpgrade": "При оновленні", "OpenBrowserOnStart": "Відкрийте браузер при запуску", "Original": "Оригінал", "OriginalLanguage": "Мова оригіналу", @@ -1288,5 +1286,6 @@ "ShowDigitalReleaseHelpText": "Показати дату випуску під плакатом", "ShowPhysicalRelease": "Дата фізичного випуску", "ShowPhysicalReleaseHelpText": "Показати дату випуску під плакатом", - "FolderNameTokens": "Маркери імен файлів" + "FolderNameTokens": "Маркери імен файлів", + "DefaultNotFoundMessage": "Ви, мабуть, заблукали, тут нічого не видно." } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 6a58934f04..418da4ad0a 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -320,7 +320,6 @@ "NoChanges": "Không thay đổi", "OnGrab": "Trên Grab", "OnHealthIssue": "Về vấn đề sức khỏe", - "OnImport": "Khi nhập khẩu", "OnLatestVersion": "Phiên bản mới nhất của {appName} đã được cài đặt", "OnlyTorrent": "Chỉ Torrent", "OnlyUsenet": "Chỉ Usenet", @@ -953,7 +952,6 @@ "OnMovieDelete": "Trên phim Xóa", "OnMovieFileDelete": "Trên phim xóa tệp", "OnMovieFileDeleteForUpgrade": "Trên tệp phim, xóa để nâng cấp", - "OnUpgrade": "Đang nâng cấp", "Reddit": "Reddit", "More": "Hơn", "Download": "Tải xuống", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 059441bb8b..362a0d29c0 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -544,7 +544,6 @@ "OnlyUsenet": "只有usenet", "OnlyTorrent": "只有torrent", "OnLatestVersion": "已安装最新版的{appName}", - "OnImport": "导入中", "OnGrab": "抓取中", "NotMonitored": "不追踪项", "NoMoveFilesSelf": " 不,我要自己移动文件", @@ -951,7 +950,6 @@ "ShowReleaseDateHelpText": "根据最小可用条件在海报下显示发布日期", "OnMovieFileDelete": "电影文件删除时", "OnMovieFileDeleteForUpgrade": "电影文件为升级删除时", - "OnUpgrade": "升级中", "OnMovieDelete": "电影删除时", "Reddit": "Reddit", "More": "更多", @@ -1836,5 +1834,8 @@ "InCinemasMovieAvailabilityDescription": "一旦在影院上映便被视为可用的电影。", "ReleasedMovieAvailabilityDescription": "一旦蓝光或流媒体版本发布便被视为可用的电影。", "TraktRating": "Trakt 评分", - "FolderNameTokens": "文件名标记" + "FolderNameTokens": "文件名标记", + "ToggleMonitoredToUnmonitored": "已监视,单击可取消监视", + "ToggleUnmonitoredToMonitored": "未监控,单击进行监控", + "DefaultNotFoundMessage": "你一定是迷路了,这里没什么可看的。" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index 672a581d9b..ded9981007 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -246,5 +246,8 @@ "AddQualityProfileError": "無法加入新的條件,請重新嘗試。", "AddCustomFormatError": "無法加入新的自動標籤,請重新嘗試。", "AddDelayProfileError": "無法加入新的條件,請重新嘗試。", - "DeleteImportListExclusion": "新增排除清單" + "DeleteImportListExclusion": "新增排除清單", + "Letterboxd": "文字方框", + "Discord": "Discord", + "TMDb": "TMDb" } From 13f10906f1b7a725cf939e4db0bca72f44e5b1f2 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 18 Aug 2024 18:58:29 -0700 Subject: [PATCH 033/579] Fixed: PWA Manifest with URL base (cherry picked from commit aedcd046fc4fc621dae4b231cc80d4b269a69177) Fixed: PWA Manifest images (cherry picked from commit da7d17f5e826d5273dba0b4f73227ffc8ed8a6c7) Closes #10317 Closes #10329 --- frontend/build/webpack.config.js | 6 ++ .../Content/Images/Icons/browserconfig.xml | 9 --- .../src/Content/Images/Icons/manifest.json | 19 ------ frontend/src/Content/browserconfig.xml | 11 ++++ frontend/src/Content/manifest.json | 19 ++++++ frontend/src/index.ejs | 4 +- frontend/src/login.html | 59 +++++++++---------- .../Frontend/Mappers/BrowserConfig.cs | 19 ++---- .../Frontend/Mappers/ManifestMapper.cs | 19 ++---- .../Frontend/Mappers/StaticResourceMapper.cs | 4 +- .../UrlBaseReplacementResourceMapperBase.cs | 58 ++++++++++++++++++ 11 files changed, 138 insertions(+), 89 deletions(-) delete mode 100644 frontend/src/Content/Images/Icons/browserconfig.xml delete mode 100644 frontend/src/Content/Images/Icons/manifest.json create mode 100644 frontend/src/Content/browserconfig.xml create mode 100644 frontend/src/Content/manifest.json create mode 100644 src/Radarr.Http/Frontend/Mappers/UrlBaseReplacementResourceMapperBase.cs diff --git a/frontend/build/webpack.config.js b/frontend/build/webpack.config.js index 60dd6d2b12..b4b423674f 100644 --- a/frontend/build/webpack.config.js +++ b/frontend/build/webpack.config.js @@ -133,6 +133,12 @@ module.exports = (env) => { { source: 'frontend/src/Content/robots.txt', destination: path.join(distFolder, 'Content/robots.txt') + }, + + // manifest.json and browserconfig.xml + { + source: 'frontend/src/Content/*.(json|xml)', + destination: path.join(distFolder, 'Content') } ] } diff --git a/frontend/src/Content/Images/Icons/browserconfig.xml b/frontend/src/Content/Images/Icons/browserconfig.xml deleted file mode 100644 index 993924968f..0000000000 --- a/frontend/src/Content/Images/Icons/browserconfig.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - #00ccff - - - diff --git a/frontend/src/Content/Images/Icons/manifest.json b/frontend/src/Content/Images/Icons/manifest.json deleted file mode 100644 index 37817250e9..0000000000 --- a/frontend/src/Content/Images/Icons/manifest.json +++ /dev/null @@ -1,19 +0,0 @@ -{ - "name": "Radarr", - "icons": [ - { - "src": "android-chrome-192x192.png", - "sizes": "192x192", - "type": "image/png" - }, - { - "src": "android-chrome-512x512.png", - "sizes": "512x512", - "type": "image/png" - } - ], - "start_url": "../../../../", - "theme_color": "#3a3f51", - "background_color": "#3a3f51", - "display": "standalone" -} diff --git a/frontend/src/Content/browserconfig.xml b/frontend/src/Content/browserconfig.xml new file mode 100644 index 0000000000..646112d061 --- /dev/null +++ b/frontend/src/Content/browserconfig.xml @@ -0,0 +1,11 @@ + + + + + + + #00ccff + + + + diff --git a/frontend/src/Content/manifest.json b/frontend/src/Content/manifest.json new file mode 100644 index 0000000000..31dc2ba11d --- /dev/null +++ b/frontend/src/Content/manifest.json @@ -0,0 +1,19 @@ +{ + "name": "Radarr", + "icons": [ + { + "src": "__URL_BASE__/Content/Images/Icons/android-chrome-192x192.png", + "sizes": "192x192", + "type": "image/png" + }, + { + "src": "__URL_BASE__/Content/Images/Icons/android-chrome-512x512.png", + "sizes": "512x512", + "type": "image/png" + } + ], + "start_url": "__URL_BASE__/", + "theme_color": "#3a3f51", + "background_color": "#3a3f51", + "display": "standalone" +} diff --git a/frontend/src/index.ejs b/frontend/src/index.ejs index 05bd5790be..f40ed28dc2 100644 --- a/frontend/src/index.ejs +++ b/frontend/src/index.ejs @@ -33,7 +33,7 @@ sizes="16x16" href="/Content/Images/Icons/favicon-16x16.png" /> - + diff --git a/frontend/src/login.html b/frontend/src/login.html index 85142880ea..2b00abb578 100644 --- a/frontend/src/login.html +++ b/frontend/src/login.html @@ -11,8 +11,11 @@ - - + + @@ -33,7 +36,11 @@ sizes="16x16" href="/Content/Images/Icons/favicon-16x16.png" /> - + - + @@ -59,7 +63,7 @@ body { background-color: var(--pageBackground); color: var(--textColor); - font-family: "Roboto", "open sans", "Helvetica Neue", Helvetica, Arial, + font-family: 'Roboto', 'open sans', 'Helvetica Neue', Helvetica, Arial, sans-serif; } @@ -209,9 +213,7 @@
- +
@@ -282,16 +284,16 @@ diff --git a/src/Radarr.Http/Frontend/Mappers/BrowserConfig.cs b/src/Radarr.Http/Frontend/Mappers/BrowserConfig.cs index c0c592cbc0..6d910940f3 100644 --- a/src/Radarr.Http/Frontend/Mappers/BrowserConfig.cs +++ b/src/Radarr.Http/Frontend/Mappers/BrowserConfig.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.EnvironmentInfo; @@ -6,29 +6,22 @@ namespace Radarr.Http.Frontend.Mappers { - public class BrowserConfig : StaticResourceMapperBase + public class BrowserConfig : UrlBaseReplacementResourceMapperBase { - private readonly IAppFolderInfo _appFolderInfo; - private readonly IConfigFileProvider _configFileProvider; - public BrowserConfig(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger) - : base(diskProvider, logger) + : base(diskProvider, configFileProvider, logger) { - _appFolderInfo = appFolderInfo; - _configFileProvider = configFileProvider; + FilePath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "Content", "browserconfig.xml"); } public override string Map(string resourceUrl) { - var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar); - path = path.Trim(Path.DirectorySeparatorChar); - - return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "xml"); + return FilePath; } public override bool CanHandle(string resourceUrl) { - return resourceUrl.StartsWith("/content/images/icons/browserconfig"); + return resourceUrl.StartsWith("/Content/browserconfig"); } } } diff --git a/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs b/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs index c0ff69f7cc..bbe2e4554d 100644 --- a/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs +++ b/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs @@ -1,4 +1,4 @@ -using System.IO; +using System.IO; using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.EnvironmentInfo; @@ -6,29 +6,22 @@ namespace Radarr.Http.Frontend.Mappers { - public class ManifestMapper : StaticResourceMapperBase + public class ManifestMapper : UrlBaseReplacementResourceMapperBase { - private readonly IAppFolderInfo _appFolderInfo; - private readonly IConfigFileProvider _configFileProvider; - public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger) - : base(diskProvider, logger) + : base(diskProvider, configFileProvider, logger) { - _appFolderInfo = appFolderInfo; - _configFileProvider = configFileProvider; + FilePath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "Content", "manifest.json"); } public override string Map(string resourceUrl) { - var path = resourceUrl.Replace('/', Path.DirectorySeparatorChar); - path = path.Trim(Path.DirectorySeparatorChar); - - return Path.ChangeExtension(Path.Combine(_appFolderInfo.StartUpFolder, _configFileProvider.UiFolder, path), "json"); + return FilePath; } public override bool CanHandle(string resourceUrl) { - return resourceUrl.StartsWith("/Content/Images/Icons/manifest"); + return resourceUrl.StartsWith("/Content/manifest"); } } } diff --git a/src/Radarr.Http/Frontend/Mappers/StaticResourceMapper.cs b/src/Radarr.Http/Frontend/Mappers/StaticResourceMapper.cs index b7f9e7fc10..b9dcd34d9b 100644 --- a/src/Radarr.Http/Frontend/Mappers/StaticResourceMapper.cs +++ b/src/Radarr.Http/Frontend/Mappers/StaticResourceMapper.cs @@ -30,8 +30,8 @@ public override bool CanHandle(string resourceUrl) { resourceUrl = resourceUrl.ToLowerInvariant(); - if (resourceUrl.StartsWith("/content/images/icons/manifest") || - resourceUrl.StartsWith("/content/images/icons/browserconfig")) + if (resourceUrl.StartsWith("/content/manifest") || + resourceUrl.StartsWith("/content/browserconfig")) { return false; } diff --git a/src/Radarr.Http/Frontend/Mappers/UrlBaseReplacementResourceMapperBase.cs b/src/Radarr.Http/Frontend/Mappers/UrlBaseReplacementResourceMapperBase.cs new file mode 100644 index 0000000000..d8697c24a4 --- /dev/null +++ b/src/Radarr.Http/Frontend/Mappers/UrlBaseReplacementResourceMapperBase.cs @@ -0,0 +1,58 @@ +using System.IO; +using NLog; +using NzbDrone.Common.Disk; +using NzbDrone.Common.EnvironmentInfo; +using NzbDrone.Core.Configuration; + +namespace Radarr.Http.Frontend.Mappers +{ + public abstract class UrlBaseReplacementResourceMapperBase : StaticResourceMapperBase + { + private readonly IDiskProvider _diskProvider; + private readonly string _urlBase; + + private string _generatedContent; + + public UrlBaseReplacementResourceMapperBase(IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger) + : base(diskProvider, logger) + { + _diskProvider = diskProvider; + _urlBase = configFileProvider.UrlBase; + } + + protected string FilePath; + + public override string Map(string resourceUrl) + { + return FilePath; + } + + protected override Stream GetContentStream(string filePath) + { + var text = GetFileText(); + + var stream = new MemoryStream(); + var writer = new StreamWriter(stream); + writer.Write(text); + writer.Flush(); + stream.Position = 0; + return stream; + } + + protected virtual string GetFileText() + { + if (RuntimeInfo.IsProduction && _generatedContent != null) + { + return _generatedContent; + } + + var text = _diskProvider.ReadAllText(FilePath); + + text = text.Replace("__URL_BASE__", _urlBase); + + _generatedContent = text; + + return _generatedContent; + } + } +} From 6747b742718a84fbb380d6eadef329229a6738d4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 19 Jul 2024 20:42:59 -0700 Subject: [PATCH 034/579] Convert History to TypeScript (cherry picked from commit 824ed0a36931ce7aae9aa544a7baf0738dae568c) Closes #10230 Closes #10390 Closes #10247 --- .../History/Details/HistoryDetails.js | 354 ------------------ .../History/Details/HistoryDetails.tsx | 287 ++++++++++++++ .../Details/HistoryDetailsConnector.js | 18 - ...etailsModal.js => HistoryDetailsModal.tsx} | 78 ++-- frontend/src/Activity/History/History.js | 158 -------- frontend/src/Activity/History/History.tsx | 216 +++++++++++ .../src/Activity/History/HistoryConnector.js | 141 ------- ...ntTypeCell.js => HistoryEventTypeCell.tsx} | 56 +-- frontend/src/Activity/History/HistoryRow.js | 277 -------------- frontend/src/Activity/History/HistoryRow.tsx | 224 +++++++++++ .../Activity/History/HistoryRowConnector.js | 73 ---- frontend/src/App/AppRoutes.tsx | 4 +- frontend/src/App/State/HistoryAppState.ts | 6 +- .../src/Utilities/Object/selectUniqueIds.js | 15 - .../src/Utilities/Object/selectUniqueIds.ts | 13 + frontend/src/typings/Helpers/KeysMatching.ts | 2 +- frontend/src/typings/History.ts | 57 ++- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 8 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 8 +- src/NzbDrone.Core/Localization/Core/es.json | 8 +- src/NzbDrone.Core/Localization/Core/fi.json | 8 +- src/NzbDrone.Core/Localization/Core/fr.json | 8 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 4 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 6 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 8 +- src/NzbDrone.Core/Localization/Core/ro.json | 8 +- src/NzbDrone.Core/Localization/Core/ru.json | 4 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 8 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 8 +- 47 files changed, 923 insertions(+), 1178 deletions(-) delete mode 100644 frontend/src/Activity/History/Details/HistoryDetails.js create mode 100644 frontend/src/Activity/History/Details/HistoryDetails.tsx delete mode 100644 frontend/src/Activity/History/Details/HistoryDetailsConnector.js rename frontend/src/Activity/History/Details/{HistoryDetailsModal.js => HistoryDetailsModal.tsx} (52%) delete mode 100644 frontend/src/Activity/History/History.js create mode 100644 frontend/src/Activity/History/History.tsx delete mode 100644 frontend/src/Activity/History/HistoryConnector.js rename frontend/src/Activity/History/{HistoryEventTypeCell.js => HistoryEventTypeCell.tsx} (56%) delete mode 100644 frontend/src/Activity/History/HistoryRow.js create mode 100644 frontend/src/Activity/History/HistoryRow.tsx delete mode 100644 frontend/src/Activity/History/HistoryRowConnector.js delete mode 100644 frontend/src/Utilities/Object/selectUniqueIds.js create mode 100644 frontend/src/Utilities/Object/selectUniqueIds.ts diff --git a/frontend/src/Activity/History/Details/HistoryDetails.js b/frontend/src/Activity/History/Details/HistoryDetails.js deleted file mode 100644 index b3ae7cb2c8..0000000000 --- a/frontend/src/Activity/History/Details/HistoryDetails.js +++ /dev/null @@ -1,354 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import DescriptionList from 'Components/DescriptionList/DescriptionList'; -import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; -import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; -import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; -import Link from 'Components/Link/Link'; -import formatDateTime from 'Utilities/Date/formatDateTime'; -import formatAge from 'Utilities/Number/formatAge'; -import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; -import translate from 'Utilities/String/translate'; -import styles from './HistoryDetails.css'; - -function HistoryDetails(props) { - const { - eventType, - sourceTitle, - data, - downloadId, - shortDateFormat, - timeFormat - } = props; - - if (eventType === 'grabbed') { - const { - indexer, - releaseGroup, - movieMatchType, - customFormatScore, - nzbInfoUrl, - downloadClient, - downloadClientName, - age, - ageHours, - ageMinutes, - publishedDate - } = data; - - const downloadClientNameInfo = downloadClientName ?? downloadClient; - - return ( - - - - { - indexer ? - : - null - } - - { - releaseGroup ? - : - null - } - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - { - movieMatchType ? - : - null - } - - { - nzbInfoUrl ? - - - {translate('InfoUrl')} - - - - {nzbInfoUrl} - - : - null - } - - { - downloadClientNameInfo ? - : - null - } - - { - downloadId ? - : - null - } - - { - indexer ? - : - null - } - - { - publishedDate ? - : - null - } - - ); - } - - if (eventType === 'downloadFailed') { - const { - message - } = data; - - return ( - - - - { - downloadId ? - : - null - } - - { - message ? - : - null - } - - ); - } - - if (eventType === 'downloadFolderImported') { - const { - customFormatScore, - droppedPath, - importedPath - } = data; - - return ( - - - - { - droppedPath ? - : - null - } - - { - importedPath ? - : - null - } - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - ); - } - - if (eventType === 'movieFileDeleted') { - const { - reason, - customFormatScore - } = data; - - let reasonMessage = ''; - - switch (reason) { - case 'Manual': - reasonMessage = translate('DeletedReasonManual'); - break; - case 'MissingFromDisk': - reasonMessage = translate('DeletedReasonMissingFromDisk'); - break; - case 'Upgrade': - reasonMessage = translate('DeletedReasonUpgrade'); - break; - default: - reasonMessage = ''; - } - - return ( - - - - - - { - customFormatScore && customFormatScore !== '0' ? - : - null - } - - ); - } - - if (eventType === 'movieFileRenamed') { - const { - sourcePath, - sourceRelativePath, - path, - relativePath - } = data; - - return ( - - - - - - - - - - ); - } - - if (eventType === 'downloadIgnored') { - const { - message - } = data; - - return ( - - - - { - downloadId ? - : - null - } - - { - message ? - : - null - } - - ); - } - - return ( - - - - ); -} - -HistoryDetails.propTypes = { - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired -}; - -export default HistoryDetails; diff --git a/frontend/src/Activity/History/Details/HistoryDetails.tsx b/frontend/src/Activity/History/Details/HistoryDetails.tsx new file mode 100644 index 0000000000..3f9bcbfe90 --- /dev/null +++ b/frontend/src/Activity/History/Details/HistoryDetails.tsx @@ -0,0 +1,287 @@ +import React from 'react'; +import { useSelector } from 'react-redux'; +import DescriptionList from 'Components/DescriptionList/DescriptionList'; +import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; +import DescriptionListItemDescription from 'Components/DescriptionList/DescriptionListItemDescription'; +import DescriptionListItemTitle from 'Components/DescriptionList/DescriptionListItemTitle'; +import Link from 'Components/Link/Link'; +import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; +import { + DownloadFailedHistory, + DownloadFolderImportedHistory, + DownloadIgnoredHistory, + GrabbedHistoryData, + HistoryData, + HistoryEventType, + MovieFileDeletedHistory, + MovieFileRenamedHistory, +} from 'typings/History'; +import formatDateTime from 'Utilities/Date/formatDateTime'; +import formatAge from 'Utilities/Number/formatAge'; +import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; +import translate from 'Utilities/String/translate'; +import styles from './HistoryDetails.css'; + +interface HistoryDetailsProps { + eventType: HistoryEventType; + sourceTitle: string; + data: HistoryData; + downloadId?: string; +} + +function HistoryDetails(props: HistoryDetailsProps) { + const { eventType, sourceTitle, data, downloadId } = props; + + const { shortDateFormat, timeFormat } = useSelector( + createUISettingsSelector() + ); + + if (eventType === 'grabbed') { + const { + indexer, + releaseGroup, + movieMatchType, + customFormatScore, + nzbInfoUrl, + downloadClient, + downloadClientName, + age, + ageHours, + ageMinutes, + publishedDate, + } = data as GrabbedHistoryData; + + const downloadClientNameInfo = downloadClientName ?? downloadClient; + + return ( + + + + {indexer ? ( + + ) : null} + + {releaseGroup ? ( + + ) : null} + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + {movieMatchType ? ( + + ) : null} + + {nzbInfoUrl ? ( + + + {translate('InfoUrl')} + + + + {nzbInfoUrl} + + + ) : null} + + {downloadClientNameInfo ? ( + + ) : null} + + {downloadId ? ( + + ) : null} + + {age || ageHours || ageMinutes ? ( + + ) : null} + + {publishedDate ? ( + + ) : null} + + ); + } + + if (eventType === 'downloadFailed') { + const { message } = data as DownloadFailedHistory; + + return ( + + + + {downloadId ? ( + + ) : null} + + {message ? ( + + ) : null} + + ); + } + + if (eventType === 'downloadFolderImported') { + const { customFormatScore, droppedPath, importedPath } = + data as DownloadFolderImportedHistory; + + return ( + + + + {droppedPath ? ( + + ) : null} + + {importedPath ? ( + + ) : null} + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + ); + } + + if (eventType === 'movieFileDeleted') { + const { reason, customFormatScore } = data as MovieFileDeletedHistory; + + let reasonMessage = ''; + + switch (reason) { + case 'Manual': + reasonMessage = translate('DeletedReasonManual'); + break; + case 'MissingFromDisk': + reasonMessage = translate('DeletedReasonMovieMissingFromDisk'); + break; + case 'Upgrade': + reasonMessage = translate('DeletedReasonUpgrade'); + break; + default: + reasonMessage = ''; + } + + return ( + + + + + + {customFormatScore && customFormatScore !== '0' ? ( + + ) : null} + + ); + } + + if (eventType === 'movieFileRenamed') { + const { sourcePath, sourceRelativePath, path, relativePath } = + data as MovieFileRenamedHistory; + + return ( + + + + + + + + + + ); + } + + if (eventType === 'downloadIgnored') { + const { message } = data as DownloadIgnoredHistory; + + return ( + + + + {downloadId ? ( + + ) : null} + + {message ? ( + + ) : null} + + ); + } + + return ( + + + + ); +} + +export default HistoryDetails; diff --git a/frontend/src/Activity/History/Details/HistoryDetailsConnector.js b/frontend/src/Activity/History/Details/HistoryDetailsConnector.js deleted file mode 100644 index 65d95e5574..0000000000 --- a/frontend/src/Activity/History/Details/HistoryDetailsConnector.js +++ /dev/null @@ -1,18 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import HistoryDetails from './HistoryDetails'; - -function createMapStateToProps() { - return createSelector( - createUISettingsSelector(), - (uiSettings) => { - return { - shortDateFormat: uiSettings.shortDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -export default connect(createMapStateToProps)(HistoryDetails); diff --git a/frontend/src/Activity/History/Details/HistoryDetailsModal.js b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx similarity index 52% rename from frontend/src/Activity/History/Details/HistoryDetailsModal.js rename to frontend/src/Activity/History/Details/HistoryDetailsModal.tsx index 19fda4907c..c54f2654f1 100644 --- a/frontend/src/Activity/History/Details/HistoryDetailsModal.js +++ b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx @@ -1,4 +1,3 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Button from 'Components/Link/Button'; import SpinnerButton from 'Components/Link/SpinnerButton'; @@ -8,11 +7,12 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { kinds } from 'Helpers/Props'; +import { HistoryData, HistoryEventType } from 'typings/History'; import translate from 'Utilities/String/translate'; import HistoryDetails from './HistoryDetails'; import styles from './HistoryDetailsModal.css'; -function getHeaderTitle(eventType) { +function getHeaderTitle(eventType: HistoryEventType) { switch (eventType) { case 'grabbed': return translate('Grabbed'); @@ -31,29 +31,33 @@ function getHeaderTitle(eventType) { } } -function HistoryDetailsModal(props) { +interface HistoryDetailsModalProps { + isOpen: boolean; + eventType: HistoryEventType; + sourceTitle: string; + data: HistoryData; + downloadId?: string; + isMarkingAsFailed: boolean; + onMarkAsFailedPress: () => void; + onModalClose: () => void; +} + +function HistoryDetailsModal(props: HistoryDetailsModalProps) { const { isOpen, eventType, sourceTitle, data, downloadId, - isMarkingAsFailed, - shortDateFormat, - timeFormat, + isMarkingAsFailed = false, onMarkAsFailedPress, - onModalClose + onModalClose, } = props; return ( - + - - {getHeaderTitle(eventType)} - + {getHeaderTitle(eventType)} - { - eventType === 'grabbed' && - - {translate('MarkAsFailed')} - - } + {eventType === 'grabbed' && ( + + {translate('MarkAsFailed')} + + )} - + ); } -HistoryDetailsModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - isMarkingAsFailed: PropTypes.bool.isRequired, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -HistoryDetailsModal.defaultProps = { - isMarkingAsFailed: false -}; - export default HistoryDetailsModal; diff --git a/frontend/src/Activity/History/History.js b/frontend/src/Activity/History/History.js deleted file mode 100644 index 21a06fb570..0000000000 --- a/frontend/src/Activity/History/History.js +++ /dev/null @@ -1,158 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import FilterMenu from 'Components/Menu/FilterMenu'; -import PageContent from 'Components/Page/PageContent'; -import PageContentBody from 'Components/Page/PageContentBody'; -import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; -import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; -import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; -import Table from 'Components/Table/Table'; -import TableBody from 'Components/Table/TableBody'; -import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; -import TablePager from 'Components/Table/TablePager'; -import { align, icons, kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import HistoryFilterModal from './HistoryFilterModal'; -import HistoryRowConnector from './HistoryRowConnector'; - -class History extends Component { - - // - // Render - - render() { - const { - isFetching, - isPopulated, - error, - isMoviesFetching, - isMoviesPopulated, - moviesError, - items, - columns, - selectedFilterKey, - filters, - customFilters, - totalRecords, - onFilterSelect, - onFirstPagePress, - ...otherProps - } = this.props; - - const isFetchingAny = isFetching || isMoviesFetching; - const isAllPopulated = isPopulated && (isMoviesPopulated || !items.length); - const hasError = error || moviesError; - - return ( - - - - - - - - - - - - - - - - - { - isFetchingAny && !isAllPopulated && - - } - - { - !isFetchingAny && hasError && - - {translate('HistoryLoadError')} - - } - - { - // If history isPopulated and it's empty show no history found and don't - // wait for the episodes to populate because they are never coming. - - isPopulated && !hasError && !items.length && - - {translate('NoHistoryFound')} - - } - - { - isAllPopulated && !hasError && !!items.length && -
- - - { - items.map((item) => { - return ( - - ); - }) - } - -
- - -
- } -
-
- ); - } -} - -History.propTypes = { - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - isMoviesFetching: PropTypes.bool.isRequired, - isMoviesPopulated: PropTypes.bool.isRequired, - moviesError: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - columns: PropTypes.arrayOf(PropTypes.object).isRequired, - selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, - filters: PropTypes.arrayOf(PropTypes.object).isRequired, - customFilters: PropTypes.arrayOf(PropTypes.object).isRequired, - totalRecords: PropTypes.number, - onFilterSelect: PropTypes.func.isRequired, - onFirstPagePress: PropTypes.func.isRequired -}; - -export default History; diff --git a/frontend/src/Activity/History/History.tsx b/frontend/src/Activity/History/History.tsx new file mode 100644 index 0000000000..f4652b5cc3 --- /dev/null +++ b/frontend/src/Activity/History/History.tsx @@ -0,0 +1,216 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import Alert from 'Components/Alert'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import FilterMenu from 'Components/Menu/FilterMenu'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; +import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; +import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import TableOptionsModalWrapper from 'Components/Table/TableOptions/TableOptionsModalWrapper'; +import TablePager from 'Components/Table/TablePager'; +import usePaging from 'Components/Table/usePaging'; +import useCurrentPage from 'Helpers/Hooks/useCurrentPage'; +import { align, icons, kinds } from 'Helpers/Props'; +import createMoviesFetchingSelector from 'Movie/createMoviesFetchingSelector'; +import { + clearHistory, + fetchHistory, + gotoHistoryPage, + setHistoryFilter, + setHistorySort, + setHistoryTableOption, +} from 'Store/Actions/historyActions'; +import { createCustomFiltersSelector } from 'Store/Selectors/createClientSideCollectionSelector'; +import { TableOptionsChangePayload } from 'typings/Table'; +import { + registerPagePopulator, + unregisterPagePopulator, +} from 'Utilities/pagePopulator'; +import translate from 'Utilities/String/translate'; +import HistoryFilterModal from './HistoryFilterModal'; +import HistoryRow from './HistoryRow'; + +function History() { + const requestCurrentPage = useCurrentPage(); + + const { + isFetching, + isPopulated, + error, + items, + columns, + selectedFilterKey, + filters, + sortKey, + sortDirection, + page, + pageSize, + totalPages, + totalRecords, + } = useSelector((state: AppState) => state.history); + + const { isMoviesFetching, isMoviesPopulated, moviesError } = useSelector( + createMoviesFetchingSelector() + ); + const customFilters = useSelector(createCustomFiltersSelector('history')); + const dispatch = useDispatch(); + + const isFetchingAny = isFetching || isMoviesFetching; + const isAllPopulated = isPopulated && (isMoviesPopulated || !items.length); + const hasError = error || moviesError; + + const { + handleFirstPagePress, + handlePreviousPagePress, + handleNextPagePress, + handleLastPagePress, + handlePageSelect, + } = usePaging({ + page, + totalPages, + gotoPage: gotoHistoryPage, + }); + + const handleFilterSelect = useCallback( + (selectedFilterKey: string) => { + dispatch(setHistoryFilter({ selectedFilterKey })); + }, + [dispatch] + ); + + const handleSortPress = useCallback( + (sortKey: string) => { + dispatch(setHistorySort({ sortKey })); + }, + [dispatch] + ); + + const handleTableOptionChange = useCallback( + (payload: TableOptionsChangePayload) => { + dispatch(setHistoryTableOption(payload)); + + if (payload.pageSize) { + dispatch(gotoHistoryPage({ page: 1 })); + } + }, + [dispatch] + ); + + useEffect(() => { + if (requestCurrentPage) { + dispatch(fetchHistory()); + } else { + dispatch(gotoHistoryPage({ page: 1 })); + } + + return () => { + dispatch(clearHistory()); + }; + }, [requestCurrentPage, dispatch]); + + useEffect(() => { + const repopulate = () => { + dispatch(fetchHistory()); + }; + + registerPagePopulator(repopulate); + + return () => { + unregisterPagePopulator(repopulate); + }; + }, [dispatch]); + + return ( + + + + + + + + + + + + + + + + + {isFetchingAny && !isAllPopulated ? : null} + + {!isFetchingAny && hasError ? ( + {translate('HistoryLoadError')} + ) : null} + + { + // If history isPopulated and it's empty show no history found and don't + // wait for the movies to populate because they are never coming. + + isPopulated && !hasError && !items.length ? ( + {translate('NoHistoryFound')} + ) : null + } + + {isAllPopulated && !hasError && items.length ? ( +
+ + + {items.map((item) => { + return ( + + ); + })} + +
+ + +
+ ) : null} +
+
+ ); +} + +export default History; diff --git a/frontend/src/Activity/History/HistoryConnector.js b/frontend/src/Activity/History/HistoryConnector.js deleted file mode 100644 index 6cb5d5f7c2..0000000000 --- a/frontend/src/Activity/History/HistoryConnector.js +++ /dev/null @@ -1,141 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import withCurrentPage from 'Components/withCurrentPage'; -import * as historyActions from 'Store/Actions/historyActions'; -import { createCustomFiltersSelector } from 'Store/Selectors/createClientSideCollectionSelector'; -import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator'; -import History from './History'; - -function createMapStateToProps() { - return createSelector( - (state) => state.history, - (state) => state.movies, - createCustomFiltersSelector('history'), - (history, movies, customFilters) => { - return { - isMoviesFetching: movies.isFetching, - isMoviesPopulated: movies.isPopulated, - moviesError: movies.error, - customFilters, - ...history - }; - } - ); -} - -const mapDispatchToProps = { - ...historyActions -}; - -class HistoryConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - useCurrentPage, - fetchHistory, - gotoHistoryFirstPage - } = this.props; - - registerPagePopulator(this.repopulate); - - if (useCurrentPage) { - fetchHistory(); - } else { - gotoHistoryFirstPage(); - } - } - - componentWillUnmount() { - unregisterPagePopulator(this.repopulate); - this.props.clearHistory(); - } - - // - // Control - - repopulate = () => { - this.props.fetchHistory(); - }; - - // - // Listeners - - onFirstPagePress = () => { - this.props.gotoHistoryFirstPage(); - }; - - onPreviousPagePress = () => { - this.props.gotoHistoryPreviousPage(); - }; - - onNextPagePress = () => { - this.props.gotoHistoryNextPage(); - }; - - onLastPagePress = () => { - this.props.gotoHistoryLastPage(); - }; - - onPageSelect = (page) => { - this.props.gotoHistoryPage({ page }); - }; - - onSortPress = (sortKey) => { - this.props.setHistorySort({ sortKey }); - }; - - onFilterSelect = (selectedFilterKey) => { - this.props.setHistoryFilter({ selectedFilterKey }); - }; - - onTableOptionChange = (payload) => { - this.props.setHistoryTableOption(payload); - - if (payload.pageSize) { - this.props.gotoHistoryFirstPage(); - } - }; - - // - // Render - - render() { - return ( - - ); - } -} - -HistoryConnector.propTypes = { - useCurrentPage: PropTypes.bool.isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - fetchHistory: PropTypes.func.isRequired, - gotoHistoryFirstPage: PropTypes.func.isRequired, - gotoHistoryPreviousPage: PropTypes.func.isRequired, - gotoHistoryNextPage: PropTypes.func.isRequired, - gotoHistoryLastPage: PropTypes.func.isRequired, - gotoHistoryPage: PropTypes.func.isRequired, - setHistorySort: PropTypes.func.isRequired, - setHistoryFilter: PropTypes.func.isRequired, - setHistoryTableOption: PropTypes.func.isRequired, - clearHistory: PropTypes.func.isRequired -}; - -export default withCurrentPage( - connect(createMapStateToProps, mapDispatchToProps)(HistoryConnector) -); diff --git a/frontend/src/Activity/History/HistoryEventTypeCell.js b/frontend/src/Activity/History/HistoryEventTypeCell.tsx similarity index 56% rename from frontend/src/Activity/History/HistoryEventTypeCell.js rename to frontend/src/Activity/History/HistoryEventTypeCell.tsx index b6e003ace2..5069a8e052 100644 --- a/frontend/src/Activity/History/HistoryEventTypeCell.js +++ b/frontend/src/Activity/History/HistoryEventTypeCell.tsx @@ -1,12 +1,17 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Icon from 'Components/Icon'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import { icons, kinds } from 'Helpers/Props'; +import { + GrabbedHistoryData, + HistoryData, + HistoryEventType, + MovieFileDeletedHistory, +} from 'typings/History'; import translate from 'Utilities/String/translate'; import styles from './HistoryEventTypeCell.css'; -function getIconName(eventType, data) { +function getIconName(eventType: HistoryEventType, data: HistoryData) { switch (eventType) { case 'grabbed': return icons.DOWNLOADING; @@ -17,7 +22,9 @@ function getIconName(eventType, data) { case 'downloadFailed': return icons.DOWNLOADING; case 'movieFileDeleted': - return data.reason === 'MissingFromDisk' ? icons.FILE_MISSING : icons.DELETE; + return (data as MovieFileDeletedHistory).reason === 'MissingFromDisk' + ? icons.FILE_MISSING + : icons.DELETE; case 'movieFileRenamed': return icons.ORGANIZE; case 'downloadIgnored': @@ -27,7 +34,7 @@ function getIconName(eventType, data) { } } -function getIconKind(eventType) { +function getIconKind(eventType: HistoryEventType) { switch (eventType) { case 'downloadFailed': return kinds.DANGER; @@ -36,52 +43,47 @@ function getIconKind(eventType) { } } -function getTooltip(eventType, data) { +function getTooltip(eventType: HistoryEventType, data: HistoryData) { switch (eventType) { case 'grabbed': - return translate('MovieGrabbedHistoryTooltip', { indexer: data.indexer, downloadClient: data.downloadClient }); + return translate('MovieGrabbedTooltip', { + indexer: (data as GrabbedHistoryData).indexer, + downloadClient: (data as GrabbedHistoryData).downloadClient, + }); case 'movieFolderImported': return translate('MovieFolderImportedTooltip'); case 'downloadFolderImported': return translate('MovieImportedTooltip'); case 'downloadFailed': - return translate('MovieDownloadFailedTooltip'); + return translate('DownloadFailedMovieTooltip'); case 'movieFileDeleted': - return data.reason === 'MissingFromDisk' ? translate('MovieFileMissingTooltip') : translate('MovieFileDeletedTooltip'); + return (data as MovieFileDeletedHistory).reason === 'MissingFromDisk' + ? translate('MovieFileMissingTooltip') + : translate('MovieFileDeletedTooltip'); case 'movieFileRenamed': return translate('MovieFileRenamedTooltip'); case 'downloadIgnored': - return translate('MovieDownloadIgnoredTooltip'); + return translate('DownloadIgnoredMovieTooltip'); default: return translate('UnknownEventTooltip'); } } -function HistoryEventTypeCell({ eventType, data }) { +interface HistoryEventTypeCellProps { + eventType: HistoryEventType; + data: HistoryData; +} + +function HistoryEventTypeCell({ eventType, data }: HistoryEventTypeCellProps) { const iconName = getIconName(eventType, data); const iconKind = getIconKind(eventType); const tooltip = getTooltip(eventType, data); return ( - - + + ); } -HistoryEventTypeCell.propTypes = { - eventType: PropTypes.string.isRequired, - data: PropTypes.object -}; - -HistoryEventTypeCell.defaultProps = { - data: {} -}; - export default HistoryEventTypeCell; diff --git a/frontend/src/Activity/History/HistoryRow.js b/frontend/src/Activity/History/HistoryRow.js deleted file mode 100644 index db87740ac9..0000000000 --- a/frontend/src/Activity/History/HistoryRow.js +++ /dev/null @@ -1,277 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import IconButton from 'Components/Link/IconButton'; -import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; -import TableRowCell from 'Components/Table/Cells/TableRowCell'; -import TableRow from 'Components/Table/TableRow'; -import Tooltip from 'Components/Tooltip/Tooltip'; -import { icons, tooltipPositions } from 'Helpers/Props'; -import MovieFormats from 'Movie/MovieFormats'; -import MovieLanguages from 'Movie/MovieLanguages'; -import MovieQuality from 'Movie/MovieQuality'; -import MovieTitleLink from 'Movie/MovieTitleLink'; -import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; -import HistoryDetailsModal from './Details/HistoryDetailsModal'; -import HistoryEventTypeCell from './HistoryEventTypeCell'; -import styles from './HistoryRow.css'; - -class HistoryRow extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isDetailsModalOpen: false - }; - } - - componentDidUpdate(prevProps) { - if ( - prevProps.isMarkingAsFailed && - !this.props.isMarkingAsFailed && - !this.props.markAsFailedError - ) { - this.setState({ isDetailsModalOpen: false }); - } - } - - // - // Listeners - - onDetailsPress = () => { - this.setState({ isDetailsModalOpen: true }); - }; - - onDetailsModalClose = () => { - this.setState({ isDetailsModalOpen: false }); - }; - - // - // Render - - render() { - const { - movie, - quality, - customFormats, - customFormatScore, - languages, - qualityCutoffNotMet, - eventType, - sourceTitle, - date, - data, - downloadId, - isMarkingAsFailed, - columns, - shortDateFormat, - timeFormat, - onMarkAsFailedPress - } = this.props; - - if (!movie) { - return null; - } - - return ( - - { - columns.map((column) => { - const { - name, - isVisible - } = column; - - if (!isVisible) { - return null; - } - - if (name === 'eventType') { - return ( - - ); - } - - if (name === 'movieMetadata.sortTitle') { - return ( - - - - ); - } - - if (name === 'languages') { - return ( - - - - ); - } - - if (name === 'quality') { - return ( - - - - ); - } - - if (name === 'customFormats') { - return ( - - - - ); - } - - if (name === 'date') { - return ( - - ); - } - - if (name === 'downloadClient') { - return ( - - {data.downloadClient} - - ); - } - - if (name === 'indexer') { - return ( - - {data.indexer} - - ); - } - - if (name === 'customFormatScore') { - return ( - - } - position={tooltipPositions.BOTTOM} - /> - - ); - } - - if (name === 'releaseGroup') { - return ( - - {data.releaseGroup} - - ); - } - - if (name === 'sourceTitle') { - return ( - - {sourceTitle} - - ); - } - - if (name === 'details') { - return ( - -
- -
-
- ); - } - - return null; - }) - } - - -
- ); - } - -} - -HistoryRow.propTypes = { - movieId: PropTypes.number, - movie: PropTypes.object.isRequired, - languages: PropTypes.arrayOf(PropTypes.object).isRequired, - quality: PropTypes.object.isRequired, - customFormats: PropTypes.arrayOf(PropTypes.object), - customFormatScore: PropTypes.number.isRequired, - qualityCutoffNotMet: PropTypes.bool.isRequired, - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - date: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - isMarkingAsFailed: PropTypes.bool, - markAsFailedError: PropTypes.object, - columns: PropTypes.arrayOf(PropTypes.object).isRequired, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired -}; - -HistoryRow.defaultProps = { - customFormats: [] -}; - -export default HistoryRow; diff --git a/frontend/src/Activity/History/HistoryRow.tsx b/frontend/src/Activity/History/HistoryRow.tsx new file mode 100644 index 0000000000..45d0766b02 --- /dev/null +++ b/frontend/src/Activity/History/HistoryRow.tsx @@ -0,0 +1,224 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { useDispatch } from 'react-redux'; +import IconButton from 'Components/Link/IconButton'; +import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import Column from 'Components/Table/Column'; +import TableRow from 'Components/Table/TableRow'; +import Tooltip from 'Components/Tooltip/Tooltip'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { icons, tooltipPositions } from 'Helpers/Props'; +import Language from 'Language/Language'; +import MovieFormats from 'Movie/MovieFormats'; +import MovieLanguages from 'Movie/MovieLanguages'; +import MovieQuality from 'Movie/MovieQuality'; +import MovieTitleLink from 'Movie/MovieTitleLink'; +import useMovie from 'Movie/useMovie'; +import { QualityModel } from 'Quality/Quality'; +import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions'; +import CustomFormat from 'typings/CustomFormat'; +import { HistoryData, HistoryEventType } from 'typings/History'; +import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; +import HistoryDetailsModal from './Details/HistoryDetailsModal'; +import HistoryEventTypeCell from './HistoryEventTypeCell'; +import styles from './HistoryRow.css'; + +interface HistoryRowProps { + id: number; + movieId: number; + languages: Language[]; + quality: QualityModel; + customFormats?: CustomFormat[]; + customFormatScore: number; + qualityCutoffNotMet: boolean; + eventType: HistoryEventType; + sourceTitle: string; + date: string; + data: HistoryData; + downloadId?: string; + isMarkingAsFailed?: boolean; + markAsFailedError?: object; + columns: Column[]; +} + +function HistoryRow(props: HistoryRowProps) { + const { + id, + movieId, + languages, + quality, + customFormats = [], + customFormatScore, + qualityCutoffNotMet, + eventType, + sourceTitle, + date, + data, + downloadId, + isMarkingAsFailed = false, + markAsFailedError, + columns, + } = props; + + const wasMarkingAsFailed = usePrevious(isMarkingAsFailed); + const dispatch = useDispatch(); + const movie = useMovie(movieId); + + const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false); + + const handleDetailsPress = useCallback(() => { + setIsDetailsModalOpen(true); + }, [setIsDetailsModalOpen]); + + const handleDetailsModalClose = useCallback(() => { + setIsDetailsModalOpen(false); + }, [setIsDetailsModalOpen]); + + const handleMarkAsFailedPress = useCallback(() => { + dispatch(markAsFailed({ id })); + }, [id, dispatch]); + + useEffect(() => { + if (wasMarkingAsFailed && !isMarkingAsFailed && !markAsFailedError) { + setIsDetailsModalOpen(false); + dispatch(fetchHistory()); + } + }, [ + wasMarkingAsFailed, + isMarkingAsFailed, + markAsFailedError, + setIsDetailsModalOpen, + dispatch, + ]); + + if (!movie) { + return null; + } + + return ( + + {columns.map((column) => { + const { name, isVisible } = column; + + if (!isVisible) { + return null; + } + + if (name === 'eventType') { + return ( + + ); + } + + if (name === 'movieMetadata.sortTitle') { + return ( + + + + ); + } + + if (name === 'languages') { + return ( + + + + ); + } + + if (name === 'quality') { + return ( + + + + ); + } + + if (name === 'customFormats') { + return ( + + + + ); + } + + if (name === 'date') { + return ; + } + + if (name === 'downloadClient') { + return ( + + {'downloadClient' in data ? data.downloadClient : ''} + + ); + } + + if (name === 'indexer') { + return ( + + {'indexer' in data ? data.indexer : ''} + + ); + } + + if (name === 'customFormatScore') { + return ( + + } + position={tooltipPositions.BOTTOM} + /> + + ); + } + + if (name === 'releaseGroup') { + return ( + + {'releaseGroup' in data ? data.releaseGroup : ''} + + ); + } + + if (name === 'sourceTitle') { + return {sourceTitle}; + } + + if (name === 'details') { + return ( + + + + ); + } + + return null; + })} + + + + ); +} + +export default HistoryRow; diff --git a/frontend/src/Activity/History/HistoryRowConnector.js b/frontend/src/Activity/History/HistoryRowConnector.js deleted file mode 100644 index f3bdb404b0..0000000000 --- a/frontend/src/Activity/History/HistoryRowConnector.js +++ /dev/null @@ -1,73 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import HistoryRow from './HistoryRow'; - -function createMapStateToProps() { - return createSelector( - createMovieSelector(), - createUISettingsSelector(), - (movie, uiSettings) => { - return { - movie, - shortDateFormat: uiSettings.shortDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -const mapDispatchToProps = { - fetchHistory, - markAsFailed -}; - -class HistoryRowConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps) { - if ( - prevProps.isMarkingAsFailed && - !this.props.isMarkingAsFailed && - !this.props.markAsFailedError - ) { - this.props.fetchHistory(); - } - } - - // - // Listeners - - onMarkAsFailedPress = () => { - this.props.markAsFailed({ id: this.props.id }); - }; - - // - // Render - - render() { - return ( - - ); - } - -} - -HistoryRowConnector.propTypes = { - id: PropTypes.number.isRequired, - isMarkingAsFailed: PropTypes.bool, - markAsFailedError: PropTypes.object, - fetchHistory: PropTypes.func.isRequired, - markAsFailed: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(HistoryRowConnector); diff --git a/frontend/src/App/AppRoutes.tsx b/frontend/src/App/AppRoutes.tsx index f562083f32..e1b2d2e11f 100644 --- a/frontend/src/App/AppRoutes.tsx +++ b/frontend/src/App/AppRoutes.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Redirect, Route } from 'react-router-dom'; import Blocklist from 'Activity/Blocklist/Blocklist'; -import HistoryConnector from 'Activity/History/HistoryConnector'; +import History from 'Activity/History/History'; import Queue from 'Activity/Queue/Queue'; import AddNewMovieConnector from 'AddMovie/AddNewMovie/AddNewMovieConnector'; import ImportMovies from 'AddMovie/ImportMovie/ImportMovies'; @@ -79,7 +79,7 @@ function AppRoutes() { Activity */} - + diff --git a/frontend/src/App/State/HistoryAppState.ts b/frontend/src/App/State/HistoryAppState.ts index e368ff86ee..632b821793 100644 --- a/frontend/src/App/State/HistoryAppState.ts +++ b/frontend/src/App/State/HistoryAppState.ts @@ -1,10 +1,14 @@ import AppSectionState, { AppSectionFilterState, + PagedAppSectionState, + TableAppSectionState, } from 'App/State/AppSectionState'; import History from 'typings/History'; interface HistoryAppState extends AppSectionState, - AppSectionFilterState {} + AppSectionFilterState, + PagedAppSectionState, + TableAppSectionState {} export default HistoryAppState; diff --git a/frontend/src/Utilities/Object/selectUniqueIds.js b/frontend/src/Utilities/Object/selectUniqueIds.js deleted file mode 100644 index c2c0c17e35..0000000000 --- a/frontend/src/Utilities/Object/selectUniqueIds.js +++ /dev/null @@ -1,15 +0,0 @@ -import _ from 'lodash'; - -function selectUniqueIds(items, idProp) { - const ids = _.reduce(items, (result, item) => { - if (item[idProp]) { - result.push(item[idProp]); - } - - return result; - }, []); - - return _.uniq(ids); -} - -export default selectUniqueIds; diff --git a/frontend/src/Utilities/Object/selectUniqueIds.ts b/frontend/src/Utilities/Object/selectUniqueIds.ts new file mode 100644 index 0000000000..847613c836 --- /dev/null +++ b/frontend/src/Utilities/Object/selectUniqueIds.ts @@ -0,0 +1,13 @@ +import KeysMatching from 'typings/Helpers/KeysMatching'; + +function selectUniqueIds(items: T[], idProp: KeysMatching) { + return items.reduce((acc: K[], item) => { + if (item[idProp] && acc.indexOf(item[idProp] as K) === -1) { + acc.push(item[idProp] as K); + } + + return acc; + }, []); +} + +export default selectUniqueIds; diff --git a/frontend/src/typings/Helpers/KeysMatching.ts b/frontend/src/typings/Helpers/KeysMatching.ts index 0e20206ef2..107e0904f6 100644 --- a/frontend/src/typings/Helpers/KeysMatching.ts +++ b/frontend/src/typings/Helpers/KeysMatching.ts @@ -1,4 +1,4 @@ -type KeysMatching = { +export type KeysMatching = { [K in keyof T]-?: T[K] extends V ? K : never; }[keyof T]; diff --git a/frontend/src/typings/History.ts b/frontend/src/typings/History.ts index ee4c118421..0c43f3236b 100644 --- a/frontend/src/typings/History.ts +++ b/frontend/src/typings/History.ts @@ -11,6 +11,61 @@ export type HistoryEventType = | 'movieFileRenamed' | 'downloadIgnored'; +export interface GrabbedHistoryData { + indexer: string; + nzbInfoUrl: string; + releaseGroup: string; + age: string; + ageHours: string; + ageMinutes: string; + publishedDate: string; + downloadClient: string; + downloadClientName: string; + size: string; + downloadUrl: string; + guid: string; + tmdbId: string; + protocol: string; + customFormatScore?: string; + movieMatchType: string; + releaseSource: string; + indexerFlags: string; +} + +export interface DownloadFailedHistory { + message: string; +} + +export interface DownloadFolderImportedHistory { + customFormatScore?: string; + droppedPath: string; + importedPath: string; +} + +export interface MovieFileDeletedHistory { + customFormatScore?: string; + reason: 'Manual' | 'MissingFromDisk' | 'Upgrade'; +} + +export interface MovieFileRenamedHistory { + sourcePath: string; + sourceRelativePath: string; + path: string; + relativePath: string; +} + +export interface DownloadIgnoredHistory { + message: string; +} + +export type HistoryData = + | GrabbedHistoryData + | DownloadFailedHistory + | DownloadFolderImportedHistory + | MovieFileDeletedHistory + | MovieFileRenamedHistory + | DownloadIgnoredHistory; + export default interface History { movieId: number; sourceTitle: string; @@ -22,6 +77,6 @@ export default interface History { date: string; downloadId: string; eventType: HistoryEventType; - data: unknown; + data: HistoryData; id: number; } diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 0785c95bbd..6857dfb034 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1048,7 +1048,7 @@ "DeleteConditionMessageText": "هل أنت متأكد من أنك تريد حذف ملف تعريف الجودة {0}", "AddAutoTagError": "غير قادر على إضافة قائمة جديدة ، يرجى المحاولة مرة أخرى.", "ConditionUsingRegularExpressions": "يتطابق هذا الشرط مع استخدام التعبيرات العادية. لاحظ أن الأحرف {0} لها معاني خاصة وتحتاج إلى الهروب بعلامة {1}", - "DeletedReasonMissingFromDisk": "لم يتمكن Whisparr من العثور على الملف على القرص لذا تمت إزالته", + "DeletedReasonMovieMissingFromDisk": "لم يتمكن {appName} من العثور على الملف على القرص لذا تمت إزالته", "MovieFileDeleted": "عند حذف ملف الفيلم", "DeleteCustomFormatMessageText": "هل أنت متأكد أنك تريد حذف العلامة \"{0}\"؟", "DeleteFormatMessageText": "هل أنت متأكد أنك تريد حذف العلامة \"{0}\"؟", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index b21ba80feb..d2f71c5101 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1046,7 +1046,7 @@ "RemoveSelectedItemsQueueMessageText": "Наистина ли искате да премахнете {0} елемент {1} от опашката?", "ApplyTagsHelpTextHowToApplyMovies": "Как да приложите тагове към избраните филми", "MovieSearchResultsLoadError": "Не могат да се заредят резултати за това търсене на филм. Опитайте отново по-късно", - "DeletedReasonMissingFromDisk": "Whisparr не можа да намери файла на диска, така че той беше премахнат", + "DeletedReasonMovieMissingFromDisk": "{appName} не можа да намери файла на диска, така че той беше премахнат", "IMDbId": "Идентификатор на TMDb", "NotificationsSimplepushSettingsEvent": "Събития", "MovieIsNotMonitored": "Филмът не се следи", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index c3b99c5ae1..5e941dfdc4 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1112,7 +1112,7 @@ "ConnectionLostReconnect": "{appName} intentarà connectar-se automàticament, o podeu fer clic a recarregar.", "ConnectionLostToBackend": "{appName} ha perdut la connexió amb el backend i s'haurà de tornar a carregar per a restaurar la funcionalitat.", "DelayingDownloadUntil": "S'està retardant la baixada fins al {date} a les {time}", - "DeletedReasonMissingFromDisk": "{appName} no ha pogut trobar el fitxer al disc, de manera que el fitxer es desenllaçarà de la pel·lícula a la base de dades", + "DeletedReasonMovieMissingFromDisk": "{appName} no ha pogut trobar el fitxer al disc, de manera que el fitxer es desenllaçarà de la pel·lícula a la base de dades", "DeletedReasonUpgrade": "S'ha suprimit el fitxer per a importar una versió millorada", "HistoryLoadError": "No es pot carregar l'historial", "MovieFileDeleted": "S'ha suprimit el fitxer de pel·lícula", @@ -1200,7 +1200,7 @@ "InteractiveSearchResultsFailedErrorMessage": "La cerca ha fallat per {message}. Actualitza la informació de la pel·lícula i verifica que hi hagi la informació necessària abans de tornar a cercar.", "LogFilesLocation": "Els fitxers de registre es troben a: {location}", "ManageDownloadClients": "Gestiona els clients de descàrrega", - "MovieGrabbedHistoryTooltip": "Pel·lícula captura de {indexer} i enviada a {downloadClient}", + "MovieGrabbedTooltip": "Pel·lícula captura de {indexer} i enviada a {downloadClient}", "MovieFolderImportedTooltip": "Pel·lícula importada des de la carpeta de pel·lícules", "FullColorEvents": "Esdeveniments a tot color", "FullColorEventsHelpText": "Estil alterat per a pintar tot l'esdeveniment amb el color d'estat, en lloc de només la vora esquerra. No s'aplica a l'Agenda", @@ -1240,8 +1240,8 @@ "InfoUrl": "URL d'informació", "InvalidUILanguage": "La vostra IU està configurada en un idioma no vàlid, corregiu-lo i deseu la configuració", "ManageImportLists": "Gestiona les llistes d'importació", - "MovieDownloadFailedTooltip": "La baixada de la pel·lícula ha fallat", - "MovieDownloadIgnoredTooltip": "S'ha ignorat la pel·lícula baixada", + "DownloadFailedMovieTooltip": "La baixada de la pel·lícula ha fallat", + "DownloadIgnoredMovieTooltip": "S'ha ignorat la pel·lícula baixada", "MovieFileRenamed": "S'ha canviat el nom del fitxer de pel·lícula", "MovieImportedTooltip": "La pel·lícula s'ha baixat correctament i s'ha recollit del client de descàrrega", "EnableProfile": "Activa el perfil", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index dcf34809f8..25d3f6a20f 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1090,7 +1090,7 @@ "BlocklistReleaseHelpText": "Zabránit {appName} v opětovném sebrání tohoto vydání pomocí RSS nebo automatického vyhledávání", "CustomFormatJson": "Vlastní JSON formát", "DeleteQualityProfileMessageText": "Opravdu chcete smazat profil kvality '{name}'?", - "DeletedReasonMissingFromDisk": "{appName}u se nepodařilo najít soubor na disku, proto byl soubor odpojen od filmu v databázi", + "DeletedReasonMovieMissingFromDisk": "{appName}u se nepodařilo najít soubor na disku, proto byl soubor odpojen od filmu v databázi", "DeletedReasonUpgrade": "Soubor byl odstraněn pro import lepší verze", "DeleteSelectedMovieFilesHelpText": "Opravdu chcete smazat vybrané soubory filmů?", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Klient stahování {downloadClientName} je nastaven na odstranění dokončených stahování. To může vést k tomu, že stahování budou z klienta odstraněna dříve, než je bude moci importovat {appName}.", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 50640851cc..6b2b052f18 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1067,7 +1067,7 @@ "MovieIsNotMonitored": "Film overvåges", "DeleteReleaseProfile": "Slet forsinkelsesprofil", "DeleteReleaseProfileMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", - "DeletedReasonMissingFromDisk": "Whisparr kunne ikke finde filen på disken, så den blev fjernet", + "DeletedReasonMovieMissingFromDisk": "{appName} kunne ikke finde filen på disken, så den blev fjernet", "ReleaseProfilesLoadError": "Kunne ikke indlæse forsinkelsesprofiler", "SearchOnAddCollectionHelpText": "Søg efter film på denne liste, når du føjes til {appName}", "EditConnectionImplementation": "Tilføj forbindelse - {implementationName}", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 277d0098e6..b95e08feea 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1443,7 +1443,7 @@ "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", "DownloadClientDelugeSettingsDirectoryHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", "ListQualityProfileHelpText": "Qualitätsprofil mit dem Listemelemente hinzugefügt werden sollen", - "DeletedReasonMissingFromDisk": "{appName} konnte die Datei auf der Festplatte nicht finden, daher wurde die Verknüpfung der Datei mit der Episode in der Datenbank aufgehoben", + "DeletedReasonMovieMissingFromDisk": "{appName} konnte die Datei auf der Festplatte nicht finden, daher wurde die Verknüpfung der Datei mit der Episode in der Datenbank aufgehoben", "ReleaseProfileTagMovieHelpText": "Veröffentlichungsprofile gelten für Künstler mit mindestens einem passenden Tag. Leer lassen, damit es für alle Künstler gilt", "SearchForAllMissingMoviesConfirmationCount": "Bist du dir sicher, dass du nach allen '{0}' fehlenden Alben suchen willst?", "SearchForCutoffUnmetMovies": "Suche nach allen abgeschnittenen unerfüllten Büchern", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 045412a6fe..d94c7426c8 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1192,7 +1192,7 @@ "ConditionUsingRegularExpressions": "Αυτή η συνθήκη ταιριάζει με τη χρήση τυπικών εκφράσεων. Λάβετε υπόψη ότι οι χαρακτήρες {0} έχουν ειδικές έννοιες και χρειάζονται διαφυγή με {1}", "DeleteSpecificationHelpText": "Είστε σίγουροι πως θέλετε να διαγράψετε τη συνθήκη '{name}';", "ApplyTagsHelpTextHowToApplyMovies": "Πώς να εφαρμόσετε ετικέτες στις επιλεγμένες ταινίες", - "DeletedReasonMissingFromDisk": "Ο Whisparr δεν μπόρεσε να βρει το αρχείο στο δίσκο και έτσι καταργήθηκε", + "DeletedReasonMovieMissingFromDisk": "Ο {appName} δεν μπόρεσε να βρει το αρχείο στο δίσκο και έτσι καταργήθηκε", "ReleaseProfileTagMovieHelpText": "Τα προφίλ κυκλοφορίας θα ισχύουν για καλλιτέχνες με τουλάχιστον μία αντίστοιχη ετικέτα. Αφήστε το κενό για να εφαρμοστεί σε όλους τους καλλιτέχνες", "DownloadClientSettingsRecentPriority": "Προτεραιότητα πελάτη", "MovieIsNotMonitored": "Η ταινία παρακολουθείται", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 11b64845a5..780d954e52 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -365,7 +365,7 @@ "Deleted": "Deleted", "DeletedMovieDescription": "Movie was deleted from TMDb", "DeletedReasonManual": "File was deleted using {appName}, either manually or by another tool through the API", - "DeletedReasonMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the movie in the database", + "DeletedReasonMovieMissingFromDisk": "{appName} was unable to find the file on disk so the file was unlinked from the movie in the database", "DeletedReasonUpgrade": "File was deleted to import an upgrade", "Destination": "Destination", "DestinationPath": "Destination Path", @@ -541,7 +541,9 @@ "DownloadClientsLoadError": "Unable to load download clients", "DownloadClientsSettingsSummary": "Download clients, download handling and remote path mappings", "DownloadFailed": "Download failed", + "DownloadFailedMovieTooltip": "Movie download failed", "DownloadIgnored": "Download Ignored", + "DownloadIgnoredMovieTooltip": "Movie Download Ignored", "DownloadPropersAndRepacks": "Propers and Repacks", "DownloadPropersAndRepacksHelpText": "Whether or not to automatically upgrade to Propers/Repacks", "DownloadPropersAndRepacksHelpTextCustomFormat": "Use 'Do not Prefer' to sort by custom format score over Propers/Repacks", @@ -962,8 +964,6 @@ "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Missing root folder for movie collection: {rootFolderInfo}", "MovieDetailsNextMovie": "Movie Details: Next Movie", "MovieDetailsPreviousMovie": "Movie Details: Previous Movie", - "MovieDownloadFailedTooltip": "Movie download failed", - "MovieDownloadIgnoredTooltip": "Movie Download Ignored", "MovieDownloaded": "Movie Downloaded", "MovieEditor": "Movie Editor", "MovieExcludedFromAutomaticAdd": "Movie Excluded From Automatic Add", @@ -978,7 +978,7 @@ "MovieFolderFormatHelpText": "Used when adding a new movie or moving movies via the movie editor", "MovieFolderImportedTooltip": "Movie imported from movie folder", "MovieFootNote": "Optionally control truncation to a maximum number of bytes including ellipsis (`...`). Truncating from the end (e.g. `{Movie Title:30}`) or the beginning (e.g. `{Movie Title:-30}`) are both supported.", - "MovieGrabbedHistoryTooltip": "Movie grabbed from {indexer} and sent to {downloadClient}", + "MovieGrabbedTooltip": "Movie grabbed from {indexer} and sent to {downloadClient}", "MovieID": "Movie ID", "MovieImported": "Movie Imported", "MovieImportedTooltip": "Movie downloaded successfully and picked up from download client", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index dc93d55824..6ec6b0cc0d 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1157,7 +1157,7 @@ "DeleteSelectedIndexersMessageText": "¿Estás seguro que quieres eliminar {count} indexador(es) seleccionado(s)?", "DisabledForLocalAddresses": "Deshabilitada para direcciones locales", "DeletedReasonManual": "El archivo fue eliminado usando {appName}, o bien manualmente o por otra herramienta a través de la API", - "DeletedReasonMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos", + "DeletedReasonMovieMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos", "DeletedReasonUpgrade": "Se ha borrado el archivo para importar una versión mejorada", "DeleteSelectedMovieFilesHelpText": "¿Está seguro de que desea eliminar los archivos de película seleccionados?", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña", @@ -1222,13 +1222,13 @@ "MovieFileRenamedTooltip": "Archivo de película renombrado", "MovieFolderImportedTooltip": "Película importada de la carpeta de películas", "InteractiveSearchModalHeader": "Búsqueda interactiva", - "MovieDownloadIgnoredTooltip": "Descarga de la película ignorada", - "MovieDownloadFailedTooltip": "No se ha podido descargar la película", + "DownloadIgnoredMovieTooltip": "Descarga de la película ignorada", + "DownloadFailedMovieTooltip": "No se ha podido descargar la película", "MovieFileDeletedTooltip": "Archivo de película eliminado", "MovieFileRenamed": "Archivo de película renombrado", "LanguagesLoadError": "No es posible cargar los idiomas", "DownloadClientQbittorrentSettingsContentLayout": "Diseño del contenido", - "MovieGrabbedHistoryTooltip": "Película capturada de {indexer} y enviada a {downloadClient}", + "MovieGrabbedTooltip": "Película capturada de {indexer} y enviada a {downloadClient}", "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Si usar el diseño de contenido configurado de qBittorrent, el diseño original del torrent o siempre crear una subcarpeta (qBittorrent 4.3.2+)", "MovieImported": "Película importada", "MovieImportedTooltip": "Película descargada correctamente y obtenida del cliente de descargas", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 28d917e9bb..40af8f982f 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1216,7 +1216,7 @@ "DeletedReasonManual": "Tiedosto poistettiin käyttöliittymän kautta", "DeletedReasonUpgrade": "Tiedosto poistettiin päivitetyn version tuomiseksi", "InteractiveImportNoMovie": "Elokuva on valittava jokaiselle valitulle tiedostolle.", - "MovieGrabbedHistoryTooltip": "Elokuva kaapattiin lähteestä {indexer} ja välitettiin lataajalle {downloadClient}", + "MovieGrabbedTooltip": "Elokuva kaapattiin lähteestä {indexer} ja välitettiin lataajalle {downloadClient}", "CloneCondition": "Monista ehto", "AutomaticAdd": "Automaattinen lisäys", "AutoTagging": "Automaattinen tunnistemerkintä", @@ -1245,7 +1245,7 @@ "InteractiveImportNoFilesFound": "Valitusta kansiosta ei löytynyt videotiedostoja.", "ManualGrab": "Manuaalinen kaappaus", "Complete": "Kokonaiset", - "DeletedReasonMissingFromDisk": "{appName} ei löytänyt tiedostoa levyltä, joten sen kytkös kirjaston elokuvaan poistettiin.", + "DeletedReasonMovieMissingFromDisk": "{appName} ei löytänyt tiedostoa levyltä, joten sen kytkös kirjaston elokuvaan poistettiin.", "ShowImdbRatingHelpText": "Näytä IMDb-arvio julisteen alla.", "ShowRottenTomatoesRating": "Näytä Tomato-arvio", "ShowRottenTomatoesRatingHelpText": "Näytä Tomato-arvio julisteen alla.", @@ -1415,7 +1415,7 @@ "CustomFormatsSpecificationRegularExpression": "Säännöllinen lauseke", "False": "Epätosi", "CustomFormatsSpecificationRegularExpressionHelpText": "Mukautetun muodon säännöllisen lausekkeen kirjainkokoa ei huomioida.", - "MovieDownloadIgnoredTooltip": "Elokuvalataus ohitettiin", + "DownloadIgnoredMovieTooltip": "Elokuvalataus ohitettiin", "MovieFolderImportedTooltip": "Elokuva tuotiin elokuvakansiosta", "True": "Tosi", "SkipRedownloadHelpText": "Estää {appName}ia lataamasta kohteelle vaihtoehtoista julkaisua.", @@ -1460,7 +1460,7 @@ "NotificationsValidationUnableToConnectToService": "Palvelua {serviceName} ei tavoiteta.", "NotificationsValidationUnableToSendTestMessage": "Testiviestin lähetys ei onnistu: {exceptionMessage}", "NotificationsEmailSettingsUseEncryptionHelpText": "Määrittää suositaanko salausta, jos se on määritetty palvelimelle, käytetäänkö aina SSL- (vain portti 465) tai StartTLS-salausta (kaikki muut portit), voi käytetäänkö salausta lainkaan.", - "MovieDownloadFailedTooltip": "Elokuvan lataus epäonnistui", + "DownloadFailedMovieTooltip": "Elokuvan lataus epäonnistui", "MovieFileDeleted": "Elokuvatiedosto poistettiin", "MovieFileDeletedTooltip": "Elokuvatiedosto poistettiin", "ThereWasAnErrorLoadingThisItem": "Virhe ladattaessa kohdetta", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index f213488467..e2247da147 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1216,7 +1216,7 @@ "AutoTaggingLoadError": "Impossible de charger le marquage automatique", "DelayingDownloadUntil": "Retarder le téléchargement jusqu'au {date} à {time}", "DeleteSelectedMovieFilesHelpText": "Voulez-vous vraiment supprimer les fichiers vidéo sélectionnés ?", - "DeletedReasonMissingFromDisk": "{appName} n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de données", + "DeletedReasonMovieMissingFromDisk": "{appName} n'a pas pu trouver le fichier sur le disque, il a donc été supprimé dans la base de données", "DeletedReasonUpgrade": "Le fichier a été supprimé pour importer une mise à niveau", "OrganizeLoadError": "Erreur lors du chargement des aperçus", "EditImportListImplementation": "Modifier la liste d'importation - {implementationName}", @@ -1285,7 +1285,7 @@ "MovieFileRenamed": "Fichier vidéo renommé", "MovieFileRenamedTooltip": "Fichier vidéo renommé", "MovieFolderImportedTooltip": "Film importé du dossier de film", - "MovieGrabbedHistoryTooltip": "Film récupéré de {indexer} et envoyé à {downloadClient}", + "MovieGrabbedTooltip": "Film récupéré de {indexer} et envoyé à {downloadClient}", "RemoveQueueItem": "Retirer - {sourceTitle}", "OverrideGrabModalTitle": "Remplacer et récupérer - {title}", "RemoveTagsAutomaticallyHelpText": "Supprimez automatiquement les étiquettes si les conditions ne sont pas remplies", @@ -1296,8 +1296,8 @@ "SetReleaseGroupModalTitle": "{modalTitle} – Définir le groupe de versions", "CountImportListsSelected": "{count} liste(s) d'importation sélectionnée(s)", "InteractiveSearchResultsFailedErrorMessage": "La recherche a échoué car il s'agit d'un {message}. Essayez d'actualiser les informations sur le film et vérifiez que les informations nécessaires sont présentes avant de lancer une nouvelle recherche.", - "MovieDownloadFailedTooltip": "Le téléchargement du film a échoué", - "MovieDownloadIgnoredTooltip": "Téléchargement de film ignoré", + "DownloadFailedMovieTooltip": "Le téléchargement du film a échoué", + "DownloadIgnoredMovieTooltip": "Téléchargement de film ignoré", "SkipRedownloadHelpText": "Empêche {appName} d'essayer de télécharger une version alternative pour cet élément", "QueueFilterHasNoItems": "Le filtre de file d'attente sélectionné ne contient aucun élément", "EnableProfile": "Activer profil", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index a4a7fadc68..cbafc41604 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1100,7 +1100,7 @@ "NotificationsSimplepushSettingsEvent": "אירועים", "RemotePathMappingCheckFilesLocalWrongOSPath": "אתה משתמש בדוקר; קליינט ההורדות {downloadClientName} שם הורדות ב-{path} אבל הנתיב לא תקין {osName}. בחן מחדש את ניתוב התיקיות והגדרות קליינט ההורדות.", "RemotePathMappingCheckLocalWrongOSPath": "אתה משתמש בדוקר; קליינט ההורדות {downloadClientName} שם הורדות ב-{path} אבל הנתיב לא תקין {osName}. בחן מחדש את ניתוב התיקיות והגדרות קליינט ההורדות.", - "DeletedReasonMissingFromDisk": "Whisparr לא הצליח למצוא את הקובץ בדיסק ולכן הוא הוסר", + "DeletedReasonMovieMissingFromDisk": "{appName} לא הצליח למצוא את הקובץ בדיסק ולכן הוא הוסר", "AddDelayProfileError": "לא ניתן להוסיף פרופיל איכות חדש, נסה שוב.", "MovieFileDeletedTooltip": "במחיקת קובץ הסרט", "DeleteMovieFolders": "מחק את תיקיית הסרטים", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 59dbbb88ed..7a23076ba9 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1047,7 +1047,7 @@ "MovieIsNotMonitored": "मूवी अनमनी है", "DownloadClientSettingsRecentPriority": "ग्राहक प्राथमिकता", "DeleteSelectedMovieFilesHelpText": "क्या आप वाकई चयनित मूवी फ़ाइलों को हटाना चाहते हैं?", - "DeletedReasonMissingFromDisk": "Whisparr डिस्क पर फ़ाइल खोजने में असमर्थ था इसलिए इसे हटा दिया गया था", + "DeletedReasonMovieMissingFromDisk": "{appName} डिस्क पर फ़ाइल खोजने में असमर्थ था इसलिए इसे हटा दिया गया था", "MovieFileDeleted": "मूवी फ़ाइल डिलीट पर", "DeleteCustomFormatMessageText": "क्या आप वाकई '{0}' टैग हटाना चाहते हैं?", "DeleteFormatMessageText": "क्या आप वाकई '{0}' टैग हटाना चाहते हैं?", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index c0205eddd2..3ff81d5506 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1151,7 +1151,7 @@ "DeleteAutoTag": "Automatikus címke törlése", "DeleteSelectedDownloadClients": "Letöltési kliens(ek) törlése", "DeleteSelectedIndexersMessageText": "Biztosan törölni szeretne {count} kiválasztott indexelőt?", - "DeletedReasonMissingFromDisk": "A(z) {appName} nem találta a fájlt a lemezen, ezért a fájlt leválasztották a filmről az adatbázisban", + "DeletedReasonMovieMissingFromDisk": "A(z) {appName} nem találta a fájlt a lemezen, ezért a fájlt leválasztották a filmről az adatbázisban", "EditIndexerImplementation": "Indexelő szerkesztése – {implementationName}", "FailedToFetchUpdates": "Nem sikerült lekérni a frissítéseket", "FormatAgeDay": "nap", @@ -1418,7 +1418,7 @@ "DownloadClientSettingsOlderPriorityMovieHelpText": "Elsőbbség a 14 nappal ezelőtt sugárzott epizódok megragadásánál", "MovieImportedTooltip": "Az epizód letöltése sikeresen megtörtént, és a letöltés kliensből lett letöltve", "SearchForCutoffUnmetMoviesConfirmationCount": "Biztosan megkeresi az összes {totalRecords} hiányzó epizódot?", - "MovieGrabbedHistoryTooltip": "Az epizódot letöltötte a(z) {indexer} és elküldte a(z) {downloadClient} számára", + "MovieGrabbedTooltip": "Az epizódot letöltötte a(z) {indexer} és elküldte a(z) {downloadClient} számára", "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Választható hely a letöltések elhelyezéséhez, hagyja üresen az alapértelmezett Aria2 hely használatához", "DownloadClientDelugeSettingsDirectoryHelpText": "Választható hely a letöltések elhelyezéséhez, hagyja üresen az alapértelmezett Aria2 hely használatához", "MovieFileDeletedTooltip": "A filmfájl törléséhez", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 3612f442c3..f8c008fbfc 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1055,7 +1055,7 @@ "NotificationsSimplepushSettingsEvent": "Viðburðir", "DeleteSelectedMovieFilesHelpText": "Ertu viss um að þú viljir eyða völdum kvikmyndaskrám?", "AutoRedownloadFailed": "Niðurhal mistókst", - "DeletedReasonMissingFromDisk": "Whisparr gat ekki fundið skrána á disknum svo hún var fjarlægð", + "DeletedReasonMovieMissingFromDisk": "{appName} gat ekki fundið skrána á disknum svo hún var fjarlægð", "DownloadClientSettingsRecentPriority": "Forgangur viðskiptavinar", "AddDelayProfileError": "Ekki er hægt að bæta við nýjum gæðaprófíl, reyndu aftur.", "MovieFileDeletedTooltip": "Á Eyða kvikmyndaskrá", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 351f801f3f..f862ea1b06 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1162,7 +1162,7 @@ "ReleaseProfilesLoadError": "Non riesco a caricare i profili di ritardo", "ReleaseGroups": "Gruppo Release", "DeleteReleaseProfileMessageText": "Sicuro di voler cancellare il profilo di qualità {0}", - "DeletedReasonMissingFromDisk": "Whisparr non è riuscito a trovare il file sul disco, quindi è stato rimosso", + "DeletedReasonMovieMissingFromDisk": "{appName} non è riuscito a trovare il file sul disco, quindi è stato rimosso", "DeleteQualityProfileMessageText": "Sicuro di voler cancellare il profilo di qualità '{name}'?", "RemotePathMappingCheckFilesLocalWrongOSPath": "Stai utilizzando docker; Il client di download {downloadClientName} riporta files in {path} ma questo non è un percorso valido {osName}. Controlla la mappa dei percorsi remoti e le impostazioni del client di download.", "AutoTaggingNegateHelpText": "Se selezionato, il formato personalizzato non verrà applicato a questa {0} condizione.", @@ -1231,7 +1231,7 @@ "ManageIndexers": "Gestisci Indicizzatori", "ManageLists": "Gestisci Liste", "Menu": "Menu", - "MovieDownloadFailedTooltip": "Download del film fallito", + "DownloadFailedMovieTooltip": "Download del film fallito", "Never": "Mai", "NotificationsSettingsWebhookMethod": "Metodo", "NotificationsTraktSettingsAuthenticateWithTrakt": "Autentica con Trakt", @@ -1284,7 +1284,7 @@ "Letterboxd": "Letterboxd", "MissingLoadError": "Errore caricando elementi mancanti", "MonitorCollection": "Monitora Collezione", - "MovieDownloadIgnoredTooltip": "Download del Film Ignorato", + "DownloadIgnoredMovieTooltip": "Download del Film Ignorato", "MovieIsNotAvailable": "Film non disponibile", "MovieIsPopular": "Film Popolare su TMDb", "MovieIsTrending": "Film in Tendenza su TMDb", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 11a91f95b6..a413424a4c 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1049,7 +1049,7 @@ "MovieFileDeleted": "ムービーファイルの削除について", "SearchOnAddCollectionHelpText": "{appName}に追加されたら、このリストで映画を検索します", "MovieIsNotMonitored": "映画は監視されていません", - "DeletedReasonMissingFromDisk": "Whisparrはディスク上でファイルを見つけることができなかったため、削除されました", + "DeletedReasonMovieMissingFromDisk": "{appName}はディスク上でファイルを見つけることができなかったため、削除されました", "IMDbId": "TMDbID", "DeleteSelectedMovieFilesHelpText": "選択したムービーファイルを削除してもよろしいですか?", "NotificationsSimplepushSettingsEvent": "イベント", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index a49428160e..b59b275f54 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1039,7 +1039,7 @@ "RemoveSelectedBlocklistMessageText": "블랙리스트에서 선택한 항목을 제거 하시겠습니까?", "Yes": "예", "ApplyTagsHelpTextHowToApplyMovies": "선택한 동영상에 태그를 적용하는 방법", - "DeletedReasonMissingFromDisk": "Whisparr가 디스크에서 파일을 찾을 수 없어 제거되었습니다.", + "DeletedReasonMovieMissingFromDisk": "{appName}가 디스크에서 파일을 찾을 수 없어 제거되었습니다.", "ShowUnknownMovieItemsHelpText": "대기열에 영화가없는 항목을 표시합니다. 여기에는 제거 된 영화 또는 {appName} 카테고리의 다른 항목이 포함될 수 있습니다.", "DeleteSelectedMovieFilesHelpText": "선택한 동영상 파일을 삭제 하시겠습니까?", "DownloadClientSettingsRecentPriority": "클라이언트 우선 순위", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 8f8be5abc0..8b9ed71a98 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1185,7 +1185,7 @@ "FormatAgeMinute": "minuten", "EditConnectionImplementation": "Voeg connectie toe - {implementationName}", "FormatAgeHour": "Uren", - "DeletedReasonMissingFromDisk": "Whisparr kon het bestand niet vinden op de schijf dus werd het verwijderd", + "DeletedReasonMovieMissingFromDisk": "{appName} kon het bestand niet vinden op de schijf dus werd het verwijderd", "DeleteReleaseProfile": "Verwijder Vertragingsprofiel", "DeleteReleaseProfileMessageText": "Bent u zeker dat u het kwaliteitsprofiel {0} wilt verwijderen", "DownloadClientSettingsRecentPriority": "Client Prioriteit", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index db21bc245e..0fb3b07c9d 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1151,7 +1151,7 @@ "MovieSearchResultsLoadError": "Nie można załadować wyników dla tego wyszukiwania filmów. Spróbuj ponownie później", "ShowUnknownMovieItemsHelpText": "Pokaż elementy bez filmu w kolejce. Może to obejmować usunięte filmy lub cokolwiek innego w kategorii Lidarr", "EditConnectionImplementation": "Dodaj Connection - {implementationName}", - "DeletedReasonMissingFromDisk": "Whisparr nie mógł znaleźć pliku na dysku, więc został usunięty", + "DeletedReasonMovieMissingFromDisk": "{appName} nie mógł znaleźć pliku na dysku, więc został usunięty", "DeleteSelectedMovieFilesHelpText": "Czy na pewno chcesz usunąć wybrane pliki filmowe?", "IMDbId": "Identyfikator TMDb", "AddDelayProfileError": "Nie można dodać nowego profilu opóźnienia, spróbuj później.", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 45a6b3c6d4..f3f5601c38 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1135,7 +1135,7 @@ "DeleteSelectedImportListsMessageText": "Tem a certeza de que pretende eliminar a(s) lista(s) de {count} importação selecionada(s)?", "DeleteSelectedMovieFilesHelpText": "Tem a certeza de que pretende apagar os ficheiros de filmes seleccionados?", "DeletedReasonManual": "O ficheiro foi eliminado através da IU", - "DeletedReasonMissingFromDisk": "O {appName} não conseguiu encontrar o ficheiro no disco, pelo que o ficheiro foi desvinculado do filme na base de dados", + "DeletedReasonMovieMissingFromDisk": "O {appName} não conseguiu encontrar o ficheiro no disco, pelo que o ficheiro foi desvinculado do filme na base de dados", "DeletedReasonUpgrade": "O ficheiro foi eliminado para importar uma atualização", "DisabledForLocalAddresses": "Desativado para Endereços Locais", "DownloadClientsLoadError": "Não foi possível carregar os clientes de transferências", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 738e63e252..0cf261fb9f 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1238,8 +1238,8 @@ "UnknownEventTooltip": "Evento desconhecido", "DeletedReasonManual": "O arquivo foi excluído usando {appName} manualmente ou por outra ferramenta por meio da API", "FormatAgeDay": "dia", - "MovieDownloadFailedTooltip": "Falha no download do filme", - "MovieDownloadIgnoredTooltip": "Download do Filme Ignorado", + "DownloadFailedMovieTooltip": "Falha no download do filme", + "DownloadIgnoredMovieTooltip": "Download do Filme Ignorado", "NoHistoryFound": "Nenhum histórico encontrado", "QueueLoadError": "Falha ao carregar a fila", "BlocklistLoadError": "Não foi possível carregar a lista de bloqueio", @@ -1252,7 +1252,7 @@ "HistoryLoadError": "Não foi possível carregar o histórico", "InfoUrl": "URL da info", "MovieImported": "Filme Importado", - "MovieGrabbedHistoryTooltip": "Filme obtido de {indexer} e enviado para {downloadClient}", + "MovieGrabbedTooltip": "Filme obtido de {indexer} e enviado para {downloadClient}", "MovieImportedTooltip": "Filme baixado com sucesso e obtido no cliente de download", "PendingDownloadClientUnavailable": "Pendente - O cliente de download não está disponível", "FormatAgeDays": "dias", @@ -1279,7 +1279,7 @@ "TablePageSize": "Tamanho da Página", "TablePageSizeHelpText": "Número de itens a serem exibidos em cada página", "TablePageSizeMinimum": "O tamanho da página precisa ser de pelo menos {minimumValue}", - "DeletedReasonMissingFromDisk": "O {appName} não conseguiu encontrar o arquivo no disco, então o arquivo foi desvinculado do filme no banco de dados", + "DeletedReasonMovieMissingFromDisk": "O {appName} não conseguiu encontrar o arquivo no disco, então o arquivo foi desvinculado do filme no banco de dados", "FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}", "RemoveSelectedBlocklistMessageText": "Tem certeza de que deseja remover os itens selecionados da lista de bloqueio?", "ShowUnknownMovieItemsHelpText": "Mostrar itens sem filme na fila. Isso pode incluir filmes removidos ou qualquer outra coisa na categoria do {appName}", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 7cf726c00f..0ac903daaf 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1035,14 +1035,14 @@ "MovieFileRenamed": "Fișier de film redenumit", "MovieFileDeletedTooltip": "Fișier de film șters", "MovieFileDeleted": "Fișier de film șters", - "MovieDownloadIgnoredTooltip": "Descărcare film ignorată", + "DownloadIgnoredMovieTooltip": "Descărcare film ignorată", "MovieImported": "Film importat", - "MovieGrabbedHistoryTooltip": "Film preluat de la {indexer} și trimis către {downloadClient}", + "MovieGrabbedTooltip": "Film preluat de la {indexer} și trimis către {downloadClient}", "FormatAgeMinutes": "minute", "UnknownEventTooltip": "Eveniment necunoscut", "TablePageSize": "Mărimea Paginii", "MovieFileRenamedTooltip": "Fișier de film redenumit", - "MovieDownloadFailedTooltip": "Descărcarea filmului a eșuat", + "DownloadFailedMovieTooltip": "Descărcarea filmului a eșuat", "FullColorEvents": "Evenimente pline de culoare", "BlocklistReleaseHelpText": "Împiedică {appName} să apuce automat această versiune din nou", "BlocklistLoadError": "Imposibil de încărcat lista neagră", @@ -1070,7 +1070,7 @@ "ReleaseProfilesLoadError": "Nu se pot încărca profilurile", "PendingDownloadClientUnavailable": "În așteptare - Clientul de descărcare nu este disponibil", "MovieImportedTooltip": "Filmul a fost descărcat cu succes și preluat de la clientul de descărcare", - "DeletedReasonMissingFromDisk": "{appName} nu a putut găsi fișierul de pe disc, așa că a fost eliminat", + "DeletedReasonMovieMissingFromDisk": "{appName} nu a putut găsi fișierul de pe disc, așa că a fost eliminat", "AddConnection": "Adăugați conexiune", "AddConnectionImplementation": "Adăugați conexiune - {implementationName}", "AddDownloadClientImplementation": "Adăugați client de descărcare - {implementationName}", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index d99970ddc8..36e08a3232 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1263,7 +1263,7 @@ "Label": "Метка", "DelayProfileMovieTagsHelpText": "Применимо к фильмам с хотя бы одним подходящим тегом", "Release": "Релиз", - "DeletedReasonMissingFromDisk": "{appName} не смог найти файл на диске, поэтому файл был откреплён от фильма в базе данных", + "DeletedReasonMovieMissingFromDisk": "{appName} не смог найти файл на диске, поэтому файл был откреплён от фильма в базе данных", "MovieIsNotMonitored": "Фильм не отслеживается", "MovieFileDeleted": "При удалении файла фильма", "DeleteReleaseProfile": "Удалить профиль релиза", @@ -1641,7 +1641,7 @@ "EditionFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Series Title:30}`), так и с начала (например, `{Series Title:-30}`).", "NotificationsCustomScriptValidationFileDoesNotExist": "Файл не существует", "NotificationsGotifySettingsServerHelpText": "URL-адрес сервера Gotify, включая http(s):// и порт, если необходимо", - "MovieGrabbedHistoryTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", + "MovieGrabbedTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", "NotificationsPlexValidationNoMovieLibraryFound": "Требуется хотя бы одна библиотека c сериалами", "SearchForAllMissingMovies": "Искать все недостающие эпизоды", "SearchForAllMissingMoviesConfirmationCount": "Вы уверены, что хотите найти все ({totalRecords}) недостающие эпизоды ?", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 7eeee1d32d..83dcf6ff35 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1069,7 +1069,7 @@ "ConditionUsingRegularExpressions": "Detta villkor matchar användningen av reguljära uttryck. Observera att tecknen {0} har speciella betydelser och behöver fly med ett {1}", "MovieFileDeleted": "På filmfil Ta bort", "DeleteCustomFormatMessageText": "Är du säker på att du vill radera taggen '{0}'?", - "DeletedReasonMissingFromDisk": "Whisparr kunde inte hitta filen på disken så den togs bort", + "DeletedReasonMovieMissingFromDisk": "{appName} kunde inte hitta filen på disken så den togs bort", "DeleteSelectedMovieFilesHelpText": "Är du säker på att du vill radera de markerade filmfilerna?", "MovieIsNotMonitored": "FIlmen är bevakad", "SearchForAllMissingMovies": "Sök efter alla saknade böcker", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 9dc48eb81b..5a5037e074 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1052,7 +1052,7 @@ "IMDbId": "รหัส TMDb", "MovieFileDeleted": "บน Movie File Delete", "AddDelayProfileError": "ไม่สามารถเพิ่มโปรไฟล์คุณภาพใหม่ได้โปรดลองอีกครั้ง", - "DeletedReasonMissingFromDisk": "Whisparr ไม่พบไฟล์บนดิสก์ดังนั้นจึงถูกลบออก", + "DeletedReasonMovieMissingFromDisk": "{appName} ไม่พบไฟล์บนดิสก์ดังนั้นจึงถูกลบออก", "DownloadClientSettingsRecentPriority": "ลำดับความสำคัญของลูกค้า", "DeleteSelectedMovieFilesHelpText": "แน่ใจไหมว่าต้องการลบไฟล์ภาพยนตร์ที่เลือก", "ShowUnknownMovieItemsHelpText": "แสดงรายการที่ไม่มีภาพยนตร์อยู่ในคิว ซึ่งอาจรวมถึงภาพยนตร์ที่ถูกนำออกหรือสิ่งอื่นใดในหมวดหมู่ของ Lidarr", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 99214201a7..7c570a3658 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1114,7 +1114,7 @@ "DeleteRootFolderMessageText": "'{path}' kök klasörünü silmek istediğinizden emin misiniz?", "DeleteSelectedIndexersMessageText": "Seçilen {count} dizinleyiciyi silmek istediğinizden emin misiniz?", "Destination": "Hedef", - "DeletedReasonMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı", + "DeletedReasonMovieMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı", "DownloadClientDelugeTorrentStateError": "Deluge bir hata bildiriyor", "DownloadClientDelugeValidationLabelPluginInactive": "Etiket eklentisi etkinleştirilmedi", "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.", @@ -1287,8 +1287,8 @@ "ListRefreshInterval": "Liste Yenileme Aralığı", "InteractiveImportNoImportMode": "Bir içe aktarma modu seçilmelidir", "MonitorCollection": "Takip Etme Koleksiyonu", - "MovieDownloadFailedTooltip": "Film indirilemedi", - "MovieDownloadIgnoredTooltip": "Film İndirme Yoksayıldı", + "DownloadFailedMovieTooltip": "Film indirilemedi", + "DownloadIgnoredMovieTooltip": "Film İndirme Yoksayıldı", "NotificationsAppriseSettingsServerUrlHelpText": "Gerekiyorsa http(s):// ve bağlantı noktasını içeren Apprise sunucu URL'si", "NotificationsAppriseSettingsTags": "Apprise Etiketler", "NotificationsEmailSettingsUseEncryption": "Şifreleme Kullan", @@ -1341,7 +1341,7 @@ "IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip dizinleyiciler: {indexerNames}.", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Film koleksiyonu için eksik kök klasör: {rootFolderInfo}", "NoImportListsFound": "İçe aktarma listesi bulunamadı", - "MovieGrabbedHistoryTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", + "MovieGrabbedTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", "NotificationStatusAllClientHealthCheckMessage": "Arızalar nedeniyle tüm bildirimler kullanılamıyor", "FormatAgeHour": "saat", "GrabId": "ID'den Yakala", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index d8d57eeced..3882323ae0 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1103,7 +1103,7 @@ "AddConnection": "Додати Підключення", "TablePageSizeHelpText": "Кількість елементів для показу на кожній сторінці", "ConnectionLostToBackend": "{appName} втратив з’єднання з серверною частиною, і його потрібно перезавантажити, щоб відновити роботу.", - "DeletedReasonMissingFromDisk": "{appName} не зміг знайти файл на диску, тому файл було від’єднано від фільму в базі даних", + "DeletedReasonMovieMissingFromDisk": "{appName} не зміг знайти файл на диску, тому файл було від’єднано від фільму в базі даних", "FormatAgeHours": "Години", "FormatAgeMinute": "Хвилин", "FormatAgeMinutes": "Хвилин", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 418da4ad0a..6b074ca785 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1046,7 +1046,7 @@ "DeleteSelectedMovieFilesHelpText": "Bạn có chắc chắn muốn xóa các tệp phim đã chọn không?", "DeleteCustomFormatMessageText": "Bạn có chắc chắn muốn xóa thẻ '{0}' không?", "DeleteQualityProfileMessageText": "Bạn có chắc chắn muốn xóa cấu hình chất lượng không {0}", - "DeletedReasonMissingFromDisk": "Whisparr không thể tìm thấy tệp trên đĩa nên nó đã bị xóa", + "DeletedReasonMovieMissingFromDisk": "{appName} không thể tìm thấy tệp trên đĩa nên nó đã bị xóa", "MovieIsNotMonitored": "Phim không được giám sát", "SearchOnAddCollectionHelpText": "Tìm kiếm phim trong danh sách này khi được thêm vào {appName}", "DeleteFormatMessageText": "Bạn có chắc chắn muốn xóa thẻ '{0}' không?", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 362a0d29c0..1424c60aab 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1205,8 +1205,8 @@ "InfoUrl": "信息 URL", "InvalidUILanguage": "您的UI设置为无效语言,请纠正并保存设置", "LanguagesLoadError": "无法加载语言", - "MovieDownloadFailedTooltip": "电影下载失败", - "MovieDownloadIgnoredTooltip": "电影下载被忽略", + "DownloadFailedMovieTooltip": "电影下载失败", + "DownloadIgnoredMovieTooltip": "电影下载被忽略", "MovieFileDeleted": "电影文件已删除", "MovieFileRenamed": "电影文件已重命名", "MovieFileRenamedTooltip": "电影文件已重命名", @@ -1217,7 +1217,7 @@ "AppUpdatedVersion": "{appName} 已经更新到版本 {version} ,重新加载 {appName} 使更新生效", "ConnectionLostReconnect": "{appName} 将会尝试自动连接,您也可以点击下方的重新加载。", "ConnectionLostToBackend": "{appName}失去了与后端的连接,需要重新加载以恢复功能。", - "DeletedReasonMissingFromDisk": "{appName} 无法在磁盘上找到该文件,因此该文件已与数据库中的电影解除链接", + "DeletedReasonMovieMissingFromDisk": "{appName} 无法在磁盘上找到该文件,因此该文件已与数据库中的电影解除链接", "EditDownloadClientImplementation": "编辑下载客户端- {implementationName}", "EditIndexerImplementation": "编辑索引器- {implementationName}", "GrabId": "抓取ID", @@ -1225,7 +1225,7 @@ "IMDbId": "IMDb Id", "InteractiveImportNoMovie": "每个选中的文件必须选择对应的电影", "MovieFileDeletedTooltip": "电影文件已删除", - "MovieGrabbedHistoryTooltip": "从 {indexer} 抓取电影并发送到 {downloadClient}", + "MovieGrabbedTooltip": "从 {indexer} 抓取电影并发送到 {downloadClient}", "IndexerDownloadClientHealthCheckMessage": "使用无效下载客户端的索引器:{indexerNames}。", "FullColorEvents": "全彩事件", "InteractiveImportNoFilesFound": "在所选文件夹中找不到视频文件", From 2c9292c249c6269e3ee1b2427d5c4dd2553505ae Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 23 Oct 2024 12:21:26 +0300 Subject: [PATCH 035/579] Save ImdbId for grabbed movie events --- frontend/src/typings/History.ts | 1 + src/NzbDrone.Core/History/HistoryService.cs | 1 + 2 files changed, 2 insertions(+) diff --git a/frontend/src/typings/History.ts b/frontend/src/typings/History.ts index 0c43f3236b..de244bb1b5 100644 --- a/frontend/src/typings/History.ts +++ b/frontend/src/typings/History.ts @@ -25,6 +25,7 @@ export interface GrabbedHistoryData { downloadUrl: string; guid: string; tmdbId: string; + imdbId: string; protocol: string; customFormatScore?: string; movieMatchType: string; diff --git a/src/NzbDrone.Core/History/HistoryService.cs b/src/NzbDrone.Core/History/HistoryService.cs index 785124ee79..56f7445a9b 100644 --- a/src/NzbDrone.Core/History/HistoryService.cs +++ b/src/NzbDrone.Core/History/HistoryService.cs @@ -150,6 +150,7 @@ public void Handle(MovieGrabbedEvent message) history.Data.Add("DownloadUrl", message.Movie.Release.DownloadUrl); history.Data.Add("Guid", message.Movie.Release.Guid); history.Data.Add("TmdbId", message.Movie.Release.TmdbId.ToString()); + history.Data.Add("ImdbId", message.Movie.Release.ImdbId.ToString()); history.Data.Add("Protocol", ((int)message.Movie.Release.DownloadProtocol).ToString()); history.Data.Add("CustomFormatScore", message.Movie.CustomFormatScore.ToString()); history.Data.Add("MovieMatchType", message.Movie.MovieMatchType.ToString()); From 2d2de7f76b351b6f4984ab439fcd1a2fa5115e16 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 23 Oct 2024 13:53:14 +0300 Subject: [PATCH 036/579] Parse "tmdbid" and "imdb" attributes in Newznab and Torznab parsers --- .../Indexers/Newznab/NewznabRssParser.cs | 14 +++++++++ .../Indexers/Torznab/TorznabRssParser.cs | 31 ++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs index 76f138e4db..a95f9840b4 100644 --- a/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs +++ b/src/NzbDrone.Core/Indexers/Newznab/NewznabRssParser.cs @@ -91,6 +91,8 @@ protected override bool PostProcess(IndexerResponse indexerResponse, List Date: Wed, 23 Oct 2024 10:54:17 +0000 Subject: [PATCH 037/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/de.json | 5 ++++- src/NzbDrone.Core/Localization/Core/es.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/hu.json | 5 ++++- src/NzbDrone.Core/Localization/Core/pt_BR.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/ru.json | 4 +++- 5 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index b95e08feea..882beda7b8 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1465,5 +1465,8 @@ "ShowDigitalReleaseHelpText": "Kino-Erscheinungsdatum unter Poster anzeigen", "ShowPhysicalRelease": "Disc Veröffentlichungsdatum", "ShowPhysicalReleaseHelpText": "Kino-Erscheinungsdatum unter Poster anzeigen", - "FolderNameTokens": "Dateinamen Teile" + "FolderNameTokens": "Dateinamen Teile", + "DefaultNotFoundMessage": "Sie müssen verloren sein, hier gibt es nichts zu sehen.", + "ToggleMonitoredToUnmonitored": "Überwacht, klicken Sie, um die Überwachung aufzuheben", + "ToggleUnmonitoredToMonitored": "Nicht überwacht, klicke zum Überwachen" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 6ec6b0cc0d..25eb739135 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1838,5 +1838,10 @@ "Install": "Instalar", "InstallMajorVersionUpdate": "Instalar actualización", "InstallMajorVersionUpdateMessage": "Esta actualización instalará una nueva versión principal y podría no ser compatible con tu sistema. ¿Estás seguro que quieres instalar esta actualización?", - "InstallMajorVersionUpdateMessageLink": "Por favor revisa [{domain}]({url}) para más información." + "InstallMajorVersionUpdateMessageLink": "Por favor revisa [{domain}]({url}) para más información.", + "DefaultNotFoundMessage": "Debes estar perdido, no hay nada que ver aquí.", + "ToggleMonitoredToUnmonitored": "Monitorizado, haz clic para dejar de monitorizar", + "ToggleUnmonitoredToMonitored": "Sin monitorizar, haz clic para monitorizar", + "OnFileImport": "Al importar un archivo", + "OnFileUpgrade": "Al actualizar archivo" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 3ff81d5506..1ee068d311 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1442,5 +1442,8 @@ "Logout": "Kijelentkezés", "SmartReplace": "Intelligens csere", "SmartReplaceHint": "Dash vagy Space Dash névtől függően", - "FolderNameTokens": "Fájlnév-tokenek" + "FolderNameTokens": "Fájlnév-tokenek", + "DefaultNotFoundMessage": "Biztosan eltévedtél, nincs itt semmi látnivaló.", + "ToggleMonitoredToUnmonitored": "Felügyelt, kattintson a figyelés megszüntetéséhez", + "ToggleUnmonitoredToMonitored": "Nem figyelt, kattintson a figyeléshez" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 0cf261fb9f..8d067da533 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1838,5 +1838,10 @@ "Install": "Instalar", "InstallMajorVersionUpdate": "Instalar Atualização", "InstallMajorVersionUpdateMessage": "Esta atualização instalará uma nova versão principal e pode não ser compatível com o seu sistema. Tem certeza de que deseja instalar esta atualização?", - "InstallMajorVersionUpdateMessageLink": "Verifique [{domain}]({url}) para obter mais informações." + "InstallMajorVersionUpdateMessageLink": "Verifique [{domain}]({url}) para obter mais informações.", + "DefaultNotFoundMessage": "Você deve estar perdido, nada para ver aqui.", + "ToggleMonitoredToUnmonitored": "Monitorado, clique para cancelar o monitoramento", + "ToggleUnmonitoredToMonitored": "Não monitorado, clique para monitorar", + "OnFileImport": "Ao Importar o Arquivo", + "OnFileUpgrade": "Ao Atualizar o Arquivo" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 36e08a3232..986618b54e 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1782,5 +1782,7 @@ "InstallMajorVersionUpdateMessage": "Это обновление установит новую основную версию и может быть несовместимо с вашей системой. Вы уверены, что хотите установить это обновление?", "DefaultNotFoundMessage": "Вы, должно быть, заблудились, здесь не на что смотреть.", "ToggleMonitoredToUnmonitored": "Отслеживается, нажмите, чтобы отключить отслеживание", - "ToggleUnmonitoredToMonitored": "Не отслеживается, нажмите, чтобы отслеживать" + "ToggleUnmonitoredToMonitored": "Не отслеживается, нажмите, чтобы отслеживать", + "OnFileImport": "При импорте файла", + "OnFileUpgrade": "При обновлении файла" } From 1be8385c416fef514ae301f025dc59a749008ee5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 23 Oct 2024 14:12:48 +0300 Subject: [PATCH 038/579] Fix paths mapping for movie specific translations --- src/NzbDrone.Core/Localization/Core/en.json | 4 ++-- src/NzbDrone.Core/Localization/Core/es.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fi.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/pt_BR.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ru.json | 4 ++-- src/NzbDrone.Core/Localization/Core/tr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/zh_CN.json | 4 ++-- .../Notifications/MediaBrowser/MediaBrowserSettings.cs | 4 ++-- .../Notifications/Plex/Server/PlexServerSettings.cs | 4 ++-- 10 files changed, 20 insertions(+), 20 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 780d954e52..1efd878241 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1179,9 +1179,9 @@ "NotificationsSendGridSettingsApiKeyHelpText": "The API Key generated by SendGrid", "NotificationsSettingsUpdateLibrary": "Update Library", "NotificationsSettingsUpdateMapPathsFrom": "Map Paths From", - "NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} path, used to modify series paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} path, used to modify movie paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", "NotificationsSettingsUpdateMapPathsTo": "Map Paths To", - "NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName} path, used to modify series paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName} path, used to modify movie paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", "NotificationsSettingsUseSslHelpText": "Connect to {serviceName} over HTTPS instead of HTTP", "NotificationsSettingsWebhookMethod": "Method", "NotificationsSettingsWebhookMethodHelpText": "Which HTTP method to use submit to the Webservice", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 25eb739135..69dc1c3656 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1319,7 +1319,7 @@ "NotificationsPushoverSettingsSoundHelpText": "Sonido de notificación, deja en blanco para usar el predeterminado", "NotificationsPushoverSettingsUserKey": "Clave de usuario", "NotificationsSettingsUpdateLibrary": "Actualizar biblioteca", - "NotificationsSettingsUpdateMapPathsToHelpText": "Ruta de {appName}, usado para modificar rutas de series cuando {serviceName} ve la ubicación de ruta de biblioteca de forma distinta a {appName} (Requiere 'Actualizar biblioteca')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "Ruta de {appName}, usado para modificar rutas de series cuando {serviceName} ve la ubicación de ruta de biblioteca de forma distinta a {appName} (Requiere 'Actualizar biblioteca')", "NotificationsSimplepushSettingsKey": "Clave", "NotificationsValidationInvalidAccessToken": "Token de acceso inválido", "NzbgetHistoryItemMessage": "Estado de PAR: {parStatus} - Estado de desempaquetado: {unpackStatus} - Estado de movido: {moveStatus} - Estado de script: {scriptStatus} - Estado de borrado: {deleteStatus} - Estado de marcado: {markStatus}", @@ -1355,7 +1355,7 @@ "NotificationsEmbySettingsSendNotificationsHelpText": "Hacer que Emby envíe notificaciones a los proveedores configurados. No soportado en Jellyfin.", "NotificationsPushoverSettingsSound": "Sonido", "NotificationsSendGridSettingsApiKeyHelpText": "La clave API generada por SendGrid", - "NotificationsSettingsUpdateMapPathsFromHelpText": "Ruta de {appName}, usado para modificar rutas de series cuando {serviceName} ve la ubicación de ruta de biblioteca de forma distinta a {appName} (Requiere 'Actualizar biblioteca')", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "Ruta de {appName}, usado para modificar rutas de series cuando {serviceName} ve la ubicación de ruta de biblioteca de forma distinta a {appName} (Requiere 'Actualizar biblioteca')", "NotificationsTwitterSettingsDirectMessage": "Mensaje directo", "NotificationsTwitterSettingsDirectMessageHelpText": "Envía un mensaje directo en lugar de un mensaje público", "NotificationsValidationInvalidHttpCredentials": "Credenciales de autenticación HTTP inválidas: {exceptionMessage}", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 40af8f982f..e78656b65c 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1434,9 +1434,9 @@ "NotificationsPushcutSettingsTimeSensitiveHelpText": "Merkitsee ilmoituksen kiireelliseksi (\"Time Sensitive\").", "NotificationsPushcutSettingsNotificationNameHelpText": "Ilmoituksen nimi Pushcut-sovelluksen ilmoitusvälilehdeltä.", "NotificationsSettingsUpdateMapPathsTo": "Kohdista sijainnit kohteeseen", - "NotificationsSettingsUpdateMapPathsFromHelpText": "{appName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", "NotificationsSettingsUpdateMapPathsFrom": "Kohdista sijainnit lähteeseen", - "NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", "NotificationsSignalSettingsSenderNumberHelpText": "Signal-API:n lähettäjärekisterin puhelinnumero.", "NotificationsSignalSettingsGroupIdPhoneNumber": "Ryhmän iD/puhelinnumero", "NotificationsSignalSettingsPasswordHelpText": "Salasana, jolla Signal-API:lle lähetettävät pyynnöt todennetaan.", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index e2247da147..8b6a65fff9 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1479,7 +1479,7 @@ "NotificationsSlackSettingsIconHelpText": "Change l'icône qui est utilisé pour les messages postés sur Slack (Émoji ou URL)", "NotificationsSignalSettingsUsernameHelpText": "Nom d'utilisateur utilisé pour authentifier les requêtes vers signal-api", "NotificationsSettingsUseSslHelpText": "Se connecter à {serviceName} en HTTPS plutôt qu'en HTTP", - "NotificationsSettingsUpdateMapPathsToHelpText": "Chemin {serviceName}, utilisé pour modifier les chemins des séries quand {serviceName} voit un chemin d'emplacement de bibliothèque différemment de {appName} (nécessite 'Mise à jour bibliothèque')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "Chemin {serviceName}, utilisé pour modifier les chemins des séries quand {serviceName} voit un chemin d'emplacement de bibliothèque différemment de {appName} (nécessite 'Mise à jour bibliothèque')", "NotificationsPushcutSettingsApiKeyHelpText": "Les clés API peuvent être gérées dans la vue Compte de l'app Pushcut", "NotificationsPushBulletSettingSenderIdHelpText": "L'identifiant de l'appareil depuis lequel envoyer les notifications, utilisez « device_iden » dans l'URL de l'appareil sur pushbullet.com (laisser vide pour l'envoyer vous-même)", "ManageFiles": "Gérer les fichiers", @@ -1680,7 +1680,7 @@ "DownloadClientDownloadStationValidationSharedFolderMissing": "Le dossier partagé n'existe pas", "MovieIsPopular": "Le film est populaire sur TMDb", "MovieIsTrending": "Le film est tendance sur TMDb", - "NotificationsSettingsUpdateMapPathsFromHelpText": "Chemin d'accès {appName}, utilisé pour modifier les chemins d'accès aux séries lorsque {serviceName} voit l'emplacement du chemin d'accès à la bibliothèque différemment de {appName} (Nécessite 'Mettre à jour la bibliothèque')", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "Chemin d'accès {appName}, utilisé pour modifier les chemins d'accès aux séries lorsque {serviceName} voit l'emplacement du chemin d'accès à la bibliothèque différemment de {appName} (Nécessite 'Mettre à jour la bibliothèque')", "NoExtraFilesToManage": "Pas de fichiers supplémentaires à gérer.", "NoMovieFilesToManage": "Pas de fichiers vidéo à gérer.", "DeleteSpecificationHelpText": "Êtes-vous sûr de vouloir supprimer la spécification '{name}' ?", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 8d067da533..cdf7f94e4e 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1412,7 +1412,7 @@ "NotificationsSettingsUpdateLibrary": "Atualizar Biblioteca", "NotificationsSettingsUpdateMapPathsFrom": "Mapear Caminhos De", "NotificationsSettingsUpdateMapPathsTo": "Mapear Caminhos Para", - "NotificationsSettingsUpdateMapPathsToHelpText": "Caminho {serviceName}, usado para modificar caminhos de série quando {serviceName} vê a localização do caminho da biblioteca de forma diferente de {appName} (requer 'Atualizar Biblioteca')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "Caminho {serviceName}, usado para modificar caminhos de série quando {serviceName} vê a localização do caminho da biblioteca de forma diferente de {appName} (requer 'Atualizar Biblioteca')", "NotificationsSettingsUseSslHelpText": "Conecte-se a {serviceName} por HTTPS em vez de HTTP", "NotificationsSettingsWebhookMethod": "Método", "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "ID do Grupo/Número de Telefone do destinatário", @@ -1476,7 +1476,7 @@ "NotificationsPushBulletSettingSenderIdHelpText": "O ID do dispositivo para enviar notificações, use device_iden no URL do dispositivo em pushbullet.com (deixe em branco para enviar de você mesmo)", "NotificationsPushoverSettingsDevicesHelpText": "Lista de nomes de dispositivos (deixe em branco para enviar para todos os dispositivos)", "NotificationsSendGridSettingsApiKeyHelpText": "A chave API gerada pelo SendGrid", - "NotificationsSettingsUpdateMapPathsFromHelpText": "Caminho {appName}, usado para modificar caminhos de série quando {serviceName} vê a localização do caminho da biblioteca de forma diferente de {appName} (requer 'Atualizar Biblioteca')", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "Caminho {appName}, usado para modificar caminhos de série quando {serviceName} vê a localização do caminho da biblioteca de forma diferente de {appName} (requer 'Atualizar Biblioteca')", "NotificationsSettingsWebhookMethodHelpText": "Qual método HTTP usar para enviar ao Webservice", "NotificationsSignalSettingsPasswordHelpText": "Senha usada para autenticar solicitações para signal-api", "NotificationsSimplepushSettingsEventHelpText": "Personalize o comportamento das notificações push", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 986618b54e..637aa7bbc3 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1447,7 +1447,7 @@ "NotificationsPushoverSettingsDevicesHelpText": "Список имен устройств (оставьте пустым, чтобы отправить на все устройства)", "NotificationsPushoverSettingsUserKey": "Пользовательский ключ", "NotificationsSendGridSettingsApiKeyHelpText": "Ключ API, сгенерированный SendGrid", - "NotificationsSettingsUpdateMapPathsFromHelpText": "Путь {appName}, используемый для изменения путей к сериалам, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "Путь {appName}, используемый для изменения путей к сериалам, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')", "NotificationsSettingsUpdateMapPathsTo": "Карта путей к", "NotificationsTelegramSettingsChatId": "Идентификатор чата", "NotificationsSignalValidationSslRequired": "Кажется, SSL требуется", @@ -1585,7 +1585,7 @@ "DownloadClientDelugeSettingsDirectoryCompleted": "Переместить каталог по завершении", "DownloadClientQbittorrentValidationCategoryAddFailure": "Не удалось настроить категорию", "MonitorSelected": "Отслеживание выбрано", - "NotificationsSettingsUpdateMapPathsToHelpText": "Путь {serviceName}, используемый для изменения путей к сериям, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "Путь {serviceName}, используемый для изменения путей к сериям, когда {serviceName} видит путь к библиотеке иначе, чем {appName} (требуется 'Обновить библиотеку')", "DownloadClientSettingsOlderPriorityMovieHelpText": "Приоритет при выборе фильмов, вышедших в эфир более 21 дня назад", "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Опциональное место для перемещения завершенных загрузок. Оставьте пустым, чтобы использовать местоположение Deluge по умолчанию", "NotificationsSignalSettingsGroupIdPhoneNumber": "Идентификатор группы/номер телефона", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 7c570a3658..bc2cfc65c7 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1632,8 +1632,8 @@ "NotificationsSlackSettingsUsernameHelpText": "Slack'e gönderilecek kullanıcı adı", "NotificationsTagsMovieHelpText": "Yalnızca en az bir eşleşen etikete sahip filmler için bildirim gönderin", "NotificationsPushoverSettingsSound": "Ses", - "NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} yolu, {serviceName} kitaplık yolu konumunu {appName}'dan farklı gördüğünde seri yollarını değiştirmek için kullanılır ('Kütüphaneyi Güncelle' gerektirir)", - "NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName}, kitaplık yolu konumunu {appName}'den farklı gördüğünde seri yollarını değiştirmek için kullanılan {serviceName} yolu ('Kütüphaneyi Güncelle' gerektirir)", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} yolu, {serviceName} kitaplık yolu konumunu {appName}'dan farklı gördüğünde seri yollarını değiştirmek için kullanılır ('Kütüphaneyi Güncelle' gerektirir)", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName}, kitaplık yolu konumunu {appName}'den farklı gördüğünde seri yollarını değiştirmek için kullanılan {serviceName} yolu ('Kütüphaneyi Güncelle' gerektirir)", "Period": "Periyot", "Popular": "Popüler", "PostImportCategory": "İçe Aktarma Sonrası Kategorisi", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 1424c60aab..3735a1c2da 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1754,7 +1754,7 @@ "SearchMoviesConfirmationMessageText": "您确定要搜索 {count} 部电影吗?", "NotificationsSettingsUpdateMapPathsFrom": "路径映射自", "NotificationsPushoverSettingsUserKey": "用户密钥", - "NotificationsSettingsUpdateMapPathsToHelpText": "{serviceName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`)", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`)", "NotificationsSignalSettingsPasswordHelpText": "用于认证 Signal API 请求的密码", "NotificationsSignalSettingsUsernameHelpText": "用于认证 Signal API 请求的用户名", "NotificationsSimplepushSettingsEventHelpText": "自定义推送通知行为", @@ -1779,7 +1779,7 @@ "NotificationsValidationUnableToSendTestMessage": "无法发送测试消息:{exceptionMessage}", "OnExcludedList": "在排除列表中", "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "更改用于“手动操作”通知的字段", - "NotificationsSettingsUpdateMapPathsFromHelpText": "{appName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`)", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`)", "NotificationsSignalSettingsSenderNumberHelpText": "发送者在 Signal API 中注册的电话号码", "NoMovieFilesToManage": "未管理电影文件。", "NotificationsPushcutSettingsTimeSensitive": "紧急", diff --git a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs index d8928e1546..ee7204df3e 100644 --- a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs +++ b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowserSettings.cs @@ -52,11 +52,11 @@ public MediaBrowserSettings() [FieldDefinition(6, Label = "NotificationsSettingsUpdateLibrary", HelpText = "NotificationsEmbySettingsUpdateLibraryHelpText", Type = FieldType.Checkbox)] public bool UpdateLibrary { get; set; } - [FieldDefinition(7, Label = "NotificationsSettingsUpdateMapPathsFrom", HelpText = "NotificationsSettingsUpdateMapPathsFromHelpText", Type = FieldType.Textbox, Advanced = true)] + [FieldDefinition(7, Label = "NotificationsSettingsUpdateMapPathsFrom", HelpText = "NotificationsSettingsUpdateMapPathsFromMovieHelpText", Type = FieldType.Textbox, Advanced = true)] [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsFrom", "serviceName", "Emby/Jellyfin")] public string MapFrom { get; set; } - [FieldDefinition(8, Label = "NotificationsSettingsUpdateMapPathsTo", HelpText = "NotificationsSettingsUpdateMapPathsToHelpText", Type = FieldType.Textbox, Advanced = true)] + [FieldDefinition(8, Label = "NotificationsSettingsUpdateMapPathsTo", HelpText = "NotificationsSettingsUpdateMapPathsToMovieHelpText", Type = FieldType.Textbox, Advanced = true)] [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsTo", "serviceName", "Emby/Jellyfin")] public string MapTo { get; set; } diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs index 721d80dce8..f7b2736844 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServerSettings.cs @@ -57,11 +57,11 @@ public PlexServerSettings() [FieldDefinition(7, Label = "NotificationsSettingsUpdateLibrary", Type = FieldType.Checkbox)] public bool UpdateLibrary { get; set; } - [FieldDefinition(8, Label = "NotificationsSettingsUpdateMapPathsFrom", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsFromHelpText")] + [FieldDefinition(8, Label = "NotificationsSettingsUpdateMapPathsFrom", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsFromMovieHelpText")] [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsFrom", "serviceName", "Plex")] public string MapFrom { get; set; } - [FieldDefinition(9, Label = "NotificationsSettingsUpdateMapPathsTo", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsToHelpText")] + [FieldDefinition(9, Label = "NotificationsSettingsUpdateMapPathsTo", Type = FieldType.Textbox, Advanced = true, HelpText = "NotificationsSettingsUpdateMapPathsToMovieHelpText")] [FieldToken(TokenField.HelpText, "NotificationsSettingsUpdateMapPathsTo", "serviceName", "Plex")] public string MapTo { get; set; } From d5fb1c55c6536431e7b9eb01aa59eb99c79b3f0a Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 23 Oct 2024 11:15:26 +0000 Subject: [PATCH 039/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Fixer Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 8b6a65fff9..60945f4b3d 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1777,7 +1777,7 @@ "EditionFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature à partir de la fin (par exemple `{Edition Tags:30}`) ou du début (par exemple `{Edition Tags:-30}`) sont toutes deux prises en charge.", "SearchForCutoffUnmetMovies": "Rechercher tous les albums de Cutoff Unmet", "SearchForCutoffUnmetMoviesConfirmationCount": "Êtes-vous sûr de vouloir rechercher tous les épisodes {totalRecords} Cutoff Unmet ?", - "MovieFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Series Title:30}`) ou du début (par exemple `{Series Title:-30}`) sont toutes deux prises en charge.", + "MovieFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Movie Title:30}`) ou du début (par exemple `{Movie Title:-30}`) sont toutes deux prises en charge.", "DeleteMovieFolderCountConfirmation": "Voulez-vous vraiment supprimer {count} séries sélectionnées ?", "DeleteMovieFolderCountWithFilesConfirmation": "Voulez-vous vraiment supprimer {count} séries sélectionnées et tous les contenus ?", "DeleteMovieFolders": "Supprimer le dossier du film", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 637aa7bbc3..be0a922e09 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -140,7 +140,7 @@ "VisitTheWikiForMoreDetails": "Перейти в wiki: ", "Yesterday": "Вчера", "DeleteMovieFolderHelpText": "Удалить папку и её содержимое", - "CustomFormatHelpText": "{appName} оценивает каждый релиз используя сумму баллов по пользовательским форматам. Если новый релиз улучшит оценку, того же или лучшего качества, то Sonarr запишет его.", + "CustomFormatHelpText": "{appName} оценивает каждый релиз используя сумму баллов по пользовательским форматам. Если новый релиз улучшит оценку, того же или лучшего качества, то {appName} запишет его.", "RequiredHelpText": "Чтобы применить пользовательский формат, это условие {implementationName} должно соответствовать. В противном случае достаточно одного совпадения {implementationName}.", "UpdateCheckUINotWritableMessage": "Невозможно установить обновление, поскольку папка пользовательского интерфейса «{uiFolder}» не доступна для записи пользователю «{userName}».", "HomePage": "Домашняя страница", @@ -1631,14 +1631,14 @@ "SearchForCutoffUnmetMoviesConfirmationCount": "Вы уверены, что хотите найти все {totalRecords}, не достигшие указанного качества эпизоды ?", "ShowTags": "Показать теги", "ShowTagsHelpText": "Показать теги под постером", - "MovieFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Series Title:30}`), так и с начала (например, `{Series Title:-30}`).", + "MovieFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Movie Title:30}`), так и с начала (например, `{Movie Title:-30}`).", "DownloadClientSettingsRecentPriorityMovieHelpText": "Приоритет при выборе эпизодов, вышедших в эфир за последние 14 дней", "MovieFolderFormatHelpText": "Используется при добавлении или перемещении новых сериалов через редактор", "NotificationsTagsMovieHelpText": "Отправляйте уведомления только для сериалов, у которых есть хотя бы один соответствующий тег", "ShowUnknownMovieItemsHelpText": "Показывать элементы без сериалов в очереди, это могут быть удаленные сериалы, фильмы или что-либо еще в категории {appName}", "NotificationsJoinSettingsDeviceIds": "ID устройств", "MovieImportedTooltip": "Эпизод успешно загружен и получен из загрузочного клиента", - "EditionFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Series Title:30}`), так и с начала (например, `{Series Title:-30}`).", + "EditionFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Edition Tags:30}`), так и с начала (например, `{Edition Tags:-30}`).", "NotificationsCustomScriptValidationFileDoesNotExist": "Файл не существует", "NotificationsGotifySettingsServerHelpText": "URL-адрес сервера Gotify, включая http(s):// и порт, если необходимо", "MovieGrabbedTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", From 017fa5ad80af2d997e103b5b29cfb3f7d867daae Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 6 Jul 2024 15:57:14 -0700 Subject: [PATCH 040/579] New: Group updates for the same movie for Kodi and Emby / Jellyfin (cherry picked from commit 46c7de379c872f757847a311b21714e905466360) Closes #10150 --- .../Xbmc/OnDownloadFixture.cs | 18 +-- .../Xbmc/UpdateMovieFixture.cs | 4 +- .../MediaBrowser/MediaBrowser.cs | 55 ++++++--- .../Notifications/MediaServerUpdateQueue.cs | 105 ++++++++++++++++++ .../Notifications/Plex/Server/PlexServer.cs | 77 ++----------- src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs | 62 +++++++---- .../Notifications/Xbmc/XbmcService.cs | 4 +- 7 files changed, 210 insertions(+), 115 deletions(-) create mode 100644 src/NzbDrone.Core/Notifications/MediaServerUpdateQueue.cs diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs index fd11fe3fa5..8d525bfeff 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/OnDownloadFixture.cs @@ -33,9 +33,10 @@ public void Setup() Subject.Definition = new NotificationDefinition(); Subject.Definition.Settings = new XbmcSettings - { - UpdateLibrary = true - }; + { + Host = "localhost", + UpdateLibrary = true + }; } private void GivenOldFiles() @@ -48,16 +49,18 @@ private void GivenOldFiles() .ToList(); Subject.Definition.Settings = new XbmcSettings - { - UpdateLibrary = true, - CleanLibrary = true - }; + { + Host = "localhost", + UpdateLibrary = true, + CleanLibrary = true + }; } [Test] public void should_not_clean_if_no_movie_was_replaced() { Subject.OnDownload(_downloadMessage); + Subject.ProcessQueue(); Mocker.GetMock().Verify(v => v.Clean(It.IsAny()), Times.Never()); } @@ -67,6 +70,7 @@ public void should_clean_if_movie_was_replaced() { GivenOldFiles(); Subject.OnDownload(_downloadMessage); + Subject.ProcessQueue(); Mocker.GetMock().Verify(v => v.Clean(It.IsAny()), Times.Once()); } diff --git a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/UpdateMovieFixture.cs b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/UpdateMovieFixture.cs index 0fcf16e143..d856950468 100644 --- a/src/NzbDrone.Core.Test/NotificationTests/Xbmc/UpdateMovieFixture.cs +++ b/src/NzbDrone.Core.Test/NotificationTests/Xbmc/UpdateMovieFixture.cs @@ -45,7 +45,7 @@ public void should_update_using_movie_path() .With(s => s.ImdbId = IMDB_ID) .Build(); - Subject.UpdateMovie(_settings, movie); + Subject.Update(_settings, movie); Mocker.GetMock() .Verify(v => v.UpdateLibrary(_settings, It.IsAny()), Times.Once()); @@ -59,7 +59,7 @@ public void should_update_all_paths_when_movie_path_not_found() .With(s => s.Title = "Not A Real Movie") .Build(); - Subject.UpdateMovie(_settings, fakeMovie); + Subject.Update(_settings, fakeMovie); Mocker.GetMock() .Verify(v => v.UpdateLibrary(_settings, null), Times.Once()); diff --git a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowser.cs b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowser.cs index d9adb47bd8..0b866d6f79 100644 --- a/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowser.cs +++ b/src/NzbDrone.Core/Notifications/MediaBrowser/MediaBrowser.cs @@ -1,5 +1,8 @@ using System.Collections.Generic; +using System.Linq; using FluentValidation.Results; +using NLog; +using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; @@ -9,10 +12,18 @@ namespace NzbDrone.Core.Notifications.Emby public class MediaBrowser : NotificationBase { private readonly IMediaBrowserService _mediaBrowserService; + private readonly MediaServerUpdateQueue _updateQueue; + private readonly Logger _logger; - public MediaBrowser(IMediaBrowserService mediaBrowserService) + private static string Created = "Created"; + private static string Deleted = "Deleted"; + private static string Modified = "Modified"; + + public MediaBrowser(IMediaBrowserService mediaBrowserService, ICacheManager cacheManager, Logger logger) { _mediaBrowserService = mediaBrowserService; + _updateQueue = new MediaServerUpdateQueue(cacheManager); + _logger = logger; } public override string Link => "https://emby.media/"; @@ -33,18 +44,12 @@ public override void OnDownload(DownloadMessage message) _mediaBrowserService.Notify(Settings, MOVIE_DOWNLOADED_TITLE_BRANDED, message.Message); } - if (Settings.UpdateLibrary) - { - _mediaBrowserService.Update(Settings, message.Movie, "Created"); - } + UpdateIfEnabled(message.Movie, Created); } public override void OnMovieRename(Movie movie, List renamedFiles) { - if (Settings.UpdateLibrary) - { - _mediaBrowserService.Update(Settings, movie, "Modified"); - } + UpdateIfEnabled(movie, Modified); } public override void OnHealthIssue(HealthCheck.HealthCheck message) @@ -80,10 +85,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) _mediaBrowserService.Notify(Settings, MOVIE_DELETED_TITLE_BRANDED, deleteMessage.Message); } - if (Settings.UpdateLibrary) - { - _mediaBrowserService.Update(Settings, deleteMessage.Movie, "Deleted"); - } + UpdateIfEnabled(deleteMessage.Movie, Deleted); } } @@ -94,9 +96,34 @@ public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) _mediaBrowserService.Notify(Settings, MOVIE_FILE_DELETED_TITLE_BRANDED, deleteMessage.Message); } + UpdateIfEnabled(deleteMessage.Movie, Deleted); + } + + public override void ProcessQueue() + { + _updateQueue.ProcessQueue(Settings.Host, (items) => + { + if (Settings.UpdateLibrary) + { + _logger.Debug("Performing library update for {0} movies", items.Count); + + items.ForEach(item => + { + // If there is only one update type for the movie use that, otherwise send null and let Emby decide + var updateType = item.Info.Count == 1 ? item.Info.First() : null; + + _mediaBrowserService.Update(Settings, item.Movie, updateType); + }); + } + }); + } + + private void UpdateIfEnabled(Movie movie, string updateType) + { if (Settings.UpdateLibrary) { - _mediaBrowserService.Update(Settings, deleteMessage.Movie, "Deleted"); + _logger.Debug("Scheduling library update for movie {0} {1}", movie.Id, movie.Title); + _updateQueue.Add(Settings.Host, movie, updateType); } } diff --git a/src/NzbDrone.Core/Notifications/MediaServerUpdateQueue.cs b/src/NzbDrone.Core/Notifications/MediaServerUpdateQueue.cs new file mode 100644 index 0000000000..80cf96b3e6 --- /dev/null +++ b/src/NzbDrone.Core/Notifications/MediaServerUpdateQueue.cs @@ -0,0 +1,105 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NzbDrone.Common.Cache; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Movies; + +namespace NzbDrone.Core.Notifications +{ + public class MediaServerUpdateQueue + where TQueueHost : class + { + private class UpdateQueue + { + public Dictionary> Pending { get; } = new (); + public bool Refreshing { get; set; } + } + + private readonly ICached _pendingMoviesCache; + + public MediaServerUpdateQueue(ICacheManager cacheManager) + { + _pendingMoviesCache = cacheManager.GetRollingCache(typeof(TQueueHost), "pendingMovies", TimeSpan.FromDays(1)); + } + + public void Add(string identifier, Movie movie, TItemInfo info) + { + var queue = _pendingMoviesCache.Get(identifier, () => new UpdateQueue()); + + lock (queue) + { + var item = queue.Pending.TryGetValue(movie.Id, out var value) + ? value + : new UpdateQueueItem(movie); + + item.Info.Add(info); + + queue.Pending[movie.Id] = item; + } + } + + public void ProcessQueue(string identifier, Action>> update) + { + var queue = _pendingMoviesCache.Find(identifier); + + if (queue == null) + { + return; + } + + lock (queue) + { + if (queue.Refreshing) + { + return; + } + + queue.Refreshing = true; + } + + try + { + while (true) + { + List> items; + + lock (queue) + { + if (queue.Pending.Empty()) + { + queue.Refreshing = false; + return; + } + + items = queue.Pending.Values.ToList(); + queue.Pending.Clear(); + } + + update(items); + } + } + catch + { + lock (queue) + { + queue.Refreshing = false; + } + + throw; + } + } + } + + public class UpdateQueueItem + { + public Movie Movie { get; set; } + public HashSet Info { get; set; } + + public UpdateQueueItem(Movie movie) + { + Movie = movie; + Info = new HashSet(); + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs index 7cf247e55d..4efc5a90b7 100644 --- a/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs +++ b/src/NzbDrone.Core/Notifications/Plex/Server/PlexServer.cs @@ -18,23 +18,15 @@ public class PlexServer : NotificationBase { private readonly IPlexServerService _plexServerService; private readonly IPlexTvService _plexTvService; + private readonly MediaServerUpdateQueue _updateQueue; private readonly Logger _logger; - private class PlexUpdateQueue - { - public Dictionary Pending { get; } = new Dictionary(); - public bool Refreshing { get; set; } - } - - private readonly ICached _pendingMoviesCache; - public PlexServer(IPlexServerService plexServerService, IPlexTvService plexTvService, ICacheManager cacheManager, Logger logger) { _plexServerService = plexServerService; _plexTvService = plexTvService; + _updateQueue = new MediaServerUpdateQueue(cacheManager); _logger = logger; - - _pendingMoviesCache = cacheManager.GetRollingCache(GetType(), "pendingSeries", TimeSpan.FromDays(1)); } public override string Link => "https://www.plex.tv/"; @@ -70,66 +62,20 @@ private void UpdateIfEnabled(Movie movie) if (Settings.UpdateLibrary) { _logger.Debug("Scheduling library update for movie {0} {1}", movie.Id, movie.Title); - var queue = _pendingMoviesCache.Get(Settings.Host, () => new PlexUpdateQueue()); - lock (queue) - { - queue.Pending[movie.Id] = movie; - } + _updateQueue.Add(Settings.Host, movie, false); } } public override void ProcessQueue() { - var queue = _pendingMoviesCache.Find(Settings.Host); - - if (queue == null) + _updateQueue.ProcessQueue(Settings.Host, (items) => { - return; - } - - lock (queue) - { - if (queue.Refreshing) + if (Settings.UpdateLibrary) { - return; + _logger.Debug("Performing library update for {0} movies", items.Count); + _plexServerService.UpdateLibrary(items.Select(i => i.Movie), Settings); } - - queue.Refreshing = true; - } - - try - { - while (true) - { - List refreshingMovies; - lock (queue) - { - if (queue.Pending.Empty()) - { - queue.Refreshing = false; - return; - } - - refreshingMovies = queue.Pending.Values.ToList(); - queue.Pending.Clear(); - } - - if (Settings.UpdateLibrary) - { - _logger.Debug("Performing library update for {0} movies", refreshingMovies.Count); - _plexServerService.UpdateLibrary(refreshingMovies, Settings); - } - } - } - catch - { - lock (queue) - { - queue.Refreshing = false; - } - - throw; - } + }); } public override ValidationResult Test() @@ -203,13 +149,6 @@ public override object RequestAction(string action, IDictionary { var result = new List(); - // result.Add(new FieldSelectStringOption - // { - // Value = s.Name, - // Name = s.Name, - // IsDisabled = true - // }); - s.Connections.ForEach(c => { var isSecure = c.Protocol == "https"; diff --git a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs index f87ad1f3f6..b1d802490d 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/Xbmc.cs @@ -3,6 +3,7 @@ using System.Net.Sockets; using FluentValidation.Results; using NLog; +using NzbDrone.Common.Cache; using NzbDrone.Common.Extensions; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; @@ -12,11 +13,13 @@ namespace NzbDrone.Core.Notifications.Xbmc public class Xbmc : NotificationBase { private readonly IXbmcService _xbmcService; + private readonly MediaServerUpdateQueue _updateQueue; private readonly Logger _logger; - public Xbmc(IXbmcService xbmcService, Logger logger) + public Xbmc(IXbmcService xbmcService, ICacheManager cacheManager, Logger logger) { _xbmcService = xbmcService; + _updateQueue = new MediaServerUpdateQueue(cacheManager); _logger = logger; } @@ -34,12 +37,12 @@ public override void OnDownload(DownloadMessage message) const string header = "Radarr - Downloaded"; Notify(Settings, header, message.Message); - UpdateAndCleanMovie(message.Movie, message.OldMovieFiles.Any()); + UpdateAndClean(message.Movie, message.OldMovieFiles.Any()); } public override void OnMovieRename(Movie movie, List renamedFiles) { - UpdateAndCleanMovie(movie); + UpdateAndClean(movie); } public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) @@ -47,7 +50,7 @@ public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) const string header = "Radarr - Deleted"; Notify(Settings, header, deleteMessage.Message); - UpdateAndCleanMovie(deleteMessage.Movie, true); + UpdateAndClean(deleteMessage.Movie, true); } public override void OnMovieDelete(MovieDeleteMessage deleteMessage) @@ -57,7 +60,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) const string header = "Radarr - Deleted"; Notify(Settings, header, deleteMessage.Message); - UpdateAndCleanMovie(deleteMessage.Movie, true); + UpdateAndClean(deleteMessage.Movie, true); } } @@ -83,6 +86,35 @@ public override void OnManualInteractionRequired(ManualInteractionRequiredMessag public override string Name => "Kodi"; + public override void ProcessQueue() + { + _updateQueue.ProcessQueue(Settings.Host, (items) => + { + _logger.Debug("Performing library update for {0} movies", items.Count); + + items.ForEach(item => + { + try + { + if (Settings.UpdateLibrary) + { + _xbmcService.Update(Settings, item.Movie); + } + + if (item.Info.Contains(true) && Settings.CleanLibrary) + { + _xbmcService.Clean(Settings); + } + } + catch (SocketException ex) + { + var logMessage = string.Format("Unable to connect to Kodi Host: {0}:{1}", Settings.Host, Settings.Port); + _logger.Debug(ex, logMessage); + } + }); + }); + } + public override ValidationResult Test() { var failures = new List(); @@ -108,24 +140,12 @@ private void Notify(XbmcSettings settings, string header, string message) } } - private void UpdateAndCleanMovie(Movie movie, bool clean = true) + private void UpdateAndClean(Movie movie, bool clean = true) { - try + if (Settings.UpdateLibrary || Settings.CleanLibrary) { - if (Settings.UpdateLibrary) - { - _xbmcService.UpdateMovie(Settings, movie); - } - - if (clean && Settings.CleanLibrary) - { - _xbmcService.Clean(Settings); - } - } - catch (SocketException ex) - { - var logMessage = string.Format("Unable to connect to Kodi Host: {0}:{1}", Settings.Host, Settings.Port); - _logger.Debug(ex, logMessage); + _logger.Debug("Scheduling library update for movie {0} {1}", movie.Id, movie.Title); + _updateQueue.Add(Settings.Host, movie, clean); } } } diff --git a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs index 56092c92e0..bf6c6e9c39 100644 --- a/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs +++ b/src/NzbDrone.Core/Notifications/Xbmc/XbmcService.cs @@ -11,7 +11,7 @@ namespace NzbDrone.Core.Notifications.Xbmc public interface IXbmcService { void Notify(XbmcSettings settings, string title, string message); - void UpdateMovie(XbmcSettings settings, Movie movie); + void Update(XbmcSettings settings, Movie movie); void Clean(XbmcSettings settings); ValidationFailure Test(XbmcSettings settings, string message); } @@ -34,7 +34,7 @@ public void Notify(XbmcSettings settings, string title, string message) _proxy.Notify(settings, title, message); } - public void UpdateMovie(XbmcSettings settings, Movie movie) + public void Update(XbmcSettings settings, Movie movie) { if (CheckIfVideoPlayerOpen(settings)) { From 00d50a030c6507b620aeeafa61c3d1258a33509a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 24 Oct 2024 11:05:25 +0300 Subject: [PATCH 041/579] Translate metadata settings --- .../MediaBrowserMetadataSettings.cs | 2 +- .../Roksbox/RoksboxMetadataSettings.cs | 4 +-- .../Consumers/Wdtv/WdtvMetadataSettings.cs | 4 +-- .../Metadata/Consumers/Xbmc/XbmcMetadata.cs | 2 +- .../Consumers/Xbmc/XbmcMetadataSettings.cs | 30 +++++++++---------- .../Extras/Metadata/MetadataSectionType.cs | 8 +++++ src/NzbDrone.Core/Localization/Core/en.json | 11 +++++++ 7 files changed, 40 insertions(+), 21 deletions(-) create mode 100644 src/NzbDrone.Core/Extras/Metadata/MetadataSectionType.cs diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs index b3e647ab92..7a1c01bbdc 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/MediaBrowser/MediaBrowserMetadataSettings.cs @@ -18,7 +18,7 @@ public MediaBrowserMetadataSettings() MovieMetadata = true; } - [FieldDefinition(0, Label = "Movie Metadata", Type = FieldType.Checkbox)] + [FieldDefinition(0, Label = "MetadataSettingsMovieMetadata", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata)] public bool MovieMetadata { get; set; } public bool IsValid => true; diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs index 3dd5f54f40..2b4e7a88d6 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Roksbox/RoksboxMetadataSettings.cs @@ -19,10 +19,10 @@ public RoksboxMetadataSettings() MovieImages = true; } - [FieldDefinition(0, Label = "Movie Metadata", Type = FieldType.Checkbox)] + [FieldDefinition(0, Label = "MetadataSettingsMovieMetadata", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata)] public bool MovieMetadata { get; set; } - [FieldDefinition(1, Label = "Movie Images", Type = FieldType.Checkbox)] + [FieldDefinition(1, Label = "MetadataSettingsMovieImages", Type = FieldType.Checkbox, Section = MetadataSectionType.Image)] public bool MovieImages { get; set; } public bool IsValid => true; diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs index 9cd64cb2e5..72e5970e8d 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Wdtv/WdtvMetadataSettings.cs @@ -19,10 +19,10 @@ public WdtvMetadataSettings() MovieImages = true; } - [FieldDefinition(0, Label = "Movie Metadata", Type = FieldType.Checkbox)] + [FieldDefinition(0, Label = "MetadataSettingsMovieMetadata", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata)] public bool MovieMetadata { get; set; } - [FieldDefinition(1, Label = "Movie Images", Type = FieldType.Checkbox)] + [FieldDefinition(1, Label = "MetadataSettingsMovieImages", Type = FieldType.Checkbox, Section = MetadataSectionType.Image)] public bool MovieImages { get; set; } public bool IsValid => true; diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs index 51c21aa22c..a0341ba5c2 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadata.cs @@ -282,7 +282,7 @@ public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFil details.Add(new XElement("country")); - if (Settings.AddCollectionName && movie.MovieMetadata.Value.CollectionTitle != null) + if (Settings.AddCollectionName && movie.MovieMetadata.Value.CollectionTitle.IsNotNullOrWhiteSpace()) { var setElement = new XElement("set"); diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs index 589feb7fe0..380d4eb61e 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Xbmc/XbmcMetadataSettings.cs @@ -17,31 +17,31 @@ public class XbmcMetadataSettings : IProviderConfig public XbmcMetadataSettings() { MovieMetadata = true; - MovieMetadataURL = false; - MovieMetadataLanguage = (int)Language.English; - MovieImages = true; UseMovieNfo = false; + MovieMetadataLanguage = (int)Language.English; + MovieMetadataURL = false; AddCollectionName = true; + MovieImages = true; } - [FieldDefinition(0, Label = "Movie Metadata", Type = FieldType.Checkbox)] + [FieldDefinition(0, Label = "MetadataSettingsMovieMetadata", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataXmbcSettingsMovieMetadataHelpText")] public bool MovieMetadata { get; set; } - [FieldDefinition(1, Label = "Movie Metadata URL", Type = FieldType.Checkbox, HelpText = "Radarr will write the tmdb/imdb url in the .nfo file", Advanced = true)] - public bool MovieMetadataURL { get; set; } - - [FieldDefinition(2, Label = "Metadata Language", Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), HelpText = "Radarr will write metadata in the selected language if available")] - public int MovieMetadataLanguage { get; set; } - - [FieldDefinition(3, Label = "Movie Images", Type = FieldType.Checkbox)] - public bool MovieImages { get; set; } - - [FieldDefinition(4, Label = "Use Movie.nfo", Type = FieldType.Checkbox, HelpText = "Radarr will write metadata to movie.nfo instead of the default .nfo")] + [FieldDefinition(1, Label = "MetadataSettingsMovieMetadataNfo", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataXmbcSettingsMovieMetadataNfoHelpText")] public bool UseMovieNfo { get; set; } - [FieldDefinition(5, Label = "Collection Name", Type = FieldType.Checkbox, HelpText = "Radarr will write the collection name to the .nfo file", Advanced = true)] + [FieldDefinition(2, Label = "MetadataSettingsMovieMetadataLanguage", Type = FieldType.Select, SelectOptions = typeof(RealLanguageFieldConverter), Section = MetadataSectionType.Metadata, HelpText = "MetadataXmbcSettingsMovieMetadataLanguageHelpText")] + public int MovieMetadataLanguage { get; set; } + + [FieldDefinition(3, Label = "MetadataSettingsMovieMetadataUrl", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataXmbcSettingsMovieMetadataUrlHelpText", Advanced = true)] + public bool MovieMetadataURL { get; set; } + + [FieldDefinition(4, Label = "MetadataSettingsMovieMetadataCollectionName", Type = FieldType.Checkbox, Section = MetadataSectionType.Metadata, HelpText = "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText", Advanced = true)] public bool AddCollectionName { get; set; } + [FieldDefinition(5, Label = "MetadataSettingsMovieImages", Type = FieldType.Checkbox, Section = MetadataSectionType.Image, HelpText = "fanart.jpg, poster.jpg")] + public bool MovieImages { get; set; } + public bool IsValid => true; public NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Extras/Metadata/MetadataSectionType.cs b/src/NzbDrone.Core/Extras/Metadata/MetadataSectionType.cs new file mode 100644 index 0000000000..7f2251d85b --- /dev/null +++ b/src/NzbDrone.Core/Extras/Metadata/MetadataSectionType.cs @@ -0,0 +1,8 @@ +namespace NzbDrone.Core.Extras.Metadata +{ + public static class MetadataSectionType + { + public const string Metadata = "metadata"; + public const string Image = "image"; + } +} diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 1efd878241..327929b089 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -912,7 +912,18 @@ "Metadata": "Metadata", "MetadataLoadError": "Unable to load Metadata", "MetadataSettings": "Metadata Settings", + "MetadataSettingsMovieImages": "Movie Images", + "MetadataSettingsMovieMetadata": "Movie Metadata", + "MetadataSettingsMovieMetadataCollectionName": "Movie Collection Name", + "MetadataSettingsMovieMetadataLanguage": "Movie Metadata Language", + "MetadataSettingsMovieMetadataNfo": "Use movie.nfo", + "MetadataSettingsMovieMetadataUrl": "Movie Metadata URL", "MetadataSettingsMovieSummary": "Create metadata files when movies are imported or refreshed", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Include collection name in .nfo", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo with full movie metadata", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Include selected language if available in .nfo", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Write metadata to movie.nfo instead of the default .nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Include TMDb and IMDb movie URLs in .nfo", "Min": "Min", "MinAvailability": "Min Availability", "MinimumAge": "Minimum Age", From 748d88852034df43d2497555c9316948c14cebed Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 24 Oct 2024 11:10:29 +0300 Subject: [PATCH 042/579] Sync metadata changes to UI --- frontend/src/Components/SignalRConnector.js | 8 ++++++++ .../Metadata/MetadataController.cs | 19 ------------------- 2 files changed, 8 insertions(+), 19 deletions(-) diff --git a/frontend/src/Components/SignalRConnector.js b/frontend/src/Components/SignalRConnector.js index 4f2fc7ac58..81c2f453f0 100644 --- a/frontend/src/Components/SignalRConnector.js +++ b/frontend/src/Components/SignalRConnector.js @@ -226,6 +226,14 @@ class SignalRConnector extends Component { } }; + handleMetadata = ({ action, resource }) => { + const section = 'settings.metadata'; + + if (action === 'updated') { + this.props.dispatchUpdateItem({ section, ...resource }); + } + }; + handleNotification = ({ action, resource }) => { const section = 'settings.notifications'; diff --git a/src/Radarr.Api.V3/Metadata/MetadataController.cs b/src/Radarr.Api.V3/Metadata/MetadataController.cs index 6302b170cb..33df04f4f9 100644 --- a/src/Radarr.Api.V3/Metadata/MetadataController.cs +++ b/src/Radarr.Api.V3/Metadata/MetadataController.cs @@ -1,7 +1,6 @@ using System; using Microsoft.AspNetCore.Mvc; using NzbDrone.Core.Extras.Metadata; -using NzbDrone.Core.ThingiProvider.Events; using NzbDrone.SignalR; using Radarr.Http; @@ -29,23 +28,5 @@ public override object DeleteProviders([FromBody] MetadataBulkResource resource) { throw new NotImplementedException(); } - - [NonAction] - public override void Handle(ProviderAddedEvent message) - { - throw new NotImplementedException(); - } - - [NonAction] - public override void Handle(ProviderUpdatedEvent message) - { - throw new NotImplementedException(); - } - - [NonAction] - public override void Handle(ProviderDeletedEvent message) - { - throw new NotImplementedException(); - } } } From 234e23eb4725549629e90150188acb6b7ec3baa3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 26 Oct 2024 04:44:19 +0000 Subject: [PATCH 043/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Ardenet <1213193613@qq.com> Co-authored-by: Havok Dan Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/es.json | 387 +++++++++--------- .../Localization/Core/pt_BR.json | 13 +- .../Localization/Core/zh_CN.json | 120 +++--- 3 files changed, 278 insertions(+), 242 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 69dc1c3656..619326d2f3 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -4,8 +4,8 @@ "Indexers": "Indexadores", "IndexerRssHealthCheckNoAvailableIndexers": "Todos los indexadores con capacidad de RSS no están disponibles temporalmente debido a errores recientes con el indexador", "ImportTipsMessage": "Algunos consejos para que la importación vaya sobre ruedas:", - "ImportMechanismHealthCheckMessage": "Activar Manipulación de Descargas Completadas", - "ImportHeader": "Importar una librería existente para añadir películas a {appName}", + "ImportMechanismHealthCheckMessage": "Activar Administración de Descargas Completadas", + "ImportHeader": "Importar una biblioteca organizada existente para añadir películas a {appName}", "Import": "Importar", "ICalLink": "Enlace de iCal", "Host": "Host", @@ -21,11 +21,11 @@ "Filter": "Filtro", "Files": "Archivos", "FileManagement": "Gestión de archivos", - "FailedDownloadHandling": "Manipulación de Descargas Fallidas", + "FailedDownloadHandling": "Error en la Administración de Descargas", "Events": "Eventos", "Edit": "Editar", "Downloaded": "Descargado", - "DownloadClientStatusCheckSingleClientMessage": "Gestores de descargas no disponibles debido a errores: {downloadClientNames}", + "DownloadClientStatusCheckSingleClientMessage": "Clientes de descargas no disponibles debido a errores: {downloadClientNames}", "DownloadClientStatusCheckAllClientMessage": "Los clientes de descargas no están disponibles debido a errores", "DownloadClients": "Clientes de descarga", "DownloadClientCheckUnableToCommunicateMessage": "Incapaz de comunicarse con {downloadClientName}. {errorMessage}", @@ -33,7 +33,7 @@ "DiskSpace": "Espacio en Disco", "Discover": "Descubrir", "Delete": "Eliminar", - "DelayProfiles": "Perfiles de retardo", + "DelayProfiles": "Perfiles de retraso", "Day": "Día", "Dates": "Fechas", "Date": "Fecha", @@ -102,7 +102,7 @@ "RemovedMovieCheckSingleMessage": "La película {movie} ya no está en TMDb", "RemovedMovieCheckMultipleMessage": "Las películas {movies} ya no están en TMDb", "RemotePathMappings": "Mapeos de ruta remota", - "ReleaseBranchCheckOfficialBranchMessage": "Las versión {0} no es una versión válida de {appName}, no recibirás actualizaciones", + "ReleaseBranchCheckOfficialBranchMessage": "La rama {0} no es una rama de lanzamiento válida de {appName}, no recibirás actualizaciones", "RefreshAndScan": "Actualizar y Escanear", "Refresh": "Actualizar", "Queue": "Cola", @@ -139,8 +139,8 @@ "ManualImport": "Importación manual", "Logging": "Registro de eventos", "LogFiles": "Archivos de Registro", - "ImportLists": "Listas", - "ImportListExclusions": "Excluidas de las listas", + "ImportLists": "Listas de Importación", + "ImportListExclusions": "Exclusiones de listas de importación", "Languages": "Idiomas", "Language": "Idioma", "IndexerStatusCheckAllClientMessage": "Todos los indexadores no están disponibles debido a errores", @@ -168,11 +168,11 @@ "PhysicalRelease": "Estreno Físico", "OutputPath": "Ruta de salida", "MovieTitle": "Título de la Película", - "MountCheckMessage": "El punto de montaje que contiene la ruta de una película es de read-only: ", + "MountCheckMessage": "El punto de montaje que contiene la ruta de una película es de solo lectura: ", "MonitoredOnly": "Solo monitorizados", - "MetadataSettingsMovieSummary": "Crear archivos de metadatos cuando las películas se importen ó actualicen", + "MetadataSettingsMovieSummary": "Crea archivos de metadatos cuando las películas se importen o actualicen", "MediaManagementSettingsSummary": "Ajustes de nombrado y gestión de archivos", - "MassMovieSearch": "Búsqueda en masa de películas", + "MassMovieSearch": "Búsqueda masiva de películas", "ImportListsSettingsSummary": "Importar desde otra instancia de {appName} o listas de Trakt y gestionar exclusiones de lista", "LastWriteTime": "Última Fecha de Escritura", "IndexerStatusCheckSingleClientMessage": "Indexadores no disponibles debido a errores: {indexerNames}", @@ -183,7 +183,7 @@ "InCinemas": "En cines", "Imported": "Importado", "Ignored": "Ignorado", - "Grabbed": "Añadido", + "Grabbed": "Capturado", "Genres": "Géneros", "GeneralSettingsSummary": "Puerto, SSL, usuario/contraseña, proxy, analíticas y actualizaciones", "Filename": "Nombre de archivo", @@ -191,7 +191,7 @@ "EventType": "Tipo de evento", "DownloadClientsSettingsSummary": "Clientes de descarga, manejo de descarga y mapeo de rutas remotas", "DownloadClient": "Cliente de descarga", - "DigitalRelease": "Estreno Digital", + "DigitalRelease": "Lanzamiento Digital", "Details": "Detalles", "Deleted": "Eliminado", "CutoffUnmet": "Límite no alcanzado", @@ -222,7 +222,7 @@ "Peers": "Pares", "Organize": "Organizar", "Ok": "Ok", - "OAuthPopupMessage": "Pop-ups bloqueados por su navegador", + "OAuthPopupMessage": "Los elementos emergentes están siendo bloqueados por tu navegador", "Name": "Nombre", "MoveFiles": "Mover archivos", "Monitored": "Monitorizado", @@ -248,10 +248,10 @@ "Age": "Antigüedad", "AddNewMovie": "Añadir película nueva", "SystemTimeCheckMessage": "El reloj del sistema está retrasado más de un día. Las tareas de mantenimiento no se ejecutarán correctamente hasta que se haya corregido", - "MonitorMovie": "Monitorear Película", - "ExistingMovies": "Película(s) Existente", + "MonitorMovie": "Monitorizar Película", + "ExistingMovies": "Película(s) Existente(s)", "EditRemotePathMapping": "Editar mapeo de ruta remota", - "DetailedProgressBarHelpText": "Mostrar tecto en la barra de progreso", + "DetailedProgressBarHelpText": "Mostrar texto en la barra de progreso", "InteractiveImport": "Importación Interactiva", "DetailedProgressBar": "Barra de Progreso Detallada", "AddRemotePathMapping": "Añadir Asignación de Ruta Remota", @@ -316,20 +316,20 @@ "DestinationRelativePath": "Ruta Relativa de Destino", "DestinationPath": "Ruta de destino", "DeleteTag": "Eliminar Etiqueta", - "DeleteSelectedMovieFiles": "Borrar Archivos Seleccionados", - "DeleteRestriction": "Borrar Restricción", - "DeleteQualityProfile": "Borrar perfil de calidad", - "DeleteNotification": "Borrar Notificacion", + "DeleteSelectedMovieFiles": "Eliminar Archivos de Películas Seleccionados", + "DeleteRestriction": "Eliminar Restricción", + "DeleteQualityProfile": "Eliminar perfil de calidad", + "DeleteNotification": "Eliminar Notificación", "DeleteIndexer": "Borrar indexador", "DeleteImportListExclusion": "Eliminar exclusión de listas de importación", - "DeleteFile": "Borrar archivo", - "DeleteEmptyFoldersHelpText": "Borrar carpetas vacías durante la exploración del disco y cuando se eliminen archivos", - "DeleteEmptyFolders": "Borrar carpetas vacías", + "DeleteFile": "Eliminar archivo", + "DeleteEmptyFoldersHelpText": "Elimina las carpetas vacías durante la exploración del disco y cuando se eliminen archivos", + "DeleteEmptyFolders": "Eliminar carpetas vacías", "DeleteDownloadClient": "Borrar cliente de descarga", - "DeleteDelayProfile": "Eliminar Perfil de Retardo", + "DeleteDelayProfile": "Eliminar Perfil de Retraso", "DeleteCustomFormat": "Eliminar formato personalizado", "DeleteBackup": "Eliminar copia de seguridad", - "DelayProfile": "Perfil de retardo", + "DelayProfile": "Perfil de retraso", "DatabaseMigration": "Migración de la base de datos", "UpgradeUntilMovieHelpText": "Una vez que la calidad es alcanzada {appName} no descargará películas tras alcanzar o exceder la puntuación del formato personalizado objetivo", "CreateGroup": "Crear grupo", @@ -337,15 +337,15 @@ "CreateEmptyMovieFolders": "Crear carpetas de películas vacías", "Conditions": "Condiciones", "ColonReplacementFormatHelpText": "Cambia la forma en que {appName} reemplaza los dos puntos", - "ClickToChangeQuality": "Clic para cambiar la calidad", - "ClickToChangeLanguage": "Clic para cambiar el idioma", + "ClickToChangeQuality": "Haz clic para cambiar la calidad", + "ClickToChangeLanguage": "Haz clic para cambiar el idioma", "CheckForFinishedDownloadsInterval": "Intervalo para verificar descargas terminadas", "ChangeHasNotBeenSavedYet": "El cambio aún no se ha guardado", "ChangeFileDate": "Cambiar fecha de archivo", "CertificationCountryHelpText": "Seleccionar país para certificaciones de películas", "CertificationCountry": "País de certificación", "CertificateValidationHelpText": "Cambia cómo de estricta es la validación de certificación de HTTPS. No cambiar a menos que entiendas los riesgos.", - "CertificateValidation": "Validacion de certificado", + "CertificateValidation": "Validación de certificado", "BypassProxyForLocalAddresses": "Omitir Proxy para Direcciones Locales", "Branch": "Rama", "BindAddressHelpText": "Dirección IP4 válida, localhost o '*' para todas las interfaces", @@ -367,10 +367,10 @@ "AnalyticsEnabledHelpText": "Envía información anónima de uso y error a los servidores de {appName}. Esto incluye información sobre tu navegador, qué páginas de interfaz web de {appName} utilizas, informes de errores, así como el sistema operativo y la versión en tiempo de ejecución. Usaremos esta información para priorizar funciones y correcciones de errores.", "AnalyseVideoFiles": "Analizar archivos de vídeo", "AlreadyInYourLibrary": "Ya en tu biblioteca", - "AllowHardcodedSubsHelpText": "Hardcoded subs que sean detectados serán automáticamente descargados", - "AllowHardcodedSubs": "Permitir Hardcoded Subs", + "AllowHardcodedSubsHelpText": "Los subtítulos incrustados detectados serán descargados automáticamente", + "AllowHardcodedSubs": "Permitir Subtítulos Incrustados", "AgeWhenGrabbed": "Antigüedad (cuando se añadió)", - "AddListExclusionMovieHelpText": "Prevenir que la película sea añadida a {appName} mediante listas", + "AddListExclusionMovieHelpText": "Evita que la película sea añadida a {appName} mediante listas", "AddImportListExclusion": "Agregar Lista de Exclusión", "YesCancel": "Sí, Cancelar", "WhitelistedSubtitleTags": "Etiquetas de Subtítulos Permitidas", @@ -398,8 +398,8 @@ "QualityDefinitionsLoadError": "No se pudo cargar las definiciones de calidad", "NotificationsLoadError": "No se pudo cargar las notificaciones", "MetadataLoadError": "No se puede cargar Metadatos", - "ImportListsLoadError": "No se puden cargar las Listas", - "ImportListExclusionsLoadError": "No se pueden cargas las Excluidas de la Lista", + "ImportListsLoadError": "No se pueden cargar las Listas de Importación", + "ImportListExclusionsLoadError": "No se pueden cargar las exclusiones de listas de importación", "IndexersLoadError": "No se pueden cargar los indexadores", "DelayProfilesLoadError": "No se pueden cargar los Perfiles de Retraso", "CustomFormatsLoadError": "No se pudo cargar Formatos Personalizados", @@ -409,7 +409,7 @@ "TorrentDelayHelpText": "Retraso en minutos a esperar antes de capturar un torrent", "TorrentDelay": "Retraso de torrent", "TmdbIdExcludeHelpText": "La Id de TMDb de la película a exluir", - "TMDBId": "TMDb Id", + "TMDBId": "Id de TMDb", "TestAllLists": "Probar todas las listas", "TestAllIndexers": "Probar todos los indexadores", "TestAllClients": "Probar todos los clientes", @@ -432,7 +432,7 @@ "ShowMonitoredHelpText": "Muestra el estado monitorizado bajo el póster", "IconForCutoffUnmetHelpText": "Muestra un icono para archivos cuando el límite no haya sido alcanzado", "ICalShowAsAllDayEvents": "Mostrar como Eventos de Todo el Día", - "ListMonitorMovieHelpText": "Si las películas o colecciones en esta lista deberían ser agregadas como monitoreadas", + "ListMonitorMovieHelpText": "Si las películas o colecciones en esta lista deberían ser añadidas como monitorizadas", "SetPermissionsLinuxHelpTextWarning": "Si no estás seguro qué configuraciones hacer, no las cambies.", "SetPermissionsLinuxHelpText": "¿Debería ejecutarse chmod cuando los archivos son importados/renombrados?", "SetPermissions": "Establecer permisos", @@ -457,7 +457,7 @@ "Reorder": "Reordenar", "RenameMoviesHelpText": "{appName} usará el nombre del archivo si el renombrado está deshabilitado", "RenameMovies": "Renombrar Películas", - "RemoveHelpTextWarning": "Eliminar borrará la descarga y el/los fichero(s) del gestor de descargas.", + "RemoveHelpTextWarning": "Eliminar borrará la descarga y el archivo(s) del cliente de descarga.", "RemoveFromQueue": "Eliminar de la cola", "RemoveFromDownloadClient": "Eliminar del cliente de descarga", "RemoveFilter": "Eliminar filtro", @@ -471,7 +471,7 @@ "RefreshInformationAndScanDisk": "Actualizar la información al escanear el disco", "RecyclingBinCleanup": "Limpieza de la papelera de reciclaje", "RecyclingBin": "Papelera de reciclaje", - "RecyclingBinHelpText": "Los archivos iran aquí una vez se hayan borrado en vez de ser borrados permanentemente", + "RecyclingBinHelpText": "Los archivos de películas irán aquí una vez se hayan borrado en vez de ser borrados permanentemente", "RecyclingBinCleanupHelpTextWarning": "Los archivos en la papelera de reciclaje anteriores al número de días seleccionado serán limpiados automáticamente", "RecyclingBinCleanupHelpText": "Establece a 0 para deshabilitar la limpieza automática", "Reason": "Razón", @@ -495,7 +495,7 @@ "Password": "Contraseña", "PackageVersion": "Versión del paquete", "Original": "Original", - "NotMonitored": "No Monitoreadas", + "NotMonitored": "No monitorizado", "NotificationTriggers": "Disparadores de notificación", "NotAvailable": "No Disponible", "NoMinimumForAnyRuntime": "No hay mínimo para ningún tiempo de ejecución", @@ -506,14 +506,14 @@ "NamingSettings": "Opciones de nombrado", "MustNotContain": "No debe contener", "MustContain": "Debe contener", - "MovieYearToExcludeHelpText": "Año de la película a excluir", + "MovieYearToExcludeHelpText": "El año de la película a excluir", "MovieYear": "Año de la Película", - "MovieTitleToExcludeHelpText": "Ttítulo de la película a excluir (puedes ser cualquier cosa)", - "MovieIsDownloading": "Le película está descargando", + "MovieTitleToExcludeHelpText": "El título de la película a excluir (puede ser cualquier cosa con sentido)", + "MovieIsDownloading": "La película se está descargando", "MovieInfoLanguageHelpTextWarning": "Recargar el Navegador", "MovieID": "ID de Película", "MovieFolderFormat": "Formato de Carpeta de Película", - "MovieFiles": "Archivos", + "MovieFiles": "Archivos de película", "MonitoredHelpText": "Descargar película si está disponible", "Mode": "Modo", "MinimumLimits": "Límites mínimos", @@ -534,10 +534,10 @@ "Logs": "Registros", "LogLevel": "Nivel de Registro", "Local": "Local", - "ListSyncLevelHelpText": "Las películas de la biblioteca se gestionarán en función de su selección si se caen o no aparecen en su(s) lista(s)", - "ImportListSettings": "Ajustes de Lista", + "ListSyncLevelHelpText": "Las películas de la biblioteca se gestionarán en función de tu selección si se caen o no aparecen en tu(s) lista(s)", + "ImportListSettings": "Ajustes de Listas de Importación", "Links": "Enlaces", - "LaunchBrowserHelpText": " Abrir un navegador web e ir a la página de inicio de {appName} al arrancar la app.", + "LaunchBrowserHelpText": " Abre un navegador web y navega a la página de inicio de {appName} al iniciarse la aplicación.", "LanguageHelpText": "Idioma de los Lanzamientos", "Interval": "Intervalo", "IndexerSettings": "Opciones del indexador", @@ -551,7 +551,7 @@ "ImportExtraFiles": "Importar Archivos Extra", "ImportedTo": "Importado a", "IllRestartLater": "Lo reiniciaré más tarde", - "IgnoredHelpText": "Este lanzamiento será rechazado si contiene uno ó más de estos términos (mayúsculas ó minúsculas)", + "IgnoredHelpText": "Este lanzamiento será rechazado si contiene uno o más de estos términos (mayúsculas o minúsculas)", "IgnoreDeletedMovies": "No monitorizar películas eliminadas", "IgnoredAddresses": "Direcciones Ignoradas", "IconForCutoffUnmet": "Icono de límite no alcanzado", @@ -561,12 +561,12 @@ "EnableSsl": "Habilitar SSL", "EnableRss": "Habilitar RSS", "EnableInteractiveSearch": "Habilitar Búsqueda Interactiva", - "EnableMetadataHelpText": "Habilitar la creación de un fichero de metadatos para este tipo de metadato", + "EnableMetadataHelpText": "Habilita la creación de un archivo de metadatos para este tipo de metadato", "ListEnabledHelpText": "Habilitar esta lista para usar en {appName}", "EnableCompletedDownloadHandlingHelpText": "Importa automáticamente las descargas completas del gestor de descargas", "EnableAutomaticSearch": "Habilitar Búsqueda Automática", "EnableAutomaticAdd": "Habilitar añadido automático", - "EnableAutomaticAddMovieHelpText": "Si se habilita, las Películas en esta lista se añadirán automáticamente a {appName}", + "EnableAutomaticAddMovieHelpText": "Si se habilita, las películas en esta lista se añadirán automáticamente a {appName}", "UpgradeUntilCustomFormatScoreMovieHelpText": "Una vez que la calidad objetivo es cumplida o excedida y esta puntuación de formato personalizado es alcanzada {appName} dejará de capturar o importar mejoras para estas películas", "CustomFormatsSettings": "Configuración de formatos personalizados", "CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, los archivos bloqueados impiden renombrar los archivos que están siendo sembrados. Puedes desactivar temporalmente la siembra y usar la función de renombrado de {appName} como alternativa.", @@ -589,7 +589,7 @@ "ShownClickToHide": "Mostrado, haz clic para ocultar", "ShowGenres": "Mostrar Géneros", "ShowCertification": "Mostrar Certificación", - "ListSearchOnAddMovieHelpText": "Buscar películas en esta lista cuando se añada a la biblioteca", + "ListSearchOnAddMovieHelpText": "Busca películas en esta lista cuando se añada a la biblioteca", "RssSyncIntervalHelpTextWarning": "Esto se aplicará a todos los indexadores, por favor sigue las reglas establecidas por ellos", "RssIsNotSupportedWithThisIndexer": "RSS no está soportado con este indexador", "RemovingTag": "Eliminando etiqueta", @@ -599,10 +599,10 @@ "NegateHelpText": "Si se marca, el formato personalizado no se aplica si coincide la condición {implementationName}.", "MoviesSelectedInterp": "{count} película(s) seleccionada(s)", "MovieIsUnmonitored": "La película no está monitorizada", - "MovieIsMonitored": "La película está monitoreada", + "MovieIsMonitored": "La película está monitorizada", "MovieExcludedFromAutomaticAdd": "Película Excluida de Adición Automática", "MovieAlreadyExcluded": "Película ya Excluida", - "MarkAsFailedMessageText": "Seguro que quieres marcar '{0}' como fallida?", + "MarkAsFailedMessageText": "¿Estás seguro que quieres marcar '{0}' como fallida?", "Manual": "Manual", "LogLevelTraceHelpTextWarning": "El registro de seguimiento sólo debe activarse temporalmente", "LastDuration": "Última Duración", @@ -610,7 +610,7 @@ "IncludeRadarrRecommendations": "Incluir Recomendaciones de {appName}", "ImportFailed": "Error de importación: {sourceTitle}", "HiddenClickToShow": "Oculto, pulsa para mostrar", - "GrabReleaseMessageText": "{appName} no pudo determinar para qué película es este lanzamiento. {appName} no podrá importar este lanzamiento automáticamente. Quieres descargar {0}?", + "GrabReleaseMessageText": "{appName} no pudo determinar para qué película es este lanzamiento. {appName} no podrá importar este lanzamiento automáticamente. ¿Quieres descargar '{0}'?", "GoToInterp": "Ir a {0}", "ExistingTag": "Etiquetas existentes", "ExcludeMovie": "Excluir Película", @@ -620,18 +620,18 @@ "DownloadWarning": "Alerta de descarga: {warningMessage}", "Downloading": "Descargando", "DownloadFailed": "La descarga ha fallado", - "DownloadClientUnavailable": "El gestor de descargas no está disponible", - "DeleteTagMessageText": "¿Está seguro de querer eliminar la etiqueta '{label}'?", - "DeleteRestrictionHelpText": "Seguro que quieres eliminar esta restricción?", - "DeleteNotificationMessageText": "¿Seguro que quieres eliminar la notificación '{name}'?", - "DeleteBackupMessageText": "Seguro que quieres eliminar la copia de seguridad '{name}'?", - "DeleteDownloadClientMessageText": "Seguro que quieres eliminar el gestor de descargas '{name}'?", + "DownloadClientUnavailable": "El cliente de descargas no está disponible", + "DeleteTagMessageText": "¿Estás seguro que quieres eliminar la etiqueta '{label}'?", + "DeleteRestrictionHelpText": "¿Estás seguro que quieres eliminar esta restricción?", + "DeleteNotificationMessageText": "¿Estás seguro que quieres eliminar la notificación '{name}'?", + "DeleteBackupMessageText": "¿Estás seguro que quieres eliminar la copia de seguridad '{name}'?", + "DeleteDownloadClientMessageText": "¿Estás seguro que quieres eliminar el cliente de descarga '{name}'?", "DeleteIndexerMessageText": "¿Estás seguro que quieres eliminar el indexador '{name}'?", "Cutoff": "Límite", - "ClickToChangeMovie": "Clic para cambiar película", + "ClickToChangeMovie": "Haz clic para cambiar película", "CheckDownloadClientForDetails": "Revisar el cliente de descarga para más detalles", - "CancelPendingTask": "Estas seguro de que deseas cancelar esta tarea pendiente?", - "BranchUpdateMechanism": "La rama se uso por un mecanisco de actualizacion externo", + "CancelPendingTask": "¿Estás seguro que quieres cancelar esta tarea pendiente?", + "BranchUpdateMechanism": "Rama usada por un mecanismo de actualización externo", "BranchUpdate": "Rama a usar para actualizar {appName}", "BeforeUpdate": "Antes de actualizar", "AddingTag": "Añadir etiqueta", @@ -645,10 +645,10 @@ "NamingSettingsLoadError": "No se pudo cargar las opciones de nombrado", "UnableToLoadMovies": "No se han podido cargar las películas", "MediaManagementSettingsLoadError": "No se puede cargar las opciones de gestión de medios", - "ListOptionsLoadError": "No se pueden cargar opciones de lista", + "ListOptionsLoadError": "No se pueden cargar las opciones de lista", "IndexerOptionsLoadError": "No se pudieron cargar las opciones del indexador", "GeneralSettingsLoadError": "No se han podido cargar los ajustes Generales", - "DownloadClientOptionsLoadError": "No se han podido cargar las opciones del gestor de descargas", + "DownloadClientOptionsLoadError": "No se han podido cargar las opciones del cliente de descarga", "BackupsLoadError": "No se han podido cargar las copias de seguridad", "AddRemotePathMappingError": "No se ha podido añadir una nueva ruta remota, prueba otra vez.", "AddQualityProfileError": "No se ha podido añadir un nuevo perfil de calidad, prueba otra vez.", @@ -656,8 +656,8 @@ "AddListError": "No se ha podido añadir una nueva lista, prueba otra vez.", "AddImportListExclusionError": "No se ha podido añadir una nueva lista de exclusión, prueba otra vez.", "AddIndexerError": "No se pudo añadir un nuevo indexador, por favor inténtalo de nuevo.", - "AddDownloadClientError": "No se ha podido añadir un nuevo gestor de descargas, prueba otra vez.", - "AddCustomFormatError": "No se ha podido añadir un nuevo formato propio, prueba otra vez.", + "AddDownloadClientError": "No se ha podido añadir un nuevo cliente de descarga, prueba otra vez.", + "AddCustomFormatError": "No se ha podido añadir un nuevo formato personalizado, prueba otra vez.", "AddConditionError": "No se ha podido añadir una nueva condición, prueba otra vez.", "TagIsNotUsedAndCanBeDeleted": "La etiqueta no se usa y puede ser borrada", "StartTypingOrSelectAPathBelow": "Comienza a escribir o selecciona una ruta debajo", @@ -673,37 +673,37 @@ "NoBackupsAreAvailable": "No hay copias de seguridad disponibles", "MoreDetails": "Más detalles", "MissingNotMonitored": "Faltante (No monitorizada)", - "MissingMonitoredAndConsideredAvailable": "No encontrada (Monitoreada)", + "MissingMonitoredAndConsideredAvailable": "No encontrada (Monitorizada)", "MinutesSixty": "60 minutos: {sixty}", "MinutesNinety": "90 Minutos: {ninety}", "MinutesHundredTwenty": "120 Minutos: {hundredTwenty}", - "MaintenanceRelease": "Lanzamiento de mantenimiento: Corrección de errores y otras mejoras. Ver historial de commits de Github para mas detalle", - "LoadingMovieFilesFailed": "La carga de los archivos ha fallado", + "MaintenanceRelease": "Lanzamiento de mantenimiento: Corrección de errores y otras mejoras. Ver el historial de commits de Github para más detalles", + "LoadingMovieFilesFailed": "La carga de los archivos de la película ha fallado", "LoadingMovieExtraFilesFailed": "La carga de los extras de la película ha fallado", "LoadingMovieCreditsFailed": "La carga de los créditos de la película ha fallado", "LinkHere": "aquí", "AddNewRestriction": "Añadir nueva restricción", - "HaveNotAddedMovies": "No has añadido películas todavía, quieres importar alguna o todas tus películas primero?", + "HaveNotAddedMovies": "No has añadido ninguna película aún. ¿Quieres importar todas o algunas de tus películas primero?", "SupportedIndexersMoreInfo": "Para más información de indexadores individuales, pulsa en los botones de información.", "SupportedListsMoreInfo": "Para más información individual sobre las listas de importación, haz clic en los botones de información.", "SupportedDownloadClientsMoreInfo": "Para más información en los clientes de descarga individuales, haz clic en los botones de más información.", "FilterPlaceHolder": "Buscar películas", - "FailedLoadingSearchResults": "Error al cargar los resultados de la busqueda, prueba otra vez.", + "FailedLoadingSearchResults": "Error al cargar los resultados de la búsqueda, prueba otra vez.", "ExtraFileExtensionsHelpTextsExamples": "Ejemplos : '.sub, .nfo' o 'sub,nfo'", - "ExtraFileExtensionsHelpText": "Separar con cons la lista de los archivos extra a importar (.nfo será impotado como .nfo-orig)", + "ExtraFileExtensionsHelpText": "Lista separada con comas de los archivos adicionales a importar (.nfo será importado como .nfo-orig)", "Excluded": "Excluida", "Exception": "Excepción", "ErrorLoadingContents": "Error cargando contenidos", "DownloadedButNotMonitored": "Descargada (No monitorizada)", - "DownloadedAndMonitored": "Descargada y Monitoreada", + "DownloadedAndMonitored": "Descargada (Monitorizada)", "CouldNotFindResults": "No se pudieron encontrar resultados para '{term}'", - "CantFindMovie": "Por qué no puedo encontrar mi película?", - "ApplyTagsHelpTextHowToApplyMovies": "Cómo añadir etiquetas a las películas seleccionadas", - "BrowserReloadRequired": "Recargar el Navegador", + "CantFindMovie": "¿Por qué no puedo encontrar mi película?", + "ApplyTagsHelpTextHowToApplyMovies": "Cómo aplicar etiquetas a las películas seleccionadas", + "BrowserReloadRequired": "Recarga de Navegador Requerida", "UiLanguageHelpText": "Idioma que {appName} usará en la interfaz", "UiLanguage": "Idioma de interfaz", - "MovieInfoLanguageHelpText": "Lenguaje que {appName} usara para el UI de Información de Película", - "MovieInfoLanguage": "Lenguaje de la Información de Película", + "MovieInfoLanguageHelpText": "Idioma que {appName} usará para la Información de la Película en la interfaz de usuario", + "MovieInfoLanguage": "Idioma de Información de la Película", "ImportCustomFormat": "Importar formato personalizado", "ExportCustomFormat": "Exportar formato personalizado", "DownloadPropersAndRepacksHelpTextWarning": "Usar formatos personalizados para actualizaciones automáticas a propers/repacks", @@ -722,9 +722,9 @@ "FocusSearchBox": "Enfocar Campo de Búsqueda", "SaveSettings": "Guardar ajustes", "OpenThisModal": "Abrir esta Ventana Modal", - "MovieIndexScrollTop": "Indice de Películas: Desplazar hacia arriba", - "MovieIndexScrollBottom": "Indice de Películas: Desplazar hacia abajo", - "MovieDetailsPreviousMovie": "Detalles: Película Anterior", + "MovieIndexScrollTop": "Índice de Películas: Desplazar hacia arriba", + "MovieIndexScrollBottom": "Índice de Películas: Desplazar hacia abajo", + "MovieDetailsPreviousMovie": "Detalles de la película: Película Anterior", "MovieDetailsNextMovie": "Detalles de la película: Siguiente Película", "CloseCurrentModal": "Cerrar esta Ventana Modal", "AcceptConfirmationModal": "Aceptar Confirmación de esta Ventana Modal", @@ -735,12 +735,12 @@ "Released": "Estrenada", "ProcessingFolders": "Procesando carpetas", "NoMatchFound": "¡Ninguna coincidencia encontrada!", - "ImportRootPath": "Dirige {appName} a la carpeta con todas tus películas, no a una específica. ej. {0} y no {1}. Adicionalmente, cada película debe estar en su propia carpeta dentro de la carpeta root/librería.", - "ImportIncludeQuality": "Asegúrate de que los archivos incluyen la calidad en el nombre. ej. {0}", + "ImportRootPath": "Dirige {appName} a la carpeta con todas tus películas, no a una específica. p. ej. {0} y no {1}. Adicionalmente, cada película debe estar en su propia carpeta dentro de la carpeta raíz/biblioteca.", + "ImportIncludeQuality": "Asegúrate de que tus archivos incluyen la calidad en el nombre. p. ej. {0}", "ImportErrors": "Importar errores", "Existing": "Existentes", "EditRestriction": "Editar restricción", - "CancelProcessing": "Procesando cancelacion", + "CancelProcessing": "Procesando cancelación", "AddRestriction": "Añadir Restricción", "AddMovie": "Añadir Película", "IndexerLongTermStatusCheckSingleClientMessage": "Indexadores no disponibles debido a errores durante más de 6 horas: {indexerNames}", @@ -758,12 +758,12 @@ "AfterManualRefresh": "Tras Refrescar Manualmente", "AllFiles": "Todos los archivos", "ImportLibrary": "Importar biblioteca", - "ExcludeTitle": "¿Excluir {0}? Esto evitará que {appName} agregue automáticamente mediante la sincronización de listas.", + "ExcludeTitle": "¿Excluir {0}? Esto evitará que {appName} añada automáticamente mediante la sincronización de listas.", "None": "Ninguno", - "QualitiesHelpText": "Las calidades situadas mas arriba en la lista son las preferidas aunque no estén marcadas. Las calidades del mismo grupo son iguales. Sólo se buscarán las calidades marcadas", + "QualitiesHelpText": "Las calidades situadas más arriba en la lista son las preferidas aunque no estén marcadas. Las calidades del mismo grupo son iguales. Sólo se buscarán las calidades marcadas", "DeleteMovieFiles": "Eliminar {movieFileCount} archivos de película", "MappedDrivesRunningAsService": "Las unidades de red asignadas no están disponibles cuando se ejecutan como un servicio de Windows. Consulta las preguntas frecuentes para obtener más información", - "RequiredRestrictionHelpText": "El comunicado debe contener al menos uno de estos términos (no distingue entre mayúsculas y minúsculas)", + "RequiredRestrictionHelpText": "El lanzamiento debe contener al menos uno de estos términos (no distingue entre mayúsculas y minúsculas)", "Announced": "Anunciado", "BuiltIn": "Construido en", "CalendarOptions": "Opciones de Calendario", @@ -771,16 +771,16 @@ "ChmodFolder": "chmod de la carpeta", "ChmodFolderHelpText": "Octal, aplicado durante la importación / cambio de nombre a carpetas y archivos multimedia (sin bits de ejecución)", "ChmodFolderHelpTextWarning": "Esto solo funciona si el usuario que ejecuta {appName} es el propietario del archivo. Es mejor asegurarse de que el cliente de descarga establezca los permisos correctamente.", - "ChownGroupHelpText": "Nombre del grupo o gid. Utilice gid para sistemas de archivos remotos.", + "ChownGroupHelpText": "Nombre del grupo o gid. Utiliza gid para sistemas de archivos remotos.", "ChownGroupHelpTextWarning": "Esto solo funciona si el usuario que ejecuta {appName} es el propietario del archivo. Es mejor asegurarse de que el cliente de descarga use el mismo grupo que {appName}.", "CouldNotConnectSignalR": "No se pudo conectar a SignalR, la interfaz de usuario no se actualiza", "DeletedMovieDescription": "La película se eliminó de TMDb", "DeleteMovieFolder": "Eliminar carpeta de películas", - "DockerUpdater": "actualice el contenedor de la ventana acoplable para recibir la actualización", + "DockerUpdater": "Actualiza el contenedor de Docker para recibir la actualización", "AllMoviesInPathHaveBeenImported": "Se han importado todas las películas de {path}", "AllResultsHiddenFilter": "Todos los resultados están ocultos por el filtro aplicado", "Always": "Siempre", - "AptUpdater": "Use apt para instalar la actualización", + "AptUpdater": "Usa apt para instalar la actualización", "AuthBasic": "Básica (Ventana emergente del navegador)", "AuthForm": "Formularios (Página de inicio de sesión)", "Enabled": "Habilitada", @@ -795,9 +795,9 @@ "NoEventsFound": "Ningún evento encontrado", "NoLinks": "Sin enlaces", "NoMoveFilesSelf": " No, moveré los archivos yo mismo", - "NoMoviesExist": "No se encontraron películas, para comenzar, querrá agregar una nueva película o importar algunas existentes.", + "NoMoviesExist": "No se encontraron películas. Para comenzar añade una nueva película o importa algunas existentes.", "NoResultsFound": "Ningún resultado encontrado", - "MovieFilesTotaling": "Totalización de archivos de película", + "MovieFilesTotaling": "Total de archivos de película", "OnGrab": "Al capturar", "OnHealthIssue": "Al haber un problema de salud", "OnLatestVersion": "La última versión de {appName} ya está instalada", @@ -814,10 +814,10 @@ "ReplaceWithDash": "Reemplazar con guion", "TMDb": "TMDb", "Tomorrow": "Mañana", - "AlternativeTitlesLoadError": "No se pueden cargar títulos alternativos.", + "AlternativeTitlesLoadError": "No se pudieron cargar títulos alternativos.", "UpgradesAllowed": "Actualizaciones permitidas", "WhatsNew": "¿Qué hay de nuevo?", - "ImportNotForDownloads": "No lo utilice para importar descargas desde su cliente de descargas, esto es sólo para bibliotecas organizadas existentes, no para archivos sin clasificar.", + "ImportNotForDownloads": "No lo utilices para importar descargas desde tu cliente de descarga, esto es solo para bibliotecas organizadas existentes, no para archivos sin clasificar.", "EditGroups": "Editar grupos", "FileNameTokens": "Tokens de nombre de archivos", "HomePage": "Página principal", @@ -827,7 +827,7 @@ "LastExecution": "Última Ejecución", "InCinemasDate": "Fecha en cines", "InCinemasMovieDescription": "La película está en los cines", - "ListSyncLevelHelpTextWarning": "Los archivos de películas se eliminarán permanentemente, esto puede resultar en borrar su biblioteca si sus listas están vacías", + "ListSyncLevelHelpTextWarning": "Los archivos de películas se eliminarán permanentemente, esto puede resultar en borrar tu biblioteca si tus listas están vacías", "Rss": "RSS", "EditDelayProfile": "Editar perfil de retraso", "Connection": "Conexiones", @@ -836,36 +836,36 @@ "Custom": "Personalizado", "CustomFormat": "Formato personalizado", "CustomFormatHelpText": "{appName} puntúa cada lanzamiento utilizando la suma de puntuaciones para hacer coincidir formatos personalizados. Si una nueva versión mejorara la puntuación, con la misma o mejor calidad, {appName} la tomará.", - "Days": "Dias", - "Debug": "Debug", + "Days": "Días", + "Debug": "Depuración", "DefaultCase": "Caso predeterminado", "DefaultDelayProfileMovie": "Este es el perfil predeterminado. Se aplica a todas las películas que no tienen un perfil explícito.", - "DeleteMovieFilesHelpText": "Eliminar los archivos de película y la carpeta de películas", - "DeleteHeader": "Eliminar: {0}", - "DeleteMovieFolderHelpText": "Eliminar la carpeta de películas y su contenido", + "DeleteMovieFilesHelpText": "Elimina los archivos de películas y la carpeta de películas", + "DeleteHeader": "Eliminar - {0}", + "DeleteMovieFolderHelpText": "Elimina la carpeta de películas y su contenido", "DeleteSelectedMovie": "Eliminar película seleccionada", "DeleteMovieFolderConfirmation": "Se eliminará la carpeta de películas '{path}' y todo su contenido.", "Discord": "Discord", "Donations": "Donaciones", "DoneEditingGroups": "Terminado de editar grupos", - "DoNotPrefer": "No prefiero", + "DoNotPrefer": "No preferir", "DoNotUpgradeAutomatically": "No actualizar automáticamente", "EditCustomFormat": "Editar formato personalizado", - "EditImportListExclusion": "Editar exclusión de lista", + "EditImportListExclusion": "Editar exclusión de lista de importación", "EditQualityProfile": "Editar perfil de calidad", "ErrorRestoringBackup": "Error restaurando la copia de seguridad", "ExternalUpdater": "{appName} está configurado para usar un mecanismo de actualización externo", "FailedToLoadMovieFromAPI": "No se pudo cargar la película desde la API", "FeatureRequests": "Peticiones de características", - "FolderMoveRenameWarning": "Esto también cambiará el nombre de la carpeta de películas según el formato de carpeta de películas en la configuración.", + "FolderMoveRenameWarning": "Esto también renombrará la carpeta de películas según el formato de carpeta de películas en la configuración.", "IMDb": "IMDb", "InstallLatest": "Instala el último", "KeepAndUnmonitorMovie": "Mantener y no monitorizar la película", "Large": "Grande", "LastUsed": "Usado por última vez", "LogOnly": "Sólo Registro", - "LookingForReleaseProfiles1": "¿Busca perfiles de lanzamiento? Tratar", - "LookingForReleaseProfiles2": "en lugar.", + "LookingForReleaseProfiles1": "¿Buscas perfiles de lanzamiento? Prueba", + "LookingForReleaseProfiles2": "en su lugar.", "Lowercase": "Minúscula", "ManualImportSelectLanguage": "Importar Manualmente - Seleccionar Idioma", "ManualImportSelectMovie": "Importar Manualmente - Seleccionar Película", @@ -875,13 +875,13 @@ "MinimumCustomFormatScore": "Puntuación mínima de formato personalizado", "MonitoredStatus": "Monitorizados/Estado", "Months": "Meses", - "MoveFolders1": "¿Le gustaría mover las carpetas de películas a '{0}'?", + "MoveFolders1": "¿Te gustaría mover las carpetas de películas a '{0}'?", "MovieChat": "Chat de películas", "MovieInvalidFormat": "Película: formato no válido", - "MultiLanguage": "Multi lenguaje", + "MultiLanguage": "Multi-idioma", "Negate": "Negar", "Negated": "Anulado", - "NoListRecommendations": "No se encontraron elementos de lista ni recomendaciones; para comenzar, querrá agregar una nueva película, importar algunas existentes o agregar una lista.", + "NoListRecommendations": "No se encontraron elementos de lista ni recomendaciones. Para comenzar añade una nueva película, importa algunas existentes o añade una lista.", "OrganizeConfirm": "¿Estás seguro que quieres organizar todos los archivos en las {count} película(s) seleccionada(s)?", "OrganizeSelectedMovies": "Organizar películas seleccionadas", "PhysicalReleaseDate": "Fecha de lanzamiento físico", @@ -893,7 +893,7 @@ "QualityLimitsMovieRuntimeHelpText": "Los límites se ajustan automáticamente para el tiempo de ejecución de la película.", "RecentChanges": "Cambios recientes", "RefreshLists": "Actualizar listas", - "RemoveMovieAndDeleteFiles": "Eliminar película y eliminar archivos", + "RemoveMovieAndDeleteFiles": "Eliminar película y borrar archivos", "RemoveMovieAndKeepFiles": "Eliminar película y conservar archivos", "Replace": "Reemplazar", "ReplaceWithSpaceDash": "Reemplazar por barra espaciadora", @@ -937,61 +937,61 @@ "WouldYouLikeToRestoreBackup": "Te gustaria restaurar la copia de seguridad '{name}'?", "YesMoveFiles": "Sí, mover los archivos", "Yesterday": "Ayer", - "MoveFolders2": "¿Le gustaría mover los archivos de película de '{0}' a '{1}'?", + "MoveFolders2": "¿Te gustaría mover los archivos de película de '{0}' a '{1}'?", "SqliteVersionCheckUpgradeRequiredMessage": "La versión {0} de SQLite instalada actualmente ya no es compatible. Actualice SQLite al menos a la versión {1}.", "ShowCinemaRelease": "Mostrar fecha de estreno en el cine", "ShowReleaseDate": "Mostrar fecha de lanzamiento", "ShowReleaseDateHelpText": "Muestra la fecha de lanzamiento basada en la mínima disponibilidad debajo del cartel", - "OnMovieDelete": "Al Eliminar Película", - "OnMovieFileDelete": "Al Eliminar Archivo De Película", - "OnMovieFileDeleteForUpgrade": "Al Eliminar Archivo De Pelicula Para Mejorar La Calidad", + "OnMovieDelete": "Al Eliminar una Película", + "OnMovieFileDelete": "Al Eliminar un Archivo De Película", + "OnMovieFileDeleteForUpgrade": "Al Eliminar un Archivo De Película Para Mejorar La Calidad", "Reddit": "Reddit", "More": "Más", "Download": "Descargar", - "DownloadClientCheckDownloadingToRoot": "El cliente de descargas {downloadClientName} coloca las descargas en la carpeta raíz {path}. No debe descargar a una carpeta raíz.", - "ImportListMultipleMissingRoots": "Múltiples carpetas raíz faltan para las listas de importación: {rootFoldersInfo}", - "ImportListMissingRoot": "Falta la capeta raíz para las listas: {rootFolderInfo}", + "DownloadClientCheckDownloadingToRoot": "El cliente de descarga {downloadClientName} coloca las descargas en la carpeta raíz {path}. No deberías descargar a una carpeta raíz.", + "ImportListMultipleMissingRoots": "Faltan varias carpetas raíz de las listas de importación: {rootFoldersInfo}", + "ImportListMissingRoot": "Falta la capeta raíz de la(s) lista(s) de importación: {rootFolderInfo}", "From": "de", - "BypassDelayIfHighestQuality": "Pasar sí es la calidad más alta", + "BypassDelayIfHighestQuality": "Omitir si es la calidad más alta", "Blocklist": "Lista de bloqueos", "BlocklistRelease": "Lista de bloqueos de lanzamiento", - "RemoveFromBlocklist": "Eliminar de lista de bloqueados", + "RemoveFromBlocklist": "Eliminar de la lista de bloqueo", "Blocklisted": "Bloqueados", "BlocklistReleases": "Lista de bloqueos de lanzamientos", "RemotePathMappingCheckDownloadPermissions": "{appName} puede ver pero no acceder a la película descargada {path}. Probablemente sea un error de permisos.", - "RemotePathMappingCheckFilesGenericPermissions": "El cliente de descarga {downloadClientName} informó de la existencia de archivos en {path} pero {appName} no puede ver este directorio. Es posible que tenga que ajustar los permisos de la carpeta.", + "RemotePathMappingCheckFilesGenericPermissions": "El cliente de descarga {downloadClientName} informó de la existencia de archivos en {path} pero {appName} no puede ver este directorio. Es posible que tengas que ajustar los permisos de la carpeta.", "Waiting": "Esperando", "ClickToChangeReleaseGroup": "Pulsa para cambiar el grupo de lanzamiento", - "ImportList": "Lista", + "ImportList": "Importar lista", "ManualImportSetReleaseGroup": "Importación manual - Configurar el grupo de lanzamiento", "NotificationTriggersHelpText": "Selecciona qué eventos deberían disparar esta notificación", "OnApplicationUpdate": "Al actualizar la aplicación", "RemotePathMappingCheckFileRemoved": "El archivo {path} fue eliminado a mitad del proceso.", - "RemotePathMappingCheckBadDockerPath": "Está utilizando docker; el cliente de descarga {downloadClientName} coloca las descargas en {path} pero esta no es una ruta válida {osName}. Revisa tus mapeos de rutas remotas y la configuración del cliente de descarga.", - "RemotePathMappingCheckDockerFolderMissing": "Está utilizando docker; el cliente de descarga {downloadClientName} coloca las descargas en {path} pero este directorio no parece existir dentro del contenedor. Revisa tus mapeos de rutas remotas y la configuración del volumen del contenedor.", - "RemotePathMappingCheckFilesBadDockerPath": "Está utilizando docker; el cliente de descarga {downloadClientName} informó de archivos en {path} pero esta no es una ruta válida {osName}. Revise sus mapeos de rutas remotas y la configuración del cliente de descarga.", - "RemotePathMappingCheckLocalWrongOSPath": "El cliente de descarga local {downloadClientName} coloca las descargas en {path} pero ésta no es una ruta válida {osName}. Revise la configuración de su cliente de descarga.", + "RemotePathMappingCheckBadDockerPath": "Estás utilizando Docker; el cliente de descarga {downloadClientName} coloca las descargas en {path} pero esta no es una ruta válida de {osName}. Revisa tus mapeos de rutas remotas y la configuración del cliente de descarga.", + "RemotePathMappingCheckDockerFolderMissing": "Estás utilizando Docker; el cliente de descarga {downloadClientName} coloca las descargas en {path} pero este directorio no parece existir dentro del contenedor. Revisa tus mapeos de rutas remotas y la configuración del volumen del contenedor.", + "RemotePathMappingCheckFilesBadDockerPath": "Estás utilizando Docker; el cliente de descarga {downloadClientName} informó de archivos en {path} pero esta no es una ruta válida de {osName}. Revisa tus mapeos de rutas remotas y la configuración del cliente de descarga.", + "RemotePathMappingCheckLocalWrongOSPath": "El cliente de descarga local {downloadClientName} coloca las descargas en {path} pero esta no es una ruta válida de {osName}. Revisa la configuración de tu cliente de descarga.", "RemotePathMappingCheckRemoteDownloadClient": "El cliente de descarga remota {downloadClientName} informó de la existencia de archivos en {path} pero este directorio no parece existir. Probablemente falta mapear la ruta remota.", "SelectLanguages": "Seleccionar idiomas", "IndexerDownloadClientHelpText": "Especifica qué cliente de descarga es usado para capturas desde este indexador", "AnnouncedMovieDescription": "Película anunciada", "Auto": "Auto", "Duration": "Duración", - "IndexerTagMovieHelpText": "Solo utilizar este indexador para películas que coincidan con al menos una etiqueta. Déjelo en blanco para utilizarlo con todas las películas.", + "IndexerTagMovieHelpText": "Solo utilizar este indexador para películas que coincidan con al menos una etiqueta. Dejar en blanco para utilizarlo con todas las películas.", "Never": "Nunca", "RemoveCompleted": "Eliminar completado", "SizeLimit": "Límite de tamaño", "Started": "Iniciado", - "BypassDelayIfHighestQualityHelpText": "Evitar el retardo cuando el lanzamiento tiene habilitada la máxima calidad en el perfil de calidad con el protocolo preferido", - "DiscordUrlInSlackNotification": "Tienes una notificación de Discord configurada como una notificación de Slack. Configure esto como una notificación de Discord para una mejor funcionalidad. Las notificaciones afectadas son: {0}", + "BypassDelayIfHighestQualityHelpText": "Omite el retraso cuando el lanzamiento tiene habilitada la máxima calidad en el perfil de calidad con el protocolo preferido", + "DiscordUrlInSlackNotification": "Tienes una notificación de Discord configurada como una notificación de Slack. Configura esto como una notificación de Discord para una mejor funcionalidad. Las notificaciones afectadas son: {0}", "IndexerJackettAll": "Indexadores que utilizan el endpoint no soportado de Jackett 'all': {indexerNames}", "UpdateAvailableHealthCheckMessage": "Una nueva actualización está disponible: {version}", "RemotePathMappingCheckImportFailed": "{appName} no pudo importar una película. Comprueba los detalles en tus registros.", - "RemotePathMappingCheckLocalFolderMissing": "El cliente de descarga remota {downloadClientName} coloca las descargas en {path} pero este directorio no parece existir. Probablemente falta o el mapeo de la ruta remota es incorrecto.", - "RemotePathMappingCheckWrongOSPath": "El cliente de descarga remota {downloadClientName} coloca las descargas en {path} pero esta no es una ruta válida {osName}. Revise los mapeos de las rutas remotas y la configuración del cliente de descarga.", - "RemotePathMappingCheckFilesWrongOSPath": "El cliente de descarga remota {downloadClientName} informó de la existencia de archivos en {path}, pero ésta no es una ruta válida de {osName}. Revise los mapeos de la ruta remota y la configuración del cliente de descarga.", + "RemotePathMappingCheckLocalFolderMissing": "El cliente de descarga remota {downloadClientName} coloca las descargas en {path} pero este directorio no parece existir. Probablemente falta el mapeo de la ruta remota o es incorrecto.", + "RemotePathMappingCheckWrongOSPath": "El cliente de descarga remota {downloadClientName} coloca las descargas en {path} pero esta no es una ruta válida de {osName}. Revisa los mapeos de las rutas remotas y la configuración del cliente de descarga.", + "RemotePathMappingCheckFilesWrongOSPath": "El cliente de descarga remota {downloadClientName} informó de la existencia de archivos en {path}, pero esta no es una ruta válida de {osName}. Revisa los mapeos de la ruta remota y la configuración del cliente de descarga.", "Letterboxd": "Letterboxd", - "ImdbRating": "Puntuación IMDb", + "ImdbRating": "Puntuación en IMDb", "ImdbVotes": "Votos en IMDb", "TmdbRating": "TMDb valoración", "TmdbVotes": "Votos en TMDb", @@ -1001,9 +1001,9 @@ "Rating": "Valoración", "RemoveFailed": "Fallo al eliminar", "RemotePathMappingCheckFolderPermissions": "{appName} puede ver pero no acceder al directorio de descarga {path}. Probablemente sea un error de permisos.", - "RemotePathMappingCheckGenericPermissions": "El cliente de descarga {downloadClientName} coloca las descargas en {path} pero {appName} no puede ver este directorio. Es posible que tenga que ajustar los permisos de la carpeta.", + "RemotePathMappingCheckGenericPermissions": "El cliente de descarga {downloadClientName} coloca las descargas en {path} pero {appName} no puede ver este directorio. Es posible que tengas que ajustar los permisos de la carpeta.", "RemoveDownloadsAlert": "Las opciones de eliminación fueron trasladadas a las opciones del cliente de descarga individual en la tabla anterior.", - "RemotePathMappingCheckFilesLocalWrongOSPath": "El cliente de descarga local {downloadClientName} informó de la existencia de archivos en {path}, pero no es una ruta válida {osName}. Revise la configuración de su cliente de descarga.", + "RemotePathMappingCheckFilesLocalWrongOSPath": "El cliente de descarga local {downloadClientName} informó de la existencia de archivos en {path}, pero no es una ruta válida de {osName}. Revisa la configuración de tu cliente de descarga.", "RemoveSelectedItem": "Eliminar elemento seleccionado", "RemoveSelectedItems": "Eliminar elementos seleccionados", "SelectReleaseGroup": "Seleccionar grupo de lanzamiento", @@ -1012,23 +1012,23 @@ "RssSyncIntervalHelpText": "Intervalo en minutos. Configurar a cero para deshabilitar (esto detendrá todas las capturas automáticas de lanzamientos)", "AllCollectionsHiddenDueToFilter": "Todas las colecciones están ocultas debido al filtro aplicado.", "Collections": "Colecciones", - "MonitorMovies": "Monitorear Películas", - "NoCollections": "No se han encontrado colecciones. Para empezar, añada una nueva película o importe algunas de las existentes", + "MonitorMovies": "Monitorizar Películas", + "NoCollections": "No se han encontrado colecciones. Para empezar, añade una nueva película o importa algunas existentes", "ChooseImportMode": "Elegir Modo de Importación", "CollectionOptions": "Opciones de la Colección", "CollectionShowDetailsHelpText": "Mostrar el estado y propiedades de la colección", - "CollectionShowOverviewsHelpText": "Mostrar resumenes de la colección", - "CollectionShowPostersHelpText": "Mostrar póster de artículos de colección", - "RefreshMonitoredIntervalHelpText": "Cada cuánto actualizar las descargas monitoreadeas desde los clientes de descarga, mínimo 1 minuto", + "CollectionShowOverviewsHelpText": "Mostrar resúmenes de la colección", + "CollectionShowPostersHelpText": "Mostrar póster de los elementos de la colección", + "RefreshMonitoredIntervalHelpText": "Cada cuánto actualizar las descargas monitorizadas desde los clientes de descarga, mínimo 1 minuto", "SearchOnAddCollectionHelpText": "Buscar películas en esta colección cuando se añada a la biblioteca", "TotalMovies": "Películas Totales", "CountCollectionsSelected": "{count} Colección(es) seleccionada(s)", "EditCollection": "Editar Colección", - "MonitorCollection": "Monitorear Colección", - "MonitoredCollectionHelpText": "Monitorear para que las películas de esta colección se añadan automáticamente a la biblioteca", + "MonitorCollection": "Monitorizar Colección", + "MonitoredCollectionHelpText": "Monitorizar para que las películas de esta colección se añadan automáticamente a la biblioteca", "MovieAndCollection": "Película y Colección", - "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Múltiples carpetas raices faltantes para colecciones de películas: {rootFoldersInfo}", - "OnMovieAdded": "Al Agregar Pelicula", + "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Múltiples carpetas raíces faltantes para colecciones de películas: {rootFoldersInfo}", + "OnMovieAdded": "Al Añadir una Película", "RefreshCollections": "Actualizar Colecciones", "ShowCollectionDetails": "Mostrar Estado De Colección", "InstanceName": "Nombre de la Instancia", @@ -1045,21 +1045,21 @@ "ResetQualityDefinitions": "Restablecer definiciones de calidad", "ResetTitles": "Restablecer títulos", "ThemeHelpText": "Cambia el tema de la interfaz de la aplicación, el tema 'Auto' usará el tema de tu sistema para establecer el modo luminoso u oscuro. Inspirado por Theme.Park", - "DownloadClientSortingCheckMessage": "El cliente de descarga {downloadClientName} tiene activada la clasificación {sortingMode} para la categoría de {appName}. Debe desactivar la clasificación en su cliente de descarga para evitar problemas de importación.", - "EnableRssHelpText": "Se utilizará cuando {appName} busque periódicamente publicaciones a través de RSS Sync", + "DownloadClientSortingCheckMessage": "El cliente de descarga {downloadClientName} tiene activada la clasificación {sortingMode} para la categoría de {appName}. Deberías desactivar la clasificación en tu cliente de descarga para evitar problemas de importación.", + "EnableRssHelpText": "Se utilizará cuando {appName} busque periódicamente publicaciones a través de la sincronización por RSS", "ShowOverview": "Presentación", "Theme": "Tema", "PreferredProtocol": "Protocolo preferido", - "EditMovies": "Editar peliculas", + "EditMovies": "Editar Películas", "EditSelectedMovies": "Editar Peliculas Seleccionadas", "ShowCinemaReleaseHelpText": "Mostrar la fecha de lanzamiento debajo del cartel", - "DeleteRemotePathMapping": "Borrar mapeo de ruta remota", - "DownloadClientMovieTagHelpText": "Solo utilizar este indexador para películas que coincidan con al menos una etiqueta. Déjelo en blanco para utilizarlo con todas las películas.", + "DeleteRemotePathMapping": "Eliminar asignación de ruta remota", + "DownloadClientMovieTagHelpText": "Solo utilizar este cliente de descarga para películas que coincidan con al menos una etiqueta. Dejar en blanco para utilizarlo con todas las películas.", "DeleteCustomFormatMessageText": "¿Estás seguro que quieres eliminar el formato personalizado '{name}'?", - "DeleteDelayProfileMessageText": "¿Está seguro de que desea borrar este perfil de retraso?", - "DeleteConditionMessageText": "Seguro que quieres eliminar la etiqueta '{name}'?", - "DeleteFormatMessageText": "¿Está seguro de que desea eliminar la etiqueta de formato {0}?", - "DeleteImportListExclusionMessageText": "¿Está seguro de que desea eliminar esta exclusión de la lista de importación?", + "DeleteDelayProfileMessageText": "¿Estás seguro que quieres borrar este perfil de retraso?", + "DeleteConditionMessageText": "¿Estás seguro que quieres eliminar la etiqueta '{name}'?", + "DeleteFormatMessageText": "¿Estás seguro que quieres eliminar la etiqueta de formato {0}?", + "DeleteImportListExclusionMessageText": "¿Estás seguro que quieres eliminar esta exclusión de la lista de importación?", "RemoveSelectedItemQueueMessageText": "¿Estás seguro que quieres eliminar 1 elemento de la cola?", "RemoveSelectedItemsQueueMessageText": "¿Estás seguro que quieres eliminar {selectedCount} elementos de la cola?", "ResetAPIKeyMessageText": "¿Estás seguro que quieres restablecer tu clave API?", @@ -1079,15 +1079,15 @@ "ApplicationURL": "URL de la aplicación", "ApplicationUrlHelpText": "La URL externa de la aplicación incluyendo http(s)://, puerto y URL base", "AllTitles": "Todos los Títulos", - "ApplyTagsHelpTextHowToApplyDownloadClients": "Cómo añadir etiquetas a los clientes de descargas seleccionados", - "ApplyTagsHelpTextHowToApplyImportLists": "Cómo añadir etiquetas a las listas de importación seleccionadas", + "ApplyTagsHelpTextHowToApplyDownloadClients": "Cómo aplicar etiquetas a los clientes de descargas seleccionados", + "ApplyTagsHelpTextHowToApplyImportLists": "Cómo aplicar etiquetas a las listas de importación seleccionadas", "ApiKeyValidationHealthCheckMessage": "Por favor actualiza tu clave API para que tenga de longitud al menos {length} caracteres. Puedes hacerlo en los ajustes o en el archivo de configuración", - "ManageClients": "Gestionar Clientes", - "ManageDownloadClients": "Gestionar Clientes de Descarga", - "ManageLists": "Gestionar Listas", - "ManageImportLists": "Gestionar Listas de Importación", + "ManageClients": "Administrar Clientes", + "ManageDownloadClients": "Administrar Clientes de Descarga", + "ManageLists": "Administrar Listas", + "ManageImportLists": "Administrar Listas de Importación", "Complete": "Completado", - "DeleteRemotePathMappingMessageText": "¿Está seguro de querer eliminar esta asignación de ruta remota?", + "DeleteRemotePathMappingMessageText": "¿Estás seguro que quieres eliminar esta asignación de ruta remota?", "ListRefreshInterval": "Intervalo de Refresco de Lista", "ImportUsingScript": "Importar usando un script", "ImportScriptPath": "Importar Ruta de Script", @@ -1100,19 +1100,19 @@ "CloneAutoTag": "Clonar Etiquetado Automático", "CloneCondition": "Clonar Condición", "DeleteAutoTag": "Eliminar Etiquetado Automático", - "DeleteAutoTagHelpText": "¿Está seguro de querer eliminar el etiquetado automático '{name}'?", + "DeleteAutoTagHelpText": "¿Estás seguro que quieres eliminar el etiquetado automático '{name}'?", "DeleteSelectedDownloadClientsMessageText": "¿Estás seguro que quieres eliminar {count} cliente(s) de descarga seleccionado(s)?", "EditAutoTag": "Editar Etiquetado Automático", "EditSelectedDownloadClients": "Editar Clientes de Descarga Seleccionados", "EditSelectedIndexers": "Editar Indexadores Seleccionados", "EditSelectedImportLists": "Editar Listas de Importación Seleccionadas", - "ManageIndexers": "Gestionar Indexadores", + "ManageIndexers": "Administrar Indexadores", "Loading": "Cargando", "IndexerDownloadClientHealthCheckMessage": "Indexadores con clientes de descarga inválidos: {indexerNames}.", "CountImportListsSelected": "{count} lista(s) de importación seleccionada(s)", "CountDownloadClientsSelected": "{count} cliente(s) de descarga seleccionado(s)", "DeleteRootFolder": "Eliminar Carpeta Raíz", - "DeleteRootFolderMessageText": "¿Está seguro de querer eliminar la carpeta raíz '{path}'?", + "DeleteRootFolderMessageText": "¿Estás seguro que quieres eliminar la carpeta raíz '{path}'?", "DeleteSelectedImportLists": "Eliminar Lista(s) de Importación", "ListWillRefreshEveryInterval": "La lista se actualizará cada {refreshInterval}", "VideoDynamicRange": "Video de Rango Dinámico", @@ -1133,7 +1133,7 @@ "AudioLanguages": "Idiomas de Audio", "AddImportListImplementation": "Añadir lista de importación - {implementationName}", "AddIndexerImplementation": "Agregar Indexador - {implementationName}", - "DeleteQualityProfileMessageText": "¿Seguro que quieres eliminar el perfil de calidad {name}?", + "DeleteQualityProfileMessageText": "¿Estás seguro que quieres eliminar el perfil de calidad {name}?", "Default": "Predeterminado", "BlocklistLoadError": "No se ha podido cargar la lista de bloqueos", "BlocklistReleaseHelpText": "Bloquea este lanzamiento de volver a ser descargado por {appName} vía RSS o búsqueda automática", @@ -1142,24 +1142,24 @@ "AutoRedownloadFailed": "Descarga fallida", "AutoRedownloadFailedFromInteractiveSearchHelpText": "Búsqueda automática e intento de descarga de una versión diferente cuando se obtiene una versión fallida de la búsqueda interactiva", "ConnectionLostToBackend": "{appName} ha perdido su conexión con el backend y tendrá que ser recargado para restaurar su funcionalidad.", - "BypassDelayIfAboveCustomFormatScoreHelpText": "Habilitar ignorar cuando la versión tenga una puntuación superior a la puntuación mínima configurada para el formato personalizado", + "BypassDelayIfAboveCustomFormatScoreHelpText": "Habilita la omisión cuando la versión tenga una puntuación superior a la puntuación mínima configurada para el formato personalizado", "AutoRedownloadFailedFromInteractiveSearch": "Fallo al volver a descargar desde la búsqueda interactiva", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Puntuación mínima de formato personalizado", - "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Puntuación mínima de formato personalizado necesaria para evitar el retraso del protocolo preferido", + "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Puntuación mínima de formato personalizado necesaria para omitir el retraso del protocolo preferido", "ConnectionLostReconnect": "{appName} intentará conectarse automáticamente, o puedes pulsar en recargar abajo.", "DefaultNameCopiedProfile": "{name} - Copia", "DefaultNameCopiedSpecification": "{name} - Copia", "DelayingDownloadUntil": "Retrasar la descarga hasta el {date} a las {time}", "DeleteImportList": "Eliminar lista de importación", - "DeleteImportListMessageText": "Seguro que quieres eliminar la lista '{name}'?", + "DeleteImportListMessageText": "¿Estás seguro que quieres eliminar la lista '{name}'?", "DeleteSelectedImportListsMessageText": "¿Estás seguro que quieres eliminar {count} lista(s) de importación seleccionada(s)?", - "AppUpdatedVersion": "{appName} ha sido actualizado a la versión `{version}`, para obtener los cambios más recientes, necesitará recargar {appName}", + "AppUpdatedVersion": "{appName} ha sido actualizado a la versión `{version}`, para obtener los cambios más recientes tendrás que recargar {appName}", "DeleteSelectedIndexersMessageText": "¿Estás seguro que quieres eliminar {count} indexador(es) seleccionado(s)?", "DisabledForLocalAddresses": "Deshabilitada para direcciones locales", "DeletedReasonManual": "El archivo fue eliminado usando {appName}, o bien manualmente o por otra herramienta a través de la API", "DeletedReasonMovieMissingFromDisk": "{appName} no ha podido encontrar el archivo en el disco, por lo que se ha desvinculado de la película en la base de datos", "DeletedReasonUpgrade": "Se ha borrado el archivo para importar una versión mejorada", - "DeleteSelectedMovieFilesHelpText": "¿Está seguro de que desea eliminar los archivos de película seleccionados?", + "DeleteSelectedMovieFilesHelpText": "¿Estás seguro que quieres eliminar los archivos de película seleccionados?", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirma la nueva contraseña", "ClearBlocklist": "Limpiar lista de bloqueos", "HistoryLoadError": "No se pudo cargar el historial", @@ -1173,9 +1173,9 @@ "CloneCustomFormat": "Clonar formato personalizado", "CloneProfile": "Clonar Perfil", "Close": "Cerrar", - "DownloadClientsLoadError": "No se puden cargar los gestores de descargas", + "DownloadClientsLoadError": "No se pudieron cargar los clientes de descargas", "EditConnectionImplementation": "Editar Notificación - {implementationName}", - "EditImportListImplementation": "Añadir lista de importación - {implementationName}", + "EditImportListImplementation": "Editar lista de importación - {implementationName}", "EditIndexerImplementation": "Editar Indexador - {implementationName}", "FormatShortTimeSpanHours": "{hours} hora(s)", "FormatShortTimeSpanMinutes": "{minutes} minuto(s)", @@ -1200,24 +1200,24 @@ "FailedToUpdateSettings": "Fallo al actualizar los ajustes", "EditConditionImplementation": "Editar Condición - {implementationName}", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "El cliente de descarga {downloadClientName} se establece para eliminar las descargas completadas. Esto puede resultar en descargas siendo eliminadas de tu cliente antes de que {appName} pueda importarlas.", - "AddRootFolderError": "No se pudoagregar la carpeta raíz", + "AddRootFolderError": "No se pudo añadir la carpeta raíz", "InfoUrl": "Información de la URL", - "InteractiveImportNoLanguage": "Se debe elegir el idioma para cada archivo seleccionado", + "InteractiveImportNoLanguage": "Debe elegirse el idioma para cada archivo seleccionado", "InteractiveImportLoadError": "No se pueden cargar elementos de la importación manual", - "InteractiveImportNoQuality": "La calidad debe elegirse para cada archivo seleccionado", + "InteractiveImportNoQuality": "Debe elegirse la calidad para cada archivo seleccionado", "InteractiveSearchResultsFailedErrorMessage": "La búsqueda ha fallado porque su {message}. Intenta actualizar la información de la película y verificar que la información necesaria esté presente antes de volver a buscar.", - "InvalidUILanguage": "Su interfaz de usuario está configurada en un idioma no válido, corríjalo y guarde la configuración", + "InvalidUILanguage": "Tu interfaz de usuario está configurada en un idioma inválido, corrígelo y guarda la configuración", "LogFilesLocation": "Los archivos de registro se encuentran en: {location}", "FullColorEvents": "Eventos a todo color", "FullColorEventsHelpText": "Estilo alterado para colorear todo el evento con el color de estado, en lugar de sólo el borde izquierdo. No se aplica a la Agenda", - "IMDbId": "Id IMDb", + "IMDbId": "Id de IMDb", "InteractiveImportNoFilesFound": "No se han encontrado archivos de vídeo en la carpeta seleccionada", "InteractiveImportNoImportMode": "Debe seleccionarse un modo de importación", "InteractiveImportNoMovie": "Debe elegirse una película para cada archivo seleccionado", "ManualGrab": "Captura manual", "MatchedToMovie": "Coincidencia con la película", - "HealthMessagesInfoBox": "Puedes encontrar más información sobre la causa de estos mensajes de comprobación de salud haciendo clic en el enlace wiki (icono de libro) al final de la fila, o comprobando tus [registros]({link}). Si tienes dificultades para interpretar estos mensajes, puedes ponerte en contacto con nuestro soporte en los enlaces que aparecen a continuación.", - "ManageFiles": "Gestionar archivos", + "HealthMessagesInfoBox": "Puedes encontrar más información sobre la causa de estos mensajes de comprobación de salud haciendo clic en el enlace wiki (icono de libro) al final de la fila, o comprobando tus [registros]({link}). Si tienes dificultades para interpretar estos mensajes, puedes ponerte en contacto con nuestro soporte en los enlaces que aparecen abajo.", + "ManageFiles": "Administrar archivos", "MovieFileDeleted": "Archivo de película eliminado", "MovieFileRenamedTooltip": "Archivo de película renombrado", "MovieFolderImportedTooltip": "Película importada de la carpeta de películas", @@ -1229,9 +1229,9 @@ "LanguagesLoadError": "No es posible cargar los idiomas", "DownloadClientQbittorrentSettingsContentLayout": "Diseño del contenido", "MovieGrabbedTooltip": "Película capturada de {indexer} y enviada a {downloadClient}", - "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Si usar el diseño de contenido configurado de qBittorrent, el diseño original del torrent o siempre crear una subcarpeta (qBittorrent 4.3.2+)", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Si usa el diseño de contenido configurado de qBittorrent, el diseño original del torrent o siempre crea una subcarpeta (qBittorrent 4.3.2+)", "MovieImported": "Película importada", - "MovieImportedTooltip": "Película descargada correctamente y obtenida del cliente de descargas", + "MovieImportedTooltip": "Película descargada correctamente y obtenida del cliente de descarga", "DownloadClientAriaSettingsDirectoryHelpText": "Ubicación opcional en la que poner las descargas, dejar en blanco para usar la ubicación de Aria2 predeterminada", "DownloadClientPriorityHelpText": "Prioridad del cliente de descarga desde 1 (la más alta) hasta 50 (la más baja). Por defecto: 1. Se usa Round-Robin para clientes con la misma prioridad.", "NotificationsDiscordSettingsUsernameHelpText": "El nombre de usuario para publicar, por defecto es el webhook predeterminado de Discord", @@ -1266,12 +1266,12 @@ "OnHealthRestored": "Al resolver las incidencias", "NotificationsDiscordSettingsAuthor": "Autor", "Clone": "Clonar", - "DownloadClientDownloadStationProviderMessage": "{appName} no pudo conectarse a la Estación de Descarga si la Autenticación de 2 factores está habilitada en su cuenta de DSM", - "NotificationsEmailSettingsUseEncryptionHelpText": "Si prefiere utilizar el cifrado si está configurado en el servidor, utilizar siempre el cifrado mediante SSL (sólo puerto 465) o StartTLS (cualquier otro puerto) o no utilizar nunca el cifrado", + "DownloadClientDownloadStationProviderMessage": "{appName} no pudo conectarse a Download Station si la Autenticación de 2 factores está habilitada en tu cuenta de DSM", + "NotificationsEmailSettingsUseEncryptionHelpText": "Si prefiere utilizar el cifrado si está configurado en el servidor, utilizar siempre el cifrado mediante SSL (sólo puerto 465) o StartTLS (cualquier otro puerto), o no utilizar nunca el cifrado", "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} no podrá efectuar el Manejo de Descargas Completadas según lo configurado. Puede arreglar esto en qBittorrent ('Herramientas -> Opciones...' en el menú) cambiando 'Opciones -> BitTorrent -> Límite de ratio ' de 'Eliminarlas' a 'Pausarlas'", "ListQualityProfileHelpText": "Los elementos de la lista del Perfil de Calidad se añadirán con", "ListRootFolderHelpText": "Los elementos de la lista de carpetas raíz se añadirán a", - "BlackholeFolderHelpText": "La carpeta en donde {appName} se almacenaran los {extension} file", + "BlackholeFolderHelpText": "La carpeta donde {appName} almacenará los archivos {extension}", "MediaInfoFootNote": "MediaInfo Full/Idiomas de audio/Idiomas de subtítulo soporta un sufijo `:ES+DE` que te permite filtrar los idiomas incluidos en el nombre de archivo. Usa `-DE` para excluir idiomas específicos. Añadir `+` (eg `:ES+`) devolverá `[ES]`/`[ES+--]`/`[--]` dependiendo de los idiomas excluidos. Por ejemplo `{MediaInfo Full:ES+DE}`.", "NotificationsAppriseSettingsNotificationType": "Tipo de notificación de Apprise", "NotificationsAppriseSettingsPasswordHelpText": "Autenticación básica HTTP de contraseña", @@ -1779,11 +1779,11 @@ "SearchForCutoffUnmetMoviesConfirmationCount": "¿Estás seguro que quieres buscar las {totalRecords} películas con límites no alcanzados?", "UnmonitorSelected": "No monitorizar seleccionados", "DeleteMovieFolderMovieCount": "{movieFileCount} archivos de películas en un total de {size}", - "DeleteMovieFolders": "Eliminar carpeta de películas", - "DeleteMovieFolderCountConfirmation": "Esta seguro que desea eliminar '{count}' series seleccionadas?", - "DeleteMovieFolderCountWithFilesConfirmation": "Esta seguro que desea eliminar '{count}' seleccionadas y sus contenidos?", - "DeleteMovieFoldersHelpText": "Eliminar los directorios de series y sus contenidos", - "DeleteSelectedMovies": "Eliminar serie seleccionada", + "DeleteMovieFolders": "Eliminar carpetas de películas", + "DeleteMovieFolderCountConfirmation": "¿Estás seguro que quieres eliminar '{count}' película(s) seleccionada(s)?", + "DeleteMovieFolderCountWithFilesConfirmation": "¿Estás seguro que quieres eliminar '{count}' película(s) seleccionada(s) y todo su contenido?", + "DeleteMovieFoldersHelpText": "Elimina las carpetas de películas y su contenido", + "DeleteSelectedMovies": "Eliminar películas seleccionadas", "NotificationsPlexSettingsServer": "Servidor", "UnableToImportAutomatically": "No se pudo importar automáticamente", "NotificationsPlexSettingsServerHelpText": "Selecciona el servidor desde una cuenta de plex.tv después de autenticarse", @@ -1822,7 +1822,7 @@ "MinimumCustomFormatScoreIncrementHelpText": "Mejora mínima requerida de la puntuación de formato personalizado entre los lanzamientos existentes y nuevos antes de que {appName} lo considere una actualización", "SkipFreeSpaceCheckHelpText": "Se usa cuando {appName} no puede detectar el espacio libre de tu carpeta raíz", "NotificationsGotifySettingsMetadataLinks": "Enlaces de metadatos", - "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Añade un enlace a los metadatos de la serie cuando se envían notificaciones", + "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Añade un enlace a los metadatos de la película cuando se envían notificaciones", "NotificationsGotifySettingsPreferredMetadataLink": "Enlace de metadatos preferido", "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Enlace de metadatos para clientes que solo soportan un único enlace", "ShowTraktRatingPosterHelpText": "Mostrar valoraciones de Tomato debajo del póster", @@ -1843,5 +1843,16 @@ "ToggleMonitoredToUnmonitored": "Monitorizado, haz clic para dejar de monitorizar", "ToggleUnmonitoredToMonitored": "Sin monitorizar, haz clic para monitorizar", "OnFileImport": "Al importar un archivo", - "OnFileUpgrade": "Al actualizar archivo" + "OnFileUpgrade": "Al actualizar un archivo", + "MetadataSettingsMovieImages": "Imágenes de la película", + "MetadataSettingsMovieMetadata": "Metadatos de la película", + "MetadataSettingsMovieMetadataCollectionName": "Nombre de la colección de películas", + "MetadataSettingsMovieMetadataLanguage": "Idioma de los metadatos de la película", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo con metadatos completos de la película", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Incluye el idioma seleccionado si está disponible en el .nfo", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Incluye el nombre de la colección en el .nfo", + "MetadataSettingsMovieMetadataUrl": "URL de los metadatos de la película", + "MetadataSettingsMovieMetadataNfo": "Usar película.nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluye las URLs de TMDb e IMDb de la película en el .nfo", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Escribe los metadatos en película.nfo en lugar de al archivo .nfo predeterminado" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index cdf7f94e4e..fffe034da3 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1843,5 +1843,16 @@ "ToggleMonitoredToUnmonitored": "Monitorado, clique para cancelar o monitoramento", "ToggleUnmonitoredToMonitored": "Não monitorado, clique para monitorar", "OnFileImport": "Ao Importar o Arquivo", - "OnFileUpgrade": "Ao Atualizar o Arquivo" + "OnFileUpgrade": "Ao Atualizar o Arquivo", + "MetadataSettingsMovieImages": "Imagens do Filme", + "MetadataSettingsMovieMetadata": "Metadados do Filme", + "MetadataSettingsMovieMetadataCollectionName": "Nome da Coleção do Filme", + "MetadataSettingsMovieMetadataLanguage": "Idioma dos Metadados do Filme", + "MetadataSettingsMovieMetadataNfo": "Usar movie.nfo", + "MetadataSettingsMovieMetadataUrl": "URL dos Metadados do Filme", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Incluir o nome da coleção no .nfo", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo com metadados completos do filme", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Incluir o idioma selecionado, se disponível em .nfo", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Grave metadados em movie.nfo em vez do nome de arquivo de filme padrão .nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluir URLs de filmes TMDb e IMDb no .nfo" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 3735a1c2da..0835c04f64 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -4,20 +4,20 @@ "DownloadClientCheckNoneAvailableMessage": "无可用的下载客户端", "DownloadClient": "下载客户端", "Donations": "赞助", - "DockerUpdater": "更新Docker容器以更新应用", + "DockerUpdater": "更新 Docker 容器以更新应用", "Docker": "Docker", - "DiskSpace": "硬盘空间", + "DiskSpace": "磁盘空间", "Discover": "发现", "Disabled": "已禁用", "Details": "详情", - "DeleteMovieFolderConfirmation": "电影文件夹 “{path}” 及其所有内容都将被删除。", + "DeleteMovieFolderConfirmation": "电影文件夹 `{path}` 及其所有内容都将被删除。", "DeleteTagMessageText": "您确定要删除标签 '{label}' 吗?", "DeleteTag": "删除标签", "DeleteSelectedMovieFiles": "删除已选中的电影文件", "DeleteSelectedMovie": "删除已选中的电影", "DeleteQualityProfile": "删除质量配置", "DeleteNotification": "删除消息推送", - "DeleteNotificationMessageText": "您确定要删除通知“{name}”吗?", + "DeleteNotificationMessageText": "您确定要删除通知 “{name}” 吗?", "DeleteMovieFolder": "删除电影文件夹", "DeleteMovieFolderHelpText": "删除电影文件夹及其内容", "DatabaseMigration": "数据库迁移版本", @@ -39,12 +39,12 @@ "DeleteFile": "删除文件", "DeleteEmptyFoldersHelpText": "在磁盘扫描和电影文件删除时删除空的电影文件夹", "DeleteEmptyFolders": "删除空目录", - "DeleteDownloadClientMessageText": "你确定要删除下载客户端 “{name}” 吗?", + "DeleteDownloadClientMessageText": "您确定要删除下载客户端 “{name}” 吗?", "DeleteDownloadClient": "删除下载客户端", "DeleteDelayProfile": "删除延迟配置", "Deleted": "已删除", "DeleteCustomFormat": "删除自定义格式", - "DeleteBackupMessageText": "您确定要删除备份“{name}”吗?", + "DeleteBackupMessageText": "您确定要删除备份 “{name}” 吗?", "DeleteBackup": "删除备份", "Delete": "删除", "AddNewMessage": "添加电影很简单,只需要输入您想要添加的电影名称即可", @@ -52,7 +52,7 @@ "Debug": "调试", "CustomFormat": "自定义格式", "CustomFilters": "自定义过滤器", - "CreateEmptyMovieFoldersHelpText": "硬盘扫描过程中将创建缺失的电影文件夹", + "CreateEmptyMovieFoldersHelpText": "磁盘扫描过程中将创建缺失的电影文件夹", "CouldNotFindResults": "找不到 '{term}' 的任何结果", "CopyToClipboard": "复制到剪贴板", "Close": "关闭", @@ -87,7 +87,7 @@ "AddRemotePathMapping": "添加远程路径映射", "ApplyTags": "应用标签", "Apply": "应用", - "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到{appName}的服务器。这包括有关您的浏览器的信息、您使用的{appName} WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", + "AnalyticsEnabledHelpText": "将匿名使用情况和错误信息发送到 {appName} 的服务器。这包括有关您的浏览器信息、您使用的 {appName} WebUI页面、错误报告以及操作系统和运行时版本。我们将使用此信息来确定功能和错误修复的优先级。", "AlternativeTitle": "其他电影名称", "Add": "添加", "AddCustomFormat": "添加自定义命名格式", @@ -334,7 +334,7 @@ "Indexer": "索引器", "InCinemasMovieDescription": "上映中电影", "InCinemasDate": "上映日期", - "InCinemas": "已上映", + "InCinemas": "上映日期", "ImportNotForDownloads": "请勿用于导入下载客户端的下载内容,本方法只限于导入已整理的现有资源库,不能导入未整理的文件。", "ImportMovies": "导入电影", "ImportMechanismHealthCheckMessage": "启用下载完成处理", @@ -424,7 +424,7 @@ "CurrentlyInstalled": "已安装", "CreateGroup": "创建组", "CreateEmptyMovieFolders": "为电影创建空文件夹", - "CouldNotConnectSignalR": "无法连接至SignalR,不会升级UI", + "CouldNotConnectSignalR": "无法连接至 SignalR,UI 将不会更新", "CopyUsingHardlinksMovieHelpText": "硬链接 (Hardlinks) 允许 {appName} 将还在做种中的文件导入到电影文件夹中而不占用额外的存储空间或者复制文件的全部内容。硬链接 (Hardlinks) 仅能在源文件和目标文件在同一磁盘卷中使用", "ConnectSettingsSummary": "通知、与媒体服务器/播放器的连接及自定义脚本", "DownloadClientSettings": "下载客户端设置", @@ -498,7 +498,7 @@ "Source": "代码", "SorryThatMovieCannotBeFound": "对不起,未找到该电影。", "SkipFreeSpaceCheck": "跳过剩余空间检查", - "SizeOnDisk": "占用磁盘体积", + "SizeOnDisk": "磁盘占用大小", "Size": "大小", "Shutdown": "关机", "ShowYear": "显示年份", @@ -531,7 +531,7 @@ "AddListExclusionMovieHelpText": "防止列表中的电影被添加到 {appName} 中", "AddExclusion": "添加排除", "AddedToDownloadQueue": "已加入下载队列", - "Added": "已添加", + "Added": "添加日期", "Actions": "动作", "IMDb": "IMDb", "PendingChangesDiscardChanges": "舍弃修改并退出", @@ -557,7 +557,7 @@ "MoveFolders1": "要将电影文件夹移至 “{0}” 吗?", "MonitorMovie": "追踪电影", "MonitoredStatus": "已追踪/状态", - "MonitoredOnly": "仅追踪", + "MonitoredOnly": "已追踪项", "MonitoredHelpText": "可用时下载电影", "Monitor": "追踪", "MinimumFreeSpaceHelpText": "如果导入的磁盘空间不足,则禁止导入", @@ -624,10 +624,10 @@ "ExcludeMovie": "排除的电影", "Excluded": "排除的", "Exception": "例外", - "AnalyseVideoFilesHelpText": "从文件中提取视频信息,如分辨率,时长和编解码器信息。这需要{appName}在扫描期间读取文件并可能导致高磁盘或网络占用。", + "AnalyseVideoFilesHelpText": "从文件中提取视频信息,如分辨率、时长和编解码器信息。这需要 {appName} 在扫描期间读取文件并可能导致高磁盘或网络占用。", "EnableMetadataHelpText": "启用此元数据类型的元数据文件创建", "EnableColorImpairedModeHelpText": "改变样式,以允许有颜色障碍的用户更好地区分颜色编码信息", - "EnableAutomaticSearchHelpText": "当自动搜索通过UI或{appName}执行时将被使用", + "EnableAutomaticSearchHelpText": "当自动搜索通过 UI 或 {appName} 执行时将被使用", "EditRestriction": "编辑限制", "Edition": "版本", "EditDelayProfile": "编辑延时配置", @@ -769,9 +769,9 @@ "RecentFolders": "最近文件夹", "ShowSearchHelpText": "悬停时显示搜索按钮", "PreviewRename": "重命名预览", - "SupportedIndexersMoreInfo": "有关单个索引器的更多信息,请点击“更多信息”按钮。", + "SupportedIndexersMoreInfo": "有关单个索引器的更多信息,请点击 “更多信息” 按钮。", "SupportedListsMoreInfo": "有关更多导入列表的详细信息,请单击info按钮。", - "SupportedDownloadClientsMoreInfo": "若需要查看有关下载客户端的详细信息,请点击“更多信息”按钮。", + "SupportedDownloadClientsMoreInfo": "若需要查看有关下载客户端的详细信息,请点击 “更多信息” 按钮。", "Crew": "工作人员", "ChownGroupHelpTextWarning": "这只在运行{appName}的用户是文件所有者的情况下才有效。最好确保下载客户端使用与{appName}相同的组。", "ChmodFolderHelpTextWarning": "仅当运行 {appName} 程序的用户是文件所有者的情况下才有效。最好确保下载客户端正确设置权限。", @@ -848,7 +848,7 @@ "NotificationsLoadError": "无法加载通知连接", "QualityDefinitionsLoadError": "无法加载质量定义", "Ungroup": "未分组", - "UpdateAutomaticallyHelpText": "自动下载并安装更新。你还可以在“系统:更新”中安装", + "UpdateAutomaticallyHelpText": "自动下载并安装更新。您还可以在「“系统”->“更新”」中安装", "UpdateCheckStartupNotWritableMessage": "无法安装更新,因为用户 “{userName}” 对启动文件夹 “{startupFolder}” 无写入权限。", "UpdateCheckStartupTranslocationMessage": "无法安装更新,因为启动文件夹 “{startupFolder}” 位于 App Translocation 文件夹中。", "UpdateScriptPathHelpText": "自定义脚本的路径,该脚本处理获取的更新包并处理更新过程的其余部分", @@ -869,7 +869,7 @@ "WhitelistedHardcodedSubsHelpText": "这里设置的字幕标签不会被认为是硬编码的", "WhitelistedSubtitleTags": "白名单的字幕标签", "Wiki": "Wiki", - "WouldYouLikeToRestoreBackup": "是否要还原备份“{name}”?", + "WouldYouLikeToRestoreBackup": "是否要还原备份 “{name}”?", "LaunchBrowserHelpText": " 启动浏览器时导航到{appName}主页。", "ReleaseBranchCheckOfficialBranchMessage": "分支 {0} 不是合法的{appName}发布分支,您不会收到任何更新", "RejectionCount": "拒绝次数", @@ -886,7 +886,7 @@ "ProxyUsernameHelpText": "如果需要,您只需要输入用户名和密码。否则就让它们为空。", "ProxyPasswordHelpText": "如果需要,您只需要输入用户名和密码,否则就让它们为空。", "ProxyCheckResolveIpMessage": "无法解析已设置的代理服务器主机{proxyHostName}的IP地址", - "ProxyBypassFilterHelpText": "使用“ , ”作为分隔符,和“ *. ”作为二级域名的通配符", + "ProxyBypassFilterHelpText": "使用 “ , ” 作为分隔符,并使用 “ *. ” 作为二级域名的通配符", "ProtocolHelpText": "在其他相同版本之间进行选择时,选择要使用的协议以及首选的协议", "Proper": "合适的", "Profiles": "配置", @@ -931,13 +931,13 @@ "FeatureRequests": "功能建议", "Extension": "扩展", "Discord": "Discord", - "CustomFormatUnknownConditionOption": "条件“{implementation}”的未知选项“{key}”", + "CustomFormatUnknownConditionOption": "条件 “{implementation}” 的未知选项 “{key}”", "Retention": "保留", "ChownGroupHelpText": "组名称或GID。对于远程文件系统请使用GID。", "MinAvailability": "最小可用性", "RequiredHelpText": "此 {implementationName} 条件必须满足才能应用自定义格式。否则,只需匹配任一 {implementationName} 即可。", "QualitiesHelpText": "即使未选中,列表中的质量排序越高优先级也越高。同组内的质量优先级相同。质量只有选中才标记为需要", - "DownloadPropersAndRepacksHelpTextCustomFormat": "使用“不喜欢”按Propers / Repacks中的自定义格式分数排序", + "DownloadPropersAndRepacksHelpTextCustomFormat": "使用 “不喜欢” 按自定义格式分数对 Propers/Repacks 排序", "LookingForReleaseProfiles1": "在寻找发布资源配置?试试这个", "QualityLimitsMovieRuntimeHelpText": "限制会根据电影的播放时长自动调整。", "QualitySettingsSummary": "质量标准和命名", @@ -986,7 +986,7 @@ "RemoveSelectedItem": "移除选中项", "RemoveSelectedItems": "移除选中项", "TaskUserAgentTooltip": "由调用API的应用程序提供的User-Agent", - "BypassDelayIfHighestQualityHelpText": "当发布资源的质量为“质量配置”中最高启用质量且为首选协议时,忽略延迟", + "BypassDelayIfHighestQualityHelpText": "当发布资源的质量为 “质量配置” 中最高启用质量且为首选协议时,忽略延迟", "RemoveCompleted": "移除成功", "RemoveDownloadsAlert": "移除设置被移至上表中的单个下载客户端设置。", "RemoveFailed": "移除失败", @@ -1051,7 +1051,7 @@ "ApplicationURL": "应用程序 URL", "BindAddressHelpText": "有效的 IP 地址、localhost、或以'*'代表所有接口", "PreferredProtocol": "首选协议", - "ThemeHelpText": "更改程序界面主题,“自动”主题将根据您的操作系统主题来设置浅色或深色模式。灵感来自Theme.Park", + "ThemeHelpText": "更改程序界面主题,“自动” 主题将根据您的操作系统主题来设置浅色或深色模式。灵感来自 Theme.Park", "ResetDefinitions": "重置定义", "ResetQualityDefinitions": "重置质量定义", "ResetTitles": "重置标题", @@ -1072,16 +1072,16 @@ "DeleteRemotePathMapping": "删除远程路径映射", "Complete": "完成", "DeleteCondition": "删除条件", - "DeleteConditionMessageText": "你确定要删除条件 “{name}” 吗?", + "DeleteConditionMessageText": "您确定要删除条件 “{name}” 吗?", "DeleteDelayProfileMessageText": "你确定要删除此延迟配置吗?", - "DeleteCustomFormatMessageText": "您确定要删除自定义格式“{name}”吗?", + "DeleteCustomFormatMessageText": "您确定要删除自定义格式 “{name}” 吗?", "DeleteRemotePathMappingMessageText": "您确认要删除此远程路径映射吗?", "ImportScriptPath": "导入脚本路径", "ImportUsingScript": "使用脚本导入", "ListRefreshInterval": "列表刷新间隔", "CloneCondition": "克隆条件", "ApiKeyValidationHealthCheckMessage": "请将API密钥更新为至少 {length} 个字符长。您可以通过设置或配置文件完成此操作", - "DeleteFormatMessageText": "你确定要删除格式标签 “{0}” 吗?", + "DeleteFormatMessageText": "您确定要删除格式标签 “{0}” 吗?", "DeleteImportListExclusionMessageText": "你确定要删除这个导入排除列表吗?", "NoIndexersFound": "未找到索引器", "Popularity": "人气", @@ -1145,9 +1145,9 @@ "AddConnectionImplementation": "添加连接- {implementationName}", "AuthenticationRequiredWarning": "为防止未经认证的远程访问,{appName} 现需要启用身份认证。您可以选择禁用本地地址的身份认证。", "CloneAutoTag": "复制自动标签", - "DeleteAutoTagHelpText": "你确定要删除 “{name}” 自动标签吗?", + "DeleteAutoTagHelpText": "您确定要删除 “{name}” 自动标签吗?", "DeleteAutoTag": "删除自动标签", - "DeleteRootFolderMessageText": "你确定要删除根目录 “{path}” 吗?", + "DeleteRootFolderMessageText": "您确定要删除根目录 “{path}” 吗?", "AddConditionImplementation": "添加条件 - {implementationName}", "AddImportList": "添加导入列表", "AddImportListImplementation": "添加导入列表- {implementationName}", @@ -1163,7 +1163,7 @@ "AutomaticUpdatesDisabledDocker": "使用 Docker 更新机制时,自动更新不被直接支持。您需要在 {appName} 之外更新容器镜像,或使用脚本进行更新", "BypassDelayIfAboveCustomFormatScore": "若高于自定义格式分数则绕过", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "最小自定义格式分数", - "DeleteQualityProfileMessageText": "您确定要删除质量配置“{name}”吗?", + "DeleteQualityProfileMessageText": "您确定要删除质量配置 “{name}” 吗?", "DeleteImportListMessageText": "您确定要删除列表 “{name}” 吗?", "AutoTaggingRequiredHelpText": "此 {implementationName} 条件必须匹配才能应用自动标记规则。否则,单个 {implementationName} 匹配就足够了。", "AuthenticationMethod": "认证方式", @@ -1203,7 +1203,7 @@ "FullColorEventsHelpText": "改变样式,用状态颜色为整个事件着色,而不仅仅是左边缘。不适用于议程", "HistoryLoadError": "无法加载历史记录", "InfoUrl": "信息 URL", - "InvalidUILanguage": "您的UI设置为无效语言,请纠正并保存设置", + "InvalidUILanguage": "您的 UI 设置为无效语言,请纠正并保存设置", "LanguagesLoadError": "无法加载语言", "DownloadFailedMovieTooltip": "电影下载失败", "DownloadIgnoredMovieTooltip": "电影下载被忽略", @@ -1281,7 +1281,7 @@ "ParseModalErrorParsing": "解析错误,请重试。", "Rejections": "拒绝", "RemoveQueueItem": "移除 - {sourceTitle}", - "RemoveQueueItemConfirmation": "您确认要从队列中移除 “{sourceTitle}” 吗?", + "RemoveQueueItemConfirmation": "您确定要从队列中移除 “{sourceTitle}” 吗?", "RemoveTagsAutomatically": "自动移除标签", "SelectFolderModalTitle": "{modalTitle} - 选择文件夹", "SelectDropdown": "选择…", @@ -1378,7 +1378,7 @@ "NotificationsGotifySettingsServerHelpText": "Gotify 服务器 URL,包括 http(s):// 和端口(如果有)", "NotificationsJoinSettingsDeviceNames": "设备名称", "NotificationsJoinSettingsDeviceIds": "设备 ID", - "NotificationsJoinSettingsDeviceIdsHelpText": "弃用,请改用“设备名称”。通知要发给的设备的 ID,以括号分隔。留空则发给所有设备。", + "NotificationsJoinSettingsDeviceIdsHelpText": "弃用,请改用 “设备名称”。通知要发给的设备的 ID,以括号分隔。留空则发给所有设备。", "NotificationsKodiSettingAlwaysUpdate": "总是更新", "NotificationsKodiSettingAlwaysUpdateHelpText": "即使有视频正在播放也更新资源库?", "NotificationsKodiSettingsCleanLibrary": "清理资源库", @@ -1402,7 +1402,7 @@ "Menu": "菜单", "BlocklistAndSearchMultipleHint": "列入黑名单后开始多次搜索替换", "BlocklistOnlyHint": "无需一次搜索替换的黑名单", - "ChangeCategoryMultipleHint": "将下载从下载客户端更改为“导入后类别”", + "ChangeCategoryMultipleHint": "将下载客户端中的下载内容更改为 “导入后类别”", "DoNotBlocklist": "不要列入黑名单", "IgnoreDownloadHint": "阻止 {appName} 进一步处理此下载", "IgnoreDownload": "忽略下载", @@ -1414,12 +1414,12 @@ "BlocklistAndSearchHint": "列入黑名单后开始一次搜索替换", "BlocklistMultipleOnlyHint": "无需搜索替换的黑名单", "BlocklistOnly": "仅限黑名单", - "ChangeCategoryHint": "将下载从下载客户端更改为“导入后类别”", + "ChangeCategoryHint": "将下载客户端中的下载内容更改为 “导入后类别”", "CustomFormatsSpecificationRegularExpressionHelpText": "自定义格式正则表达式不区分大小写", "DoNotBlocklistHint": "删除而不列入黑名单", "IgnoreDownloads": "忽略下载", "RemoveMultipleFromDownloadClientHint": "从下载客户端删除下载和文件", - "RemoveQueueItemRemovalMethodHelpTextWarning": "“从下载客户端中移除”将从下载客户端中移除下载记录和文件。", + "RemoveQueueItemRemovalMethodHelpTextWarning": "“从下载客户端中移除” 将从下载客户端中移除下载记录和文件。", "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "即使种子的散列值被列入黑名单,某些索引器在 RSS 同步或者搜索期间可能无法正确拒绝它,启用此功能将允许在抓取种子之后但在将其发送到下载客户端之前拒绝它。", "CustomFormatsSpecificationRegularExpression": "正则表达式", "AddListExclusion": "添加列表排除项", @@ -1462,11 +1462,11 @@ "DownloadClientFloodSettingsPostImportTags": "导入后标签", "DownloadClientFloodSettingsPostImportTagsHelpText": "导入下载后附加标签。", "DownloadClientFreeboxSettingsAppId": "App ID", - "DownloadClientFreeboxSettingsAppIdHelpText": "创建访问 Freebox API 所需的 App ID(即“app_id”)", - "DownloadClientFreeboxUnableToReachFreeboxApi": "无法访问 Freebox API。 请检查“API 地址”的基础地址和版本。", + "DownloadClientFreeboxSettingsAppIdHelpText": "创建访问 Freebox API 所需的 App ID(即 “app_id”)", + "DownloadClientFreeboxUnableToReachFreeboxApi": "无法访问 Freebox API。 请检查 “API 地址” 的基础地址和版本。", "DownloadClientNzbgetSettingsAddPausedHelpText": "此选项至少需要 NzbGet 版本 16.0", "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "首先下载第一个和最后一个片段(qBittorrent 4.1.0+)", - "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} 将无法按照 “已完成下载处理” 配置执行。 您可以在 qBittorrent 中修复此问题(菜单中的 “工具 -> 选项...”),通过将 “选项 -> BitTorrent -> 分享率限制” 从 “删除种子” 更改为 “暂停种子”", + "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} 将无法按照 “已完成下载处理” 配置执行。 您可以在 qBittorrent 中修复此问题(菜单中的「 “工具 -> 选项...”」),通过将「“选项 -> BitTorrent -> 分享率限制”」从 “删除种子” 更改为 “暂停种子”", "DownloadClientRTorrentSettingsAddStopped": "添加后暂停", "DownloadClientRTorrentSettingsUrlPathHelpText": "XMLRPC 端点的路径,请参阅 {url}。 使用 ruTorrent 时,这通常是 RPC2 或 [ruTorrent 路径]{url2}。", "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "使用 “下载前检查” 会影响 {appName} 跟踪新下载内容的能力。 此外,Sabnzbd 建议启用 “中止无法完成的任务”,因为这样更有效。", @@ -1486,7 +1486,7 @@ "DownloadClientQbittorrentSettingsFirstAndLastFirst": "先下载首尾文件块", "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "按顺序下载文件(qBittorrent 4.1.0+)", "DownloadClientQbittorrentSettingsUseSslHelpText": "使用安全连接。 请参阅 qBittorrent 中的「选项 -> Web UI -> “使用 HTTPS 而不是 HTTP”」。", - "DownloadClientRTorrentProviderMessage": "当种子满足做种规则时,rTorrent 不会暂停做种。 仅当启用 “删除已完成项” 时,{appName} 才会根据 “设置 -> 索引器” 中的当前做种规则自动删除种子。 导入后,它还会将 {importedView} 设置为 rTorrent 视图,可以使用 rTorrent 脚本来自定义行为。", + "DownloadClientRTorrentProviderMessage": "当种子满足做种规则时,rTorrent 不会暂停做种。 仅当启用 “删除已完成项” 时,{appName} 才会根据「“设置 -> 索引器”」中的当前做种规则自动删除种子。 导入后,它还会将 {importedView} 设置为 rTorrent 视图,可以使用 rTorrent 脚本来自定义行为。", "DownloadClientRTorrentSettingsAddStoppedHelpText": "启用将在停止状态下向 rTorrent 添加 torrent 和磁力链接。 这可能会破坏磁力文件。", "DownloadClientSettingsInitialStateHelpText": "添加到 {clientName} 的种子初始状态", "DownloadClientValidationTestTorrents": "无法获取种子列表:{exceptionMessage}", @@ -1516,18 +1516,18 @@ "DownloadClientDownloadStationProviderMessage": "如果您的 DSM 账户启用了二步认证,{appName} 将无法连接到 Download Station", "DownloadClientFloodSettingsAdditionalTags": "附加标签", "DownloadClientFloodSettingsAddPaused": "添加并暂停", - "DownloadClientFloodSettingsRemovalInfo": "{appName} 将根据“设置”->“索引器”中的当前做种规则自动删除种子", + "DownloadClientFloodSettingsRemovalInfo": "{appName} 将根据「“设置”->“索引器”」中的当前做种规则自动删除种子", "DownloadClientFloodSettingsStartOnAdd": "添加并开始", "DownloadClientFloodSettingsTagsHelpText": "下载的初始标签。下载必须具有所有初始标签才可被识别。 这可以避免与不相关的下载发生冲突。", "DownloadClientFloodSettingsUrlBaseHelpText": "为 Flood API 添加前缀,例如 {url}", "DownloadClientFreeboxApiError": "Freebox API 返回错误:{errorDescription}", "DownloadClientFreeboxSettingsApiUrl": "API 地址", - "DownloadClientFreeboxSettingsApiUrlHelpText": "使用 API 版本定义 Freebox API 基本 URL,例如“{url}”,默认为“{defaultApiUrl}”", + "DownloadClientFreeboxSettingsApiUrlHelpText": "使用 API 版本定义 Freebox API 基本 URL,例如 “{url}”,默认为 “{defaultApiUrl}”", "DownloadClientFreeboxSettingsAppToken": "App Token", - "DownloadClientFreeboxSettingsAppTokenHelpText": "创建访问 Freebox API 所需的 App token(即“ app_token”)", - "DownloadClientFreeboxSettingsHostHelpText": "Freebox 的主机名或主机 IP 地址,默认为“{url}”(仅在同一网络上有效)", + "DownloadClientFreeboxSettingsAppTokenHelpText": "创建访问 Freebox API 所需的 App token(即 “ app_token”)", + "DownloadClientFreeboxSettingsHostHelpText": "Freebox 的主机名或主机 IP 地址,默认为 “{url}”(仅在同一网络上有效)", "DownloadClientFreeboxSettingsPortHelpText": "用于访问 Freebox 接口的端口,默认为 '{port}'", - "DownloadClientFreeboxUnableToReachFreebox": "无法访问 Freebox API。请检查“主机名”、“端口”或“使用 SSL”的设置(错误: {exceptionMessage})", + "DownloadClientFreeboxUnableToReachFreebox": "无法访问 Freebox API。请检查 “主机名”、“端口” 或 “使用 SSL” 的设置(错误: {exceptionMessage})", "DownloadClientNzbVortexMultipleFilesMessage": "下载包含多个文件且不在作业文件夹中:{outputPath}", "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "NzbGet 设置 KeepHistory 设置得太高。", "DownloadClientPneumaticSettingsNzbFolder": "Nzb 文件夹", @@ -1542,7 +1542,7 @@ "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "qBittorrent 版本 3.3.0 之前不支持分类。 请升级后重试或者留空。", "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent 配置为在达到共享比率限制时删除种子", "DownloadClientRTorrentSettingsDirectoryHelpText": "用于放置下载的可选位置,留空以使用默认的 rTorrent 位置", - "DownloadClientSabnzbdValidationCheckBeforeDownload": "禁用 Sabnbzd 中的“下载前检查”选项", + "DownloadClientSabnzbdValidationCheckBeforeDownload": "禁用 Sabnbzd 中的 “下载前检查” 选项", "DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd开发版本,假设版本3.0.0或更高。", "DownloadClientSabnzbdValidationEnableDisableDateSorting": "禁用日期排序", "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "您必须禁用 {appName} 使用的分类的日期排序,以防止出现导入问题。 在 Sabnzbd 修复它。", @@ -1576,7 +1576,7 @@ "UsenetBlackholeNzbFolder": "Nzb 文件夹", "XmlRpcPath": "XML RPC 路径", "NotificationsTwitterSettingsAccessToken": "访问令牌", - "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "用于磁力链接的扩展名,默认为“.magnet”", + "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "用于磁力链接的扩展名,默认为 “.magnet”", "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText": "这将指示 {appName} 进行复制或硬链接(取决于设置/系统配置),而不是移动文件", "TorrentBlackholeTorrentFolder": "种子文件夹", "UseSsl": "使用 SSL", @@ -1623,12 +1623,12 @@ "DownloadClientValidationTestNzbs": "无法获取 NZB 列表:{exceptionMessage}", "DownloadClientDownloadStationSettingsDirectoryHelpText": "用于存放下载内容的共享文件夹可选择,留空使用默认的 Download Station 位置", "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "您必须对 {appName} 使用的类别禁用电视节目排序,以防止出现导入问题。 去 Sabnzbd 修复它。", - "DownloadClientQbittorrentTorrentStatePathError": "无法导入。路径与客户端的基础下载目录匹配,可能是该种子的 “保留顶级文件夹” 功能已禁用,或 “种子内容布局” 未设置为 “原始” 或 “创建子文件夹”?", + "DownloadClientQbittorrentTorrentStatePathError": "无法导入。路径与客户端的基础下载目录匹配,可能是该种子的 “保留顶级文件夹” 功能被禁用,或 “种子内容布局” 未设置为 “原始” 或 “创建子文件夹”?", "DownloadClientQbittorrentTorrentStateStalled": "下载因无连接而停止", "DownloadClientQbittorrentTorrentStateUnknown": "未知下载状态:{state}", "DownloadClientQbittorrentValidationCategoryAddFailure": "分类配置失败", "DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName} 无法将标签添加到 qBittorrent。", - "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "您的 qBittorrent 设置中未启用 Torrent 队列。 在 qBittorrent 中启用它或选择“最后”作为优先级。", + "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "您的 qBittorrent 设置中未启用 Torrent 队列。 在 qBittorrent 中启用它或选择 “最后” 作为优先级。", "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubitleLanguages 支持 `:EN+DE` 后缀,允许您过滤在文件名中包含的语言。使用 `-DE` 可排除特定语言。附加 `+` (例如 `:EN+`)将输出 `[EN]`/`[EN+--]`/`[--]`,具体取决于排除的语言。例如 `{MediaInfo Full:EN+DE}`。", "NzbgetHistoryItemMessage": "PAR 状态:{parStatus} - 解压状态:{unpackStatus} - 移动状态:{moveStatus} - 脚本状态:{scriptStatus} - 删除状态:{deleteStatus} - 标记状态:{markStatus}", "TorrentBlackholeSaveMagnetFilesHelpText": "如果没有可用的 .torrent 文件,请保存磁力链接(仅当下载客户端支持保存到文件的磁力连接时才有用)", @@ -1763,7 +1763,7 @@ "NotificationsTwitterSettingsConsumerSecretHelpText": "来自 Twitter 应用的 Consumer Secret", "NotificationsTwitterSettingsDirectMessage": "私信", "NotificationsTwitterSettingsDirectMessageHelpText": "发送私信而非公共消息", - "NotificationsDiscordSettingsOnImportFieldsHelpText": "更改用于“导入”通知的字段", + "NotificationsDiscordSettingsOnImportFieldsHelpText": "更改用于 “导入” 通知的字段", "NotificationsSettingsWebhookMethodHelpText": "向 Web 服务提交数据时使用哪种 HTTP 方法", "NotificationsAppriseSettingsConfigurationKey": "Apprise 配置密钥", "NotificationsTwitterSettingsMentionHelpText": "在发送的推文中提及此用户", @@ -1778,7 +1778,7 @@ "NotificationsValidationInvalidHttpCredentials": "HTTP 认证凭据无效:{exceptionMessage}", "NotificationsValidationUnableToSendTestMessage": "无法发送测试消息:{exceptionMessage}", "OnExcludedList": "在排除列表中", - "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "更改用于“手动操作”通知的字段", + "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "更改用于 “手动操作” 通知的字段", "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} 路径,当 {serviceName} 与 {appName} 对资源库路径的识别不一致时,可以使用此设置修改系列路径(需要`更新资源库`)", "NotificationsSignalSettingsSenderNumberHelpText": "发送者在 Signal API 中注册的电话号码", "NoMovieFilesToManage": "未管理电影文件。", @@ -1811,7 +1811,7 @@ "NoBlocklistItems": "无黑名单项目", "NoCustomFormatsFound": "未找到自定义格式", "NotificationsDiscordSettingsOnImportFields": "导入时字段", - "NotificationsDiscordSettingsOnGrabFieldsHelpText": "更改用于“抓取”通知的字段", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "更改用于 “抓取” 通知的字段", "NotificationsDiscordSettingsOnManualInteractionFields": "手动操作时字段", "NotificationsPushoverSettingsSoundHelpText": "通知声音,留空使用默认声音", "ReleaseGroupFootNote": "可选参数,控制使用省略号(`...`)的最大截断字数。支持从末尾截断(例如:`{Movie Title:30}`)或从开头截断(例如:`{Movie Title:-30}`)。", @@ -1837,5 +1837,19 @@ "FolderNameTokens": "文件名标记", "ToggleMonitoredToUnmonitored": "已监视,单击可取消监视", "ToggleUnmonitoredToMonitored": "未监控,单击进行监控", - "DefaultNotFoundMessage": "你一定是迷路了,这里没什么可看的。" + "DefaultNotFoundMessage": "你一定是迷路了,这里没什么可看的。", + "Install": "安装", + "InstallMajorVersionUpdate": "安装更新", + "InstallMajorVersionUpdateMessageLink": "请查看 [{domain}]({url}) 以获取更多信息。", + "InstallMajorVersionUpdateMessage": "此更新将安装新的主要版本,这可能与您的系统不兼容。您确定要安装此更新吗?", + "MetadataSettingsMovieMetadata": "电影元数据", + "MetadataSettingsMovieMetadataLanguage": "电影元数据语言", + "MetadataSettingsMovieMetadataCollectionName": "电影合集名称", + "MetadataSettingsMovieMetadataNfo": "使用 movie.nfo", + "MetadataSettingsMovieMetadataUrl": "电影元数据 URL", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "在 .nfo 文件中包含合集名称", + "MetadataXmbcSettingsMovieMetadataHelpText": "包含电影所有元数据的 .nfo 文件", + "MetadataSettingsMovieImages": "电影图片", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "将元数据写入 movie.nfo 而非默认的 .nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "在 .nfo 文件中包含电影的 TMDb 和 IMDb URLs" } From 9aecf94e8e0e6b68711145a6669e780af09affe7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 26 Oct 2024 09:10:14 +0300 Subject: [PATCH 044/579] Bump version to 5.14.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index b40be13662..1fc1656985 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.13.1' + majorVersion: '5.14.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From c946ed83f958384200a41cc8e60623d80893ac26 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 22 Oct 2024 12:41:08 +0300 Subject: [PATCH 045/579] Fixed: Stopped/Started as initial state for qBittorrent v5.0 --- .../QBittorrent/QBittorrentProxySelector.cs | 2 - .../Clients/QBittorrent/QBittorrentProxyV1.cs | 24 ++--------- .../Clients/QBittorrent/QBittorrentProxyV2.cs | 40 +++++++------------ .../Clients/QBittorrent/QBittorrentState.cs | 9 ++++- 4 files changed, 27 insertions(+), 48 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs index 12d77a01f0..d9c6946fa9 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxySelector.cs @@ -25,8 +25,6 @@ public interface IQBittorrentProxy Dictionary GetLabels(QBittorrentSettings settings); void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, QBittorrentSettings settings); void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings); - void PauseTorrent(string hash, QBittorrentSettings settings); - void ResumeTorrent(string hash, QBittorrentSettings settings); void SetForceStart(string hash, bool enabled, QBittorrentSettings settings); } diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs index 8139983b09..948259af46 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV1.cs @@ -146,7 +146,7 @@ public void AddTorrentFromUrl(string torrentUrl, TorrentSeedConfiguration seedCo { request.AddFormParameter("paused", false); } - else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) + else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop) { request.AddFormParameter("paused", true); } @@ -176,7 +176,7 @@ public void AddTorrentFromFile(string fileName, byte[] fileContent, TorrentSeedC { request.AddFormParameter("paused", false); } - else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) + else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop) { request.AddFormParameter("paused", true); } @@ -212,7 +212,7 @@ public void SetTorrentLabel(string hash, string label, QBittorrentSettings setti catch (DownloadClientException ex) { // if setCategory fails due to method not being found, then try older setLabel command for qBittorrent < v.3.3.5 - if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound) + if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound) { var setLabelRequest = BuildRequest(settings).Resource("/command/setLabel") .Post() @@ -254,7 +254,7 @@ public void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings) catch (DownloadClientException ex) { // qBittorrent rejects all Prio commands with 403: Forbidden if Options -> BitTorrent -> Torrent Queueing is not enabled - if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Forbidden) + if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Forbidden) { return; } @@ -263,22 +263,6 @@ public void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings) } } - public void PauseTorrent(string hash, QBittorrentSettings settings) - { - var request = BuildRequest(settings).Resource("/command/pause") - .Post() - .AddFormParameter("hash", hash); - ProcessRequest(request, settings); - } - - public void ResumeTorrent(string hash, QBittorrentSettings settings) - { - var request = BuildRequest(settings).Resource("/command/resume") - .Post() - .AddFormParameter("hash", hash); - ProcessRequest(request, settings); - } - public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings) { var request = BuildRequest(settings).Resource("/command/setForceStart") diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs index 85795170f6..f85fb99e11 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs @@ -246,14 +246,20 @@ private void AddTorrentDownloadFormParameters(HttpRequestBuilder request, QBitto request.AddFormParameter("category", settings.MovieCategory); } - // Note: ForceStart is handled by separate api call - if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) + // Avoid extraneous API version check if initial state is ForceStart + if ((QBittorrentState)settings.InitialState is QBittorrentState.Start or QBittorrentState.Stop) { - request.AddFormParameter("paused", false); - } - else if ((QBittorrentState)settings.InitialState == QBittorrentState.Pause) - { - request.AddFormParameter("paused", true); + var stoppedParameterName = GetApiVersion(settings) >= new Version(2, 11, 0) ? "stopped" : "paused"; + + // Note: ForceStart is handled by separate api call + if ((QBittorrentState)settings.InitialState == QBittorrentState.Start) + { + request.AddFormParameter(stoppedParameterName, false); + } + else if ((QBittorrentState)settings.InitialState == QBittorrentState.Stop) + { + request.AddFormParameter(stoppedParameterName, true); + } } if (settings.SequentialOrder) @@ -291,7 +297,7 @@ public void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration catch (DownloadClientException ex) { // setShareLimits was added in api v2.0.1 so catch it case of the unlikely event that someone has api v2.0 - if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.NotFound) + if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.NotFound) { return; } @@ -313,7 +319,7 @@ public void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings) catch (DownloadClientException ex) { // qBittorrent rejects all Prio commands with 409: Conflict if Options -> BitTorrent -> Torrent Queueing is not enabled - if (ex.InnerException is HttpException && (ex.InnerException as HttpException).Response.StatusCode == HttpStatusCode.Conflict) + if (ex.InnerException is HttpException httpException && httpException.Response.StatusCode == HttpStatusCode.Conflict) { return; } @@ -322,22 +328,6 @@ public void MoveTorrentToTopInQueue(string hash, QBittorrentSettings settings) } } - public void PauseTorrent(string hash, QBittorrentSettings settings) - { - var request = BuildRequest(settings).Resource("/api/v2/torrents/pause") - .Post() - .AddFormParameter("hashes", hash); - ProcessRequest(request, settings); - } - - public void ResumeTorrent(string hash, QBittorrentSettings settings) - { - var request = BuildRequest(settings).Resource("/api/v2/torrents/resume") - .Post() - .AddFormParameter("hashes", hash); - ProcessRequest(request, settings); - } - public void SetForceStart(string hash, bool enabled, QBittorrentSettings settings) { var request = BuildRequest(settings).Resource("/api/v2/torrents/setForceStart") diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentState.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentState.cs index 56c5ddf1a9..b8fddbc117 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentState.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentState.cs @@ -1,9 +1,16 @@ +using NzbDrone.Core.Annotations; + namespace NzbDrone.Core.Download.Clients.QBittorrent { public enum QBittorrentState { + [FieldOption(Label = "Started")] Start = 0, + + [FieldOption(Label = "Force Started")] ForceStart = 1, - Pause = 2 + + [FieldOption(Label = "Stopped")] + Stop = 2 } } From 781e0c9d1c607ed35dd1595e929bf2a2e5009863 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 26 Oct 2024 14:32:33 +0300 Subject: [PATCH 046/579] Fixed: Optional square and round brackets for "{Release Year}" --- src/NzbDrone.Core/Organizer/FileNameBuilder.cs | 2 +- .../ApiTests/NamingConfigFixture.cs | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index b499da390d..1e865b543d 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -41,7 +41,7 @@ public class FileNameBuilder : IBuildFileNames private static readonly Regex TitleRegex = new Regex(@"(?\{(?:imdb-|edition-))?\{(?[- ._\[(]*)(?(?:[a-z0-9]+)(?:(?[- ._]+)(?:[a-z0-9]+))?)(?::(?[ ,a-z0-9|+-]+(?[-} ._)\]]*)\}", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); - public static readonly Regex ReleaseYearRegex = new Regex(@"\{Release[- ._]Year\}", RegexOptions.Compiled | RegexOptions.IgnoreCase); + public static readonly Regex ReleaseYearRegex = new Regex(@"\{[\[\(]?Release[- ._]Year[\]\)]?\}", RegexOptions.Compiled | RegexOptions.IgnoreCase); public static readonly Regex MovieTitleRegex = new Regex(@"(?\{(?:Movie)(?[- ._])(?:Clean)?(?:OriginalTitle|Title(?:The)?)(?::(?[a-z0-9|-]+))?\})", RegexOptions.Compiled | RegexOptions.IgnoreCase); diff --git a/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs index 47c0e82035..fb85bbacfa 100644 --- a/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs +++ b/src/NzbDrone.Integration.Test/ApiTests/NamingConfigFixture.cs @@ -20,12 +20,14 @@ public void should_be_able_to_get_by_id() NamingConfig.Get(config.Id).Id.Should().Be(config.Id); } - [Test] - public void should_be_able_to_update() + [TestCase("{Movie Title} {Release Year}")] + [TestCase("{Movie Title} {(Release Year)}")] + [TestCase("{Movie Title} {[Release Year]}")] + public void should_be_able_to_update(string standardMovieFormat) { var config = NamingConfig.GetSingle(); config.RenameMovies = false; - config.StandardMovieFormat = "{Movie Title} {Release Year}"; + config.StandardMovieFormat = standardMovieFormat; var result = NamingConfig.Put(config); result.RenameMovies.Should().BeFalse(); From d4993cf69b64b8472cdad92f59ff56e8091bc3bb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 26 Oct 2024 17:41:27 +0300 Subject: [PATCH 047/579] Bump version to 5.15.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 1fc1656985..6f8fc327ed 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.14.0' + majorVersion: '5.15.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 879c8721793d4d4e37a2ce42fa3384cd3cd47667 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 19 Oct 2024 06:25:54 +0300 Subject: [PATCH 048/579] Cleanse exceptions in event logs (cherry picked from commit 404e6d68ea526ab521cd39ecda1bf3b02285765d) --- .../Instrumentation/DatabaseTarget.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs index 896b274a6c..1c334a19c7 100644 --- a/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs +++ b/src/NzbDrone.Core/Instrumentation/DatabaseTarget.cs @@ -60,33 +60,36 @@ protected override void Write(LogEventInfo logEvent) { try { - var log = new Log(); - log.Time = logEvent.TimeStamp; - log.Message = CleanseLogMessage.Cleanse(logEvent.FormattedMessage); - - log.Logger = logEvent.LoggerName; + var log = new Log + { + Time = logEvent.TimeStamp, + Logger = logEvent.LoggerName, + Level = logEvent.Level.Name + }; if (log.Logger.StartsWith("NzbDrone.")) { log.Logger = log.Logger.Remove(0, 9); } + var message = logEvent.FormattedMessage; + if (logEvent.Exception != null) { - if (string.IsNullOrWhiteSpace(log.Message)) + if (string.IsNullOrWhiteSpace(message)) { - log.Message = logEvent.Exception.Message; + message = logEvent.Exception.Message; } else { - log.Message += ": " + logEvent.Exception.Message; + message += ": " + logEvent.Exception.Message; } - log.Exception = logEvent.Exception.ToString(); + log.Exception = CleanseLogMessage.Cleanse(logEvent.Exception.ToString()); log.ExceptionType = logEvent.Exception.GetType().ToString(); } - log.Level = logEvent.Level.Name; + log.Message = CleanseLogMessage.Cleanse(message); var connectionInfo = _connectionStringFactory.LogDbConnection; From 79cd6269f4cf393f8eac3051222f065a2566d011 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 27 Oct 2024 00:22:16 +0300 Subject: [PATCH 049/579] Fixed: Status check for completed directories in Deluge (cherry picked from commit 33139d4b53c1adad769c7e2b0510e8990c66b84a) --- .../DelugeTests/DelugeFixture.cs | 24 +++++++++++++++---- .../Download/Clients/Deluge/Deluge.cs | 13 ++++++++-- 2 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs index 89077fec04..8655141900 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/DelugeTests/DelugeFixture.cs @@ -312,11 +312,12 @@ public void GetItems_should_ignore_items_without_hash() [Test] public void should_return_status_with_outputdirs() { - var configItems = new Dictionary(); - - configItems.Add("download_location", @"C:\Downloads\Downloading\deluge".AsOsAgnostic()); - configItems.Add("move_completed_path", @"C:\Downloads\Finished\deluge".AsOsAgnostic()); - configItems.Add("move_completed", true); + var configItems = new Dictionary + { + { "download_location", @"C:\Downloads\Downloading\deluge".AsOsAgnostic() }, + { "move_completed_path", @"C:\Downloads\Finished\deluge".AsOsAgnostic() }, + { "move_completed", true } + }; Mocker.GetMock() .Setup(v => v.GetConfig(It.IsAny())) @@ -328,5 +329,18 @@ public void should_return_status_with_outputdirs() result.OutputRootFolders.Should().NotBeNull(); result.OutputRootFolders.First().Should().Be(@"C:\Downloads\Finished\deluge".AsOsAgnostic()); } + + [Test] + public void should_return_status_with_outputdirs_for_directories_in_settings() + { + Subject.Definition.Settings.As().DownloadDirectory = @"D:\Downloads\Downloading\deluge".AsOsAgnostic(); + Subject.Definition.Settings.As().CompletedDirectory = @"D:\Downloads\Finished\deluge".AsOsAgnostic(); + + var result = Subject.GetStatus(); + + result.IsLocalhost.Should().BeTrue(); + result.OutputRootFolders.Should().NotBeNull(); + result.OutputRootFolders.First().Should().Be(@"D:\Downloads\Finished\deluge".AsOsAgnostic()); + } } } diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index 02d7c0b7d7..8e4fba2e88 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -216,9 +216,18 @@ public override DownloadClientInfo GetStatus() { var config = _proxy.GetConfig(Settings); var label = _proxy.GetLabelOptions(Settings); + OsPath destDir; - if (label != null && label.ApplyMoveCompleted && label.MoveCompleted) + if (Settings.CompletedDirectory.IsNotNullOrWhiteSpace()) + { + destDir = new OsPath(Settings.CompletedDirectory); + } + else if (Settings.DownloadDirectory.IsNotNullOrWhiteSpace()) + { + destDir = new OsPath(Settings.DownloadDirectory); + } + else if (label is { ApplyMoveCompleted: true, MoveCompleted: true }) { // if label exists and a label completed path exists and is enabled use it instead of global destDir = new OsPath(label.MoveCompletedPath); @@ -234,7 +243,7 @@ public override DownloadClientInfo GetStatus() var status = new DownloadClientInfo { - IsLocalhost = Settings.Host == "127.0.0.1" || Settings.Host == "localhost" + IsLocalhost = Settings.Host is "127.0.0.1" or "localhost" }; if (!destDir.IsEmpty) From 63c6f70e677f45846fc3ac5da7ffd66341ba24fe Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 25 Oct 2024 09:42:55 +0300 Subject: [PATCH 050/579] Fixed: Changing movies to another root folder without moving files --- .../PathExtensionFixture.cs | 20 +++++++++++++++++++ .../Extensions/PathExtensions.cs | 2 +- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Common.Test/PathExtensionFixture.cs b/src/NzbDrone.Common.Test/PathExtensionFixture.cs index 13f28b681d..2c9d8f7a5a 100644 --- a/src/NzbDrone.Common.Test/PathExtensionFixture.cs +++ b/src/NzbDrone.Common.Test/PathExtensionFixture.cs @@ -413,5 +413,25 @@ public void unix_path_should_return_clean_path(string path, string cleanPath) { path.GetCleanPath().Should().Be(cleanPath); } + + [TestCase(@"C:\Test\", @"C:\Test\Series Title", "Series Title")] + [TestCase(@"C:\Test\", @"C:\Test\Collection\Series Title", @"Collection\Series Title")] + [TestCase(@"C:\Test\mydir\", @"C:\Test\mydir\Collection\Series Title", @"Collection\Series Title")] + [TestCase(@"\\server\share", @"\\server\share\Series Title", "Series Title")] + [TestCase(@"\\server\share\mydir\", @"\\server\share\mydir\/Collection\Series Title", @"Collection\Series Title")] + public void windows_path_should_return_relative_path(string parentPath, string childPath, string relativePath) + { + parentPath.GetRelativePath(childPath).Should().Be(relativePath); + } + + [TestCase(@"/test", "/test/Series Title", "Series Title")] + [TestCase(@"/test/", "/test/Collection/Series Title", "Collection/Series Title")] + [TestCase(@"/test/mydir", "/test/mydir/Series Title", "Series Title")] + [TestCase(@"/test/mydir/", "/test/mydir/Collection/Series Title", "Collection/Series Title")] + [TestCase(@"/test/mydir/", @"/test/mydir/\Collection/Series Title", "Collection/Series Title")] + public void unix_path_should_return_relative_path(string parentPath, string childPath, string relativePath) + { + parentPath.GetRelativePath(childPath).Should().Be(relativePath); + } } } diff --git a/src/NzbDrone.Common/Extensions/PathExtensions.cs b/src/NzbDrone.Common/Extensions/PathExtensions.cs index 865e25138f..cbf82e41cb 100644 --- a/src/NzbDrone.Common/Extensions/PathExtensions.cs +++ b/src/NzbDrone.Common/Extensions/PathExtensions.cs @@ -86,7 +86,7 @@ public static string GetRelativePath(this string parentPath, string childPath) throw new NotParentException("{0} is not a child of {1}", childPath, parentPath); } - return childPath.Substring(parentPath.Length).Trim(Path.DirectorySeparatorChar); + return childPath.Substring(parentPath.Length).Trim('\\', '/'); } public static string GetParentPath(this string childPath) From 25bb52b206847a56fed6361118435b297498e57f Mon Sep 17 00:00:00 2001 From: Hadrien Patte Date: Sat, 26 Oct 2024 23:14:20 +0200 Subject: [PATCH 051/579] Use `OperatingSystem` class to get OS information (cherry picked from commit 135b5c2ddd8f0a274b0d59eb07f75aaf1446b9da) --- src/NzbDrone.Common/EnvironmentInfo/OsInfo.cs | 87 ++++--------------- 1 file changed, 18 insertions(+), 69 deletions(-) diff --git a/src/NzbDrone.Common/EnvironmentInfo/OsInfo.cs b/src/NzbDrone.Common/EnvironmentInfo/OsInfo.cs index b9a206e4e3..aece278595 100644 --- a/src/NzbDrone.Common/EnvironmentInfo/OsInfo.cs +++ b/src/NzbDrone.Common/EnvironmentInfo/OsInfo.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using NLog; @@ -25,22 +24,25 @@ public class OsInfo : IOsInfo static OsInfo() { - var platform = Environment.OSVersion.Platform; - - switch (platform) + if (OperatingSystem.IsWindows()) { - case PlatformID.Win32NT: - { - Os = Os.Windows; - break; - } - - case PlatformID.MacOSX: - case PlatformID.Unix: - { - Os = GetPosixFlavour(); - break; - } + Os = Os.Windows; + } + else if (OperatingSystem.IsMacOS()) + { + Os = Os.Osx; + } + else if (OperatingSystem.IsFreeBSD()) + { + Os = Os.Bsd; + } + else + { +#if ISMUSL + Os = Os.LinuxMusl; +#else + Os = Os.Linux; +#endif } } @@ -84,59 +86,6 @@ public OsInfo(IEnumerable versionAdapters, Logger logger) IsDocker = true; } } - - private static Os GetPosixFlavour() - { - var output = RunAndCapture("uname", "-s"); - - if (output.StartsWith("Darwin")) - { - return Os.Osx; - } - else if (output.Contains("BSD")) - { - return Os.Bsd; - } - else - { -#if ISMUSL - return Os.LinuxMusl; -#else - return Os.Linux; -#endif - } - } - - private static string RunAndCapture(string filename, string args) - { - var processStartInfo = new ProcessStartInfo - { - FileName = filename, - Arguments = args, - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardOutput = true - }; - - var output = string.Empty; - - try - { - using (var p = Process.Start(processStartInfo)) - { - // To avoid deadlocks, always read the output stream first and then wait. - output = p.StandardOutput.ReadToEnd(); - - p.WaitForExit(1000); - } - } - catch (Exception) - { - output = string.Empty; - } - - return output; - } } public interface IOsInfo From ab8a2d190e3d173ebd99117190e8281b048c9cf5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 18 Oct 2024 05:45:03 +0300 Subject: [PATCH 052/579] Improve message for grab errors due to no matching tags Co-authored-by: zakary (cherry picked from commit df672487cf1d5f067849367a2bfb0068defc315d) Closes #10593 --- .../Download/DownloadClientProviderFixture.cs | 10 +--------- .../Download/DownloadClientProvider.cs | 15 ++++++++++----- 2 files changed, 11 insertions(+), 14 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientProviderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientProviderFixture.cs index cb326ba7a5..6733bcde87 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientProviderFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientProviderFixture.cs @@ -200,17 +200,9 @@ public void should_fail_to_choose_when_clients_have_tags_but_no_match() var seriesTags = new HashSet { 2 }; var clientTags = new HashSet { 1 }; - WithTorrentClient(0, clientTags); - WithTorrentClient(0, clientTags); - WithTorrentClient(0, clientTags); WithTorrentClient(0, clientTags); - var client1 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags); - var client2 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags); - var client3 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags); - var client4 = Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags); - - Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags).Should().BeNull(); + Assert.Throws(() => Subject.GetDownloadClient(DownloadProtocol.Torrent, 0, false, seriesTags)); } [Test] diff --git a/src/NzbDrone.Core/Download/DownloadClientProvider.cs b/src/NzbDrone.Core/Download/DownloadClientProvider.cs index 769928f2f2..9a4eb87955 100644 --- a/src/NzbDrone.Core/Download/DownloadClientProvider.cs +++ b/src/NzbDrone.Core/Download/DownloadClientProvider.cs @@ -41,18 +41,23 @@ public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int var blockedProviders = new HashSet(_downloadClientStatusService.GetBlockedProviders().Select(v => v.ProviderId)); var availableProviders = _downloadClientFactory.GetAvailableProviders().Where(v => v.Protocol == downloadProtocol).ToList(); - if (tags != null) + if (!availableProviders.Any()) + { + return null; + } + + if (tags is { Count: > 0 }) { var matchingTagsClients = availableProviders.Where(i => i.Definition.Tags.Intersect(tags).Any()).ToList(); availableProviders = matchingTagsClients.Count > 0 ? matchingTagsClients : availableProviders.Where(i => i.Definition.Tags.Empty()).ToList(); - } - if (!availableProviders.Any()) - { - return null; + if (!availableProviders.Any()) + { + throw new DownloadClientUnavailableException("No download client was found without tags or a matching movie tag. Please check your settings."); + } } if (indexerId > 0) From 0049ccd39f4e869dc2a5e3348a59130db562b9a5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 17 Oct 2024 04:46:15 +0300 Subject: [PATCH 053/579] Inherit trigger from pushed command models (cherry picked from commit 0bc4903954b955fce0c368ef7fd2a6f3761d6a93) Closes #10592 --- .../Messaging/Commands/CommandQueueManager.cs | 7 ++++--- src/Radarr.Api.V3/Commands/CommandController.cs | 3 +-- src/Radarr.Api.V3/Movies/MovieController.cs | 5 ++--- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs index 7be373e793..6f7f6d705e 100644 --- a/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs +++ b/src/NzbDrone.Core/Messaging/Commands/CommandQueueManager.cs @@ -106,6 +106,8 @@ public CommandModel Push(TCommand command, CommandPriority priority = _logger.Trace("Publishing {0}", command.Name); _logger.Trace("Checking if command is queued or started: {0}", command.Name); + command.Trigger = trigger; + lock (_commandQueue) { var existingCommands = QueuedOrStarted(command.Name); @@ -142,7 +144,6 @@ public CommandModel Push(string commandName, DateTime? lastExecutionTime, DateTi var command = GetCommand(commandName); command.LastExecutionTime = lastExecutionTime; command.LastStartTime = lastStartTime; - command.Trigger = trigger; return Push(command, priority, trigger); } @@ -244,13 +245,13 @@ public void CleanCommands() _repo.Trim(); } - private dynamic GetCommand(string commandName) + private Command GetCommand(string commandName) { commandName = commandName.Split('.').Last(); var commands = _knownTypes.GetImplementations(typeof(Command)); var commandType = commands.Single(c => c.Name.Equals(commandName, StringComparison.InvariantCultureIgnoreCase)); - return Json.Deserialize("{}", commandType); + return Json.Deserialize("{}", commandType) as Command; } private void Update(CommandModel command, CommandStatus status, string message) diff --git a/src/Radarr.Api.V3/Commands/CommandController.cs b/src/Radarr.Api.V3/Commands/CommandController.cs index 744f39c732..7a7436b008 100644 --- a/src/Radarr.Api.V3/Commands/CommandController.cs +++ b/src/Radarr.Api.V3/Commands/CommandController.cs @@ -66,9 +66,8 @@ public ActionResult StartCommand([FromBody] CommandResource com ? CommandPriority.High : CommandPriority.Normal; - dynamic command = STJson.Deserialize(body, commandType); + var command = STJson.Deserialize(body, commandType) as Command; - command.Trigger = CommandTrigger.Manual; command.SuppressMessages = !command.SendUpdatesToClient; command.SendUpdatesToClient = true; command.ClientUserAgent = Request.Headers["UserAgent"]; diff --git a/src/Radarr.Api.V3/Movies/MovieController.cs b/src/Radarr.Api.V3/Movies/MovieController.cs index dc3189a190..4392185476 100644 --- a/src/Radarr.Api.V3/Movies/MovieController.cs +++ b/src/Radarr.Api.V3/Movies/MovieController.cs @@ -274,9 +274,8 @@ public ActionResult UpdateMovie([FromBody] MovieResource moviesRe { MovieId = movie.Id, SourcePath = sourcePath, - DestinationPath = destinationPath, - Trigger = CommandTrigger.Manual - }); + DestinationPath = destinationPath + }, trigger: CommandTrigger.Manual); } var model = moviesResource.ToModel(movie); From 3708d58847d0ab89f3db285ee346483c9509deb1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 28 Oct 2024 07:49:55 +0200 Subject: [PATCH 054/579] Fixed: Custom filtering movies by year Fixes #10610 --- frontend/src/Components/Filter/Builder/FilterBuilderRowValue.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderRowValue.js b/frontend/src/Components/Filter/Builder/FilterBuilderRowValue.js index a3f5a22115..6ae3c23f42 100644 --- a/frontend/src/Components/Filter/Builder/FilterBuilderRowValue.js +++ b/frontend/src/Components/Filter/Builder/FilterBuilderRowValue.js @@ -58,7 +58,7 @@ function getValue(input, selectedFilterBuilderProp) { if (selectedFilterBuilderProp.type === filterBuilderTypes.NUMBER) { const { numberFractionDigits = 0 } = selectedFilterBuilderProp; - return Number(input).toFixed(numberFractionDigits); + return Number(Number(input).toFixed(numberFractionDigits)); } return input; From 06d54e0ec212cdc8646e766fed642a5583946a2f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 29 Oct 2024 10:00:57 +0200 Subject: [PATCH 055/579] Update JetBrains logos Closes #10603 --- Logo/dottrace.svg | 33 ----------------------- Logo/jetbrains.svg | 66 ---------------------------------------------- Logo/resharper.svg | 50 ----------------------------------- Logo/rider.svg | 42 ----------------------------- Logo/webstorm.svg | 36 ------------------------- README.md | 14 +++++----- 6 files changed, 7 insertions(+), 234 deletions(-) delete mode 100644 Logo/dottrace.svg delete mode 100644 Logo/jetbrains.svg delete mode 100644 Logo/resharper.svg delete mode 100644 Logo/rider.svg delete mode 100644 Logo/webstorm.svg diff --git a/Logo/dottrace.svg b/Logo/dottrace.svg deleted file mode 100644 index b879517cd0..0000000000 --- a/Logo/dottrace.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Logo/jetbrains.svg b/Logo/jetbrains.svg deleted file mode 100644 index 75d4d21771..0000000000 --- a/Logo/jetbrains.svg +++ /dev/null @@ -1,66 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Logo/resharper.svg b/Logo/resharper.svg deleted file mode 100644 index 24c987a780..0000000000 --- a/Logo/resharper.svg +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Logo/rider.svg b/Logo/rider.svg deleted file mode 100644 index 82da35b0b2..0000000000 --- a/Logo/rider.svg +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - rider - - - - - - - - - - - - - - diff --git a/Logo/webstorm.svg b/Logo/webstorm.svg deleted file mode 100644 index 39ab7eb973..0000000000 --- a/Logo/webstorm.svg +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/README.md b/README.md index 056625b3fd..ebde395ea0 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ Note that only one type of a given movie is supported. If you want both a 4k ver * Adding new movies with lots of information, such as trailers, ratings, etc. * Support for major platforms: Windows, Linux, macOS, Raspberry Pi, etc. -* Can watch for better quality of the movies you have and do an automatic upgrade. *e.g. from DVD to Blu-Ray* +* Can watch for better quality of the movies you have and do an automatic upgrade. _eg. from DVD to Blu-Ray_ * Automatic failed download handling will try another release if one fails * Manual search so you can pick any release or to see why a release was not downloaded automatically * Full integration with SABnzbd and NZBGet @@ -68,12 +68,12 @@ Support this project by becoming a sponsor. Your logo will show up here with a l ## JetBrains -Thank you to [JetBrains JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools. +Thank you to [JetBrains](http://www.jetbrains.com/) for providing us with free licenses to their great tools. -* [ReSharper ReSharper](http://www.jetbrains.com/resharper/) -* [WebStorm WebStorm](http://www.jetbrains.com/webstorm/) -* [Rider Rider](http://www.jetbrains.com/rider/) -* [dotTrace dotTrace](http://www.jetbrains.com/dottrace/) +* [ReSharper ReSharper](http://www.jetbrains.com/resharper/) +* [WebStorm WebStorm](http://www.jetbrains.com/webstorm/) +* [Rider Rider](http://www.jetbrains.com/rider/) +* [dotTrace dotTrace](http://www.jetbrains.com/dottrace/) ## DigitalOcean @@ -87,4 +87,4 @@ This project is also supported by DigitalOcean ### License * [GNU GPL v3](http://www.gnu.org/licenses/gpl.html) -* Copyright 2010-2022 +* Copyright 2010-2024 From 8f507ac726179c82de561bec9615272112f21149 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 29 Oct 2024 19:44:28 +0200 Subject: [PATCH 056/579] =?UTF-8?q?Fixed:=20Parse=20"Catal=C3=A0"=20and=20?= =?UTF-8?q?"Catal=C3=A1n"=20as=20Catalan?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ParserTests/LanguageParserFixture.cs | 4 ++++ src/NzbDrone.Core/Parser/LanguageParser.cs | 11 ++++++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 50830ac953..e1f3dae236 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -416,6 +416,10 @@ public void should_parse_language_spanish_latino(string postTitle) } [TestCase("Movie.Title.1994.Catalan.1080p.XviD-LOL")] + [TestCase("Movie.Title.2024.Catalán.1080p.XviD-LOL")] + [TestCase("Movie.Title.(2024).(Catala.Spanish.Subs).WEBRip.1080p.x264-EAC3")] + [TestCase("Movie.Title.(2024).(Spanish.Catala.English.Subs).BDRip.1080p.x264-EAC3")] + [TestCase("Movie Title [2024] [BDrip 1080p-x264-AC3 5.1 català-español-english+sub]")] public void should_parse_language_catalan(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 0abdc249c7..5fcf8acda8 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -31,6 +31,7 @@ public static class LanguageParser (?\[(?:CH[ST]|BIG5|GB)\]|简|繁|字幕)| (?(?:(?:\dx)?UKR))| (?\b(?:español|castellano)\b)| + (?\b(?:catalan?|catalán|català)\b)| (?\b(?:lat|lav|lv)\b)| (?\btel\b)| (?\bVIE\b)", @@ -208,11 +209,6 @@ public static List ParseLanguages(string title) languages.Add(Language.SpanishLatino); } - if (lowerTitle.Contains("catalan")) - { - languages.Add(Language.Catalan); - } - if (lowerTitle.Contains("tamil")) { languages.Add(Language.Tamil); @@ -348,6 +344,11 @@ public static List ParseLanguages(string title) languages.Add(Language.Spanish); } + if (match.Groups["catalan"].Success) + { + languages.Add(Language.Catalan); + } + if (match.Groups["ukrainian"].Success) { languages.Add(Language.Ukrainian); From b42f7e09f9fc29af05512cda1653b934658495f7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 31 Oct 2024 10:54:32 +0200 Subject: [PATCH 057/579] =?UTF-8?q?Fixed:=20Cleaning=20the=20French=20prep?= =?UTF-8?q?osition=20'=C3=A0'=20from=20titles?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/NzbDrone.Core.Test/ParserTests/NormalizeTitleFixture.cs | 2 ++ src/NzbDrone.Core/Parser/Parser.cs | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/NormalizeTitleFixture.cs b/src/NzbDrone.Core.Test/ParserTests/NormalizeTitleFixture.cs index 23631b51d9..565bb1e768 100644 --- a/src/NzbDrone.Core.Test/ParserTests/NormalizeTitleFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/NormalizeTitleFixture.cs @@ -26,6 +26,8 @@ public void should_normalize_series_title(string parsedSeriesName, string series [TestCase("24", "24")] [TestCase("I'm a cyborg, but that's OK", "imcyborgbutthatsok")] [TestCase("Im a cyborg, but thats ok", "imcyborgbutthatsok")] + [TestCase("Test: Something à Deux", "testsomethingdeux")] + [TestCase("Parler à", "parlera")] public void should_remove_special_characters_and_casing(string dirty, string clean) { var result = dirty.CleanMovieTitle(); diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 6fdf822b73..260a186d92 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -107,7 +107,7 @@ public static class Parser private static readonly Regex NormalizeAlternativeTitleRegex = new Regex(@"[ ]+(?:A\.K\.A\.)[ ]+", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex NormalizeRegex = new Regex(@"((?:\b|_)(? Date: Thu, 31 Oct 2024 17:16:33 +0200 Subject: [PATCH 058/579] Fixed: Loading queue with pending releases for deleted movies --- .../Datastore/Extensions/BuilderExtensions.cs | 9 +++++++++ .../Download/Pending/PendingReleaseRepository.cs | 7 ++++++- .../Download/Pending/PendingReleaseService.cs | 7 ++----- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs b/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs index e48ef63fcd..fe650a61cf 100644 --- a/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs +++ b/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs @@ -72,6 +72,15 @@ public static SqlBuilder LeftJoin(this SqlBuilder builder, Expres return builder.LeftJoin($"\"{rightTable}\" ON {wb.ToString()}"); } + public static SqlBuilder InnerJoin(this SqlBuilder builder, Expression> filter) + { + var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence); + + var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight)); + + return builder.InnerJoin($"\"{rightTable}\" ON {wb}"); + } + public static SqlBuilder GroupBy(this SqlBuilder builder, Expression> property) { var table = TableMapping.Mapper.TableNameMapping(typeof(TModel)); diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs index d38a382c14..232527ff8a 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseRepository.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using NzbDrone.Core.Datastore; using NzbDrone.Core.Messaging.Events; +using NzbDrone.Core.Movies; namespace NzbDrone.Core.Download.Pending { @@ -30,7 +31,11 @@ public List AllByMovieId(int movieId) public List WithoutFallback() { - return Query(x => x.Reason != PendingReleaseReason.Fallback); + var builder = new SqlBuilder(_database.DatabaseType) + .InnerJoin((p, m) => p.MovieId == m.Id) + .Where(p => p.Reason != PendingReleaseReason.Fallback); + + return Query(builder); } } } diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index d24e89cebc..9ea33e5ce9 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -254,10 +254,7 @@ private List IncludeRemoteMovies(List releases, { foreach (var movie in knownRemoteMovies.Values.Select(v => v.Movie)) { - if (!movieMap.ContainsKey(movie.Id)) - { - movieMap[movie.Id] = movie; - } + movieMap.TryAdd(movie.Id, movie); } } @@ -273,7 +270,7 @@ private List IncludeRemoteMovies(List releases, // Just in case the movie was removed, but wasn't cleaned up yet (housekeeper will clean it up) if (movie == null) { - return null; + continue; } // Languages will be empty if added before upgrading to v4, reparsing the languages if they're empty will set it to Unknown or better. From b5505800de3065b3a440cf074d2d8faeb0d8f31e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 2 Nov 2024 21:07:10 +0200 Subject: [PATCH 059/579] Fix file browser translations --- src/NzbDrone.Core/Localization/Core/ar.json | 4 ++-- src/NzbDrone.Core/Localization/Core/bg.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ca.json | 4 ++-- src/NzbDrone.Core/Localization/Core/cs.json | 4 ++-- src/NzbDrone.Core/Localization/Core/da.json | 4 ++-- src/NzbDrone.Core/Localization/Core/de.json | 4 ++-- src/NzbDrone.Core/Localization/Core/el.json | 4 ++-- src/NzbDrone.Core/Localization/Core/en.json | 5 +++-- src/NzbDrone.Core/Localization/Core/es.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fi.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/he.json | 4 ++-- src/NzbDrone.Core/Localization/Core/hi.json | 4 ++-- src/NzbDrone.Core/Localization/Core/hu.json | 4 ++-- src/NzbDrone.Core/Localization/Core/is.json | 4 ++-- src/NzbDrone.Core/Localization/Core/it.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ja.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ko.json | 4 ++-- src/NzbDrone.Core/Localization/Core/nl.json | 4 ++-- src/NzbDrone.Core/Localization/Core/pl.json | 4 ++-- src/NzbDrone.Core/Localization/Core/pt.json | 4 ++-- src/NzbDrone.Core/Localization/Core/pt_BR.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ro.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ru.json | 4 ++-- src/NzbDrone.Core/Localization/Core/sv.json | 4 ++-- src/NzbDrone.Core/Localization/Core/th.json | 4 ++-- src/NzbDrone.Core/Localization/Core/tr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/uk.json | 4 ++-- src/NzbDrone.Core/Localization/Core/vi.json | 4 ++-- src/NzbDrone.Core/Localization/Core/zh_CN.json | 4 ++-- 30 files changed, 61 insertions(+), 60 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 6857dfb034..03debb6de5 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -500,7 +500,7 @@ "Studio": "ستوديو", "Status": "الحالة", "StartupDirectory": "دليل بدء التشغيل", - "StartTypingOrSelectAPathBelow": "ابدأ الكتابة أو حدد المسار أدناه", + "FileBrowserPlaceholderText": "ابدأ الكتابة أو حدد المسار أدناه", "StartSearchForMissingMovie": "ابدأ البحث عن فيلم مفقود", "StartProcessing": "ابدأ المعالجة", "StartImport": "ابدأ الاستيراد", @@ -881,7 +881,7 @@ "MassMovieSearch": "البحث الشامل عن الأفلام", "MarkAsFailedMessageText": "هل أنت متأكد أنك تريد وضع علامة \"{0}\" على أنه فشل؟", "MarkAsFailed": "وضع علامة فشل", - "MappedDrivesRunningAsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات", + "MappedNetworkDrivesWindowsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات", "ManualImportSelectQuality": " استيراد يدوي - حدد الجودة", "ManualImportSelectMovie": "استيراد يدوي - حدد فيلم", "ManualImportSelectLanguage": "استيراد يدوي - حدد لغة", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index d2f71c5101..b396a65493 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -329,7 +329,7 @@ "ManualImportSelectLanguage": "Ръчно импортиране - Изберете език", "ManualImportSelectMovie": "Ръчно импортиране - Изберете филм", "ManualImportSelectQuality": " Ръчен импорт - Изберете качество", - "MappedDrivesRunningAsService": "Картографираните мрежови устройства не са налични, когато се изпълняват като услуга на Windows. Моля, вижте често задаваните въпроси за повече информация", + "MappedNetworkDrivesWindowsService": "Картографираните мрежови устройства не са налични, когато се изпълняват като услуга на Windows. Моля, вижте често задаваните въпроси за повече информация", "MarkAsFailedMessageText": "Наистина ли искате да маркирате „{0}“ като неуспешен?", "MassMovieSearch": "Масово търсене на филми", "MaximumLimits": "Максимални граници", @@ -921,7 +921,7 @@ "RestoreBackup": "Възстанови архива", "RootFolder": "Рут папка", "RootFolderCheckMultipleMessage": "Липсват множество коренни папки: {rootFolderPaths}", - "StartTypingOrSelectAPathBelow": "Започнете да пишете или изберете път отдолу", + "FileBrowserPlaceholderText": "Започнете да пишете или изберете път отдолу", "StartupDirectory": "Стартова директория", "System": "Система", "SystemTimeCheckMessage": "Системното време е изключено с повече от 1 ден. Планираните задачи може да не се изпълняват правилно, докато времето не бъде коригирано", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 5e941dfdc4..643729a68c 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -227,7 +227,7 @@ "Genres": "Gèneres", "DownloadClientOptionsLoadError": "No es poden carregar les opcions del client de baixada", "ImportList": "Llista", - "MappedDrivesRunningAsService": "Les unitats de xarxa assignades no estan disponibles quan s'executen com a servei de Windows. Si us plau, consulteu les PMF per a obtenir més informació", + "MappedNetworkDrivesWindowsService": "Les unitats de xarxa assignades no estan disponibles quan s'executen com a servei de Windows. Si us plau, consulteu les PMF per a obtenir més informació", "MissingMonitoredAndConsideredAvailable": "Absent (Monitorada)", "MissingNotMonitored": "Absent (No monitorada)", "Mode": "Mode", @@ -837,7 +837,7 @@ "SslPort": "Port SSL", "StartImport": "Inicieu la importació", "StartProcessing": "Inicieu el processament", - "StartTypingOrSelectAPathBelow": "Comenceu a escriure o seleccioneu un camí a continuació", + "FileBrowserPlaceholderText": "Comenceu a escriure o seleccioneu un camí a continuació", "StartupDirectory": "Directori d'inici", "Status": "Estat", "Studio": "Estudi", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 25d3f6a20f..b09adad33d 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -440,7 +440,7 @@ "RootFolder": "Kořenový adresář", "RootFolderCheckMultipleMessage": "Chybí více kořenových složek: {rootFolderPaths}", "SendAnonymousUsageData": "Odesílejte anonymní údaje o používání", - "StartTypingOrSelectAPathBelow": "Začněte psát nebo vyberte cestu níže", + "FileBrowserPlaceholderText": "Začněte psát nebo vyberte cestu níže", "StartupDirectory": "Spouštěcí adresář", "System": "Systém", "SystemTimeCheckMessage": "Systémový čas je vypnutý o více než 1 den. Naplánované úlohy nemusí fungovat správně, dokud nebude čas opraven", @@ -664,7 +664,7 @@ "ManualImportSelectLanguage": "Ruční import - vyberte jazyk", "ManualImportSelectMovie": "Ruční import - vyberte Film", "ManualImportSelectQuality": " Ruční import - vyberte kvalitu", - "MappedDrivesRunningAsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v častých dotazech", + "MappedNetworkDrivesWindowsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v častých dotazech", "MarkAsFailedMessageText": "Opravdu chcete označit „{0}“ jako neúspěšné?", "MassMovieSearch": "Hromadné vyhledávání filmů", "MaximumLimits": "Maximální limity", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 6b2b052f18..2fb9b755aa 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -132,7 +132,7 @@ "Images": "Billeder", "IndexerPriorityHelpText": "Indekseringsprioritet fra 1 (højest) til 50 (lavest). Standard: 25.", "LogLevelTraceHelpTextWarning": "Sporlogning bør kun aktiveres midlertidigt", - "MappedDrivesRunningAsService": "Tilsluttede netværksdrev er ikke tilgængelige, når programmet kører som en Windows-tjeneste. Se FAQ'en for mere information", + "MappedNetworkDrivesWindowsService": "Tilsluttede netværksdrev er ikke tilgængelige, når programmet kører som en Windows-tjeneste. Se FAQ'en for mere information", "MassMovieSearch": "Massefilmsøgning", "MIA": "MIA", "MonitoredOnly": "Kun overvåget", @@ -423,7 +423,7 @@ "RootFolder": "Rodmappe", "RootFolderCheckMultipleMessage": "Der mangler flere rodmapper: {rootFolderPaths}", "Level": "Niveau", - "StartTypingOrSelectAPathBelow": "Start med at skrive, eller vælg en sti nedenfor", + "FileBrowserPlaceholderText": "Start med at skrive, eller vælg en sti nedenfor", "StartupDirectory": "Startmappe", "MoviesSelectedInterp": "{0} Film (er) valgt", "MovieTitle": "Filmtitel", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 882beda7b8..32f52e0ce5 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -657,7 +657,7 @@ "AddDownloadClientError": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", "AddCustomFormatError": "Das neue eigene Format konnte nicht hinzugefügt werden, bitte erneut probieren.", "AddConditionError": "Die neue Bedingung konnte nicht hinzugefügt werden, bitte erneut probieren.", - "StartTypingOrSelectAPathBelow": "Eingeben oder unten auswählen", + "FileBrowserPlaceholderText": "Eingeben oder unten auswählen", "Restore": "Wiederherstellen", "RegularExpressionsCanBeTested": "Reguläre Ausdrücke können [hier](http://regexstorm.net/tester) getestet werden.", "SupportedCustomConditions": "Benutzerdefinierte Bedingungen gegen die unten aufgeführten Release-Eigenschaften werden unterstützt.", @@ -753,7 +753,7 @@ "ListSyncLevelHelpTextWarning": "Filmdateien werden dauerhaft gelöcht, dies kann deine ganze Mediathek leeren wenn deine Listen leer sind", "ConsideredAvailable": "Verfügbarkeit angenommen", "Announced": "Angekündigt", - "MappedDrivesRunningAsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", + "MappedNetworkDrivesWindowsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", "ChownGroupHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der {appName} ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die gleiche Gruppe wie {appName} verwendet.", "ChownGroupHelpText": "Gruppenname oder gid. Verwenden Sie gid für entfernte Dateisysteme.", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index d94c7426c8..5da8a5438f 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -428,7 +428,7 @@ "RootFolder": "Φάκελος ρίζας", "RootFolderCheckMultipleMessage": "Λείπουν πολλοί ριζικοί φάκελοι: {rootFolderPaths}", "SendAnonymousUsageData": "Αποστολή ανώνυμων δεδομένων χρήσης", - "StartTypingOrSelectAPathBelow": "Ξεκινήστε να πληκτρολογείτε ή επιλέξτε μια διαδρομή παρακάτω", + "FileBrowserPlaceholderText": "Ξεκινήστε να πληκτρολογείτε ή επιλέξτε μια διαδρομή παρακάτω", "StartupDirectory": "Κατάλογος εκκίνησης", "System": "Σύστημα", "SystemTimeCheckMessage": "Ο χρόνος συστήματος είναι απενεργοποιημένος για περισσότερο από 1 ημέρα. Οι προγραμματισμένες εργασίες ενδέχεται να μην εκτελούνται σωστά έως ότου διορθωθεί η ώρα", @@ -618,7 +618,7 @@ "Lowercase": "Πεζά", "ManualImportSelectLanguage": "Μη αυτόματη εισαγωγή - Επιλέξτε γλώσσα", "ManualImportSelectQuality": " Μη αυτόματη εισαγωγή - Επιλέξτε Ποιότητα", - "MappedDrivesRunningAsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες", + "MappedNetworkDrivesWindowsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες", "MarkAsFailedMessageText": "Είστε βέβαιοι ότι θέλετε να επισημάνετε \"{0}\" ως αποτυχημένο;", "MassMovieSearch": "Μαζική αναζήτηση ταινιών", "MaximumLimits": "Μέγιστα όρια", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 327929b089..86075d43a9 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -631,6 +631,8 @@ "False": "False", "FeatureRequests": "Feature Requests", "File": "File", + "FileBrowser": "File Browser", + "FileBrowserPlaceholderText": "Start typing or select a path below", "FileManagement": "File Management", "FileNameTokens": "File Name Tokens", "FileNames": "File Names", @@ -888,7 +890,7 @@ "ManualImportSelectMovie": "Manual Import - Select Movie", "ManualImportSelectQuality": " Manual Import - Select Quality", "ManualImportSetReleaseGroup": "Manual Import - Set Release Group", - "MappedDrivesRunningAsService": "Mapped network drives are not available when running as a Windows Service. Please see the FAQ for more information", + "MappedNetworkDrivesWindowsService": "Mapped network drives are not available when running as a Windows Service, see the [FAQ]({url}) for more information.", "MarkAsFailed": "Mark as Failed", "MarkAsFailedMessageText": "Are you sure you want to mark '{0}' as failed?", "MassMovieSearch": "Mass Movie Search", @@ -1673,7 +1675,6 @@ "StartImport": "Start Import", "StartProcessing": "Start Processing", "StartSearchForMissingMovie": "Start search for missing movie", - "StartTypingOrSelectAPathBelow": "Start typing or select a path below", "Started": "Started", "StartupDirectory": "Startup Directory", "Status": "Status", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 619326d2f3..fa59b6f31e 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -660,7 +660,7 @@ "AddCustomFormatError": "No se ha podido añadir un nuevo formato personalizado, prueba otra vez.", "AddConditionError": "No se ha podido añadir una nueva condición, prueba otra vez.", "TagIsNotUsedAndCanBeDeleted": "La etiqueta no se usa y puede ser borrada", - "StartTypingOrSelectAPathBelow": "Comienza a escribir o selecciona una ruta debajo", + "FileBrowserPlaceholderText": "Comienza a escribir o selecciona una ruta debajo", "Restore": "Restaurar", "RegularExpressionsCanBeTested": "Las expresiones regulares pueden ser probadas [aquí](http://regexstorm.net/tester).", "SupportedListsMovie": "{appName} soporta cualquier lista RSS de películas, como también la listada debajo.", @@ -762,7 +762,7 @@ "None": "Ninguno", "QualitiesHelpText": "Las calidades situadas más arriba en la lista son las preferidas aunque no estén marcadas. Las calidades del mismo grupo son iguales. Sólo se buscarán las calidades marcadas", "DeleteMovieFiles": "Eliminar {movieFileCount} archivos de película", - "MappedDrivesRunningAsService": "Las unidades de red asignadas no están disponibles cuando se ejecutan como un servicio de Windows. Consulta las preguntas frecuentes para obtener más información", + "MappedNetworkDrivesWindowsService": "Las unidades de red asignadas no están disponibles cuando se ejecutan como un servicio de Windows. Consulta las preguntas frecuentes para obtener más información", "RequiredRestrictionHelpText": "El lanzamiento debe contener al menos uno de estos términos (no distingue entre mayúsculas y minúsculas)", "Announced": "Anunciado", "BuiltIn": "Construido en", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index e78656b65c..18ad633400 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -46,7 +46,7 @@ "LinkHere": "tässä", "ListSyncLevelHelpText": "Kirjaston elokuvia käsitellään valinnan perusteella, jos ne poistuvat tai niitä ei löydy tuontilistoilta.", "ManualImportSelectMovie": "Manuaalinen tuonti - Valitse elokuva", - "MappedDrivesRunningAsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä kun sovellus suoritetaan Windows-palveluna. Saat lisätietoja UKK:sta.", + "MappedNetworkDrivesWindowsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä kun sovellus suoritetaan Windows-palveluna. Saat lisätietoja UKK:sta.", "MinimumAgeHelpText": "Vain Usenet: NZB:n vähimmäisikä minuutteina, ennen niiden kaappausta. Tämän avulla uusille julkaisuille voidaan antaa aikaa levitä Usenet-palveluntarjoajalle.", "MinimumFreeSpaceHelpText": "Estä tuonti, jos sen jälkeinen vapaa levytila olisi tässä määritettyä pienempi.", "MonitoredHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.", @@ -390,7 +390,7 @@ "Search": "Haku", "AddListExclusionMovieHelpText": "Estä {appName}ia lisäämästä elokuvaa listoilta.", "ImportListStatusCheckAllClientMessage": "Mitkään listat eivät ole virheiden vuoksi käytettävissä", - "StartTypingOrSelectAPathBelow": "Aloita kirjoitus tai valitse sijainti alta", + "FileBrowserPlaceholderText": "Aloita kirjoitus tai valitse sijainti alta", "StartupDirectory": "Käynnistyskansio", "System": "Järjestelmä", "SystemTimeCheckMessage": "Järjestelmän ajassa on ainakin vuorokauden heitto eivätkä ajoitetut tehtävät tämän vuoksi toimi oikein ennen kuin se on korjattu.", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 60945f4b3d..aad0637220 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -572,7 +572,7 @@ "TorrentDelay": "Retard du torrent", "TagIsNotUsedAndCanBeDeleted": "L'étiquette n'est pas utilisée et peut être supprimée", "ICalTagsMoviesHelpText": "S'applique aux films avec au moins une balise correspondante", - "StartTypingOrSelectAPathBelow": "Commencer à écrire ou sélectionner un chemin ci-dessous", + "FileBrowserPlaceholderText": "Commencer à écrire ou sélectionner un chemin ci-dessous", "ProtocolHelpText": "Choisissez quel(s) protocole(s) utiliser et lequel est préféré lorsque vous choisissez entre des versions par ailleurs égales", "PreferIndexerFlagsHelpText": "Prioriser les versions avec des indicateurs spéciaux", "PreferIndexerFlags": "Préférer les indicateurs d'indexation", @@ -839,7 +839,7 @@ "InCinemasMovieDescription": "Le film est dans les cinémas", "Lowercase": "Minuscule", "ManualImportSelectMovie": "Importation manuelle - Sélectionnez un film", - "MappedDrivesRunningAsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations", + "MappedNetworkDrivesWindowsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations", "RequiredRestrictionHelpText": "La version doit contenir au moins un de ces termes (insensible à la casse)", "InvalidFormat": "Format invalide", "LastExecution": "Dernière exécution", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index cbafc41604..23fd29ef72 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -389,7 +389,7 @@ "RestoreBackup": "שחזור גיבוי", "RootFolder": "תיקיית שורש", "RootFolderCheckMultipleMessage": "חסרות מספר תיקיות שורש: {rootFolderPaths}", - "StartTypingOrSelectAPathBelow": "התחל להקליד או בחר נתיב למטה", + "FileBrowserPlaceholderText": "התחל להקליד או בחר נתיב למטה", "Warn": "לְהַזהִיר", "StartupDirectory": "ספריית ההפעלה", "System": "מערכת", @@ -628,7 +628,7 @@ "ManualImportSelectLanguage": "יבוא ידני - בחר שפה", "ManualImportSelectMovie": "ייבוא ידני - בחר סרט", "ManualImportSelectQuality": " יבוא ידני - בחר איכות", - "MappedDrivesRunningAsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף", + "MappedNetworkDrivesWindowsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף", "MarkAsFailedMessageText": "האם אתה בטוח שברצונך לסמן את '{0}' ככושל?", "MassMovieSearch": "חיפוש סרטים המוני", "MaximumLimits": "מגבלות מקסימליות", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 7a23076ba9..6f837617a7 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -119,7 +119,7 @@ "LogOnly": "केवल लॉग करें", "ManualImportSelectLanguage": "मैनुअल आयात - भाषा का चयन करें", "ManualImportSelectMovie": "मैनुअल आयात - मूवी का चयन करें", - "MappedDrivesRunningAsService": "विंडोज सर्विस के रूप में चलने पर मैप्ड नेटवर्क ड्राइव उपलब्ध नहीं हैं। अधिक जानकारी के लिए कृपया FAQ देखें", + "MappedNetworkDrivesWindowsService": "विंडोज सर्विस के रूप में चलने पर मैप्ड नेटवर्क ड्राइव उपलब्ध नहीं हैं। अधिक जानकारी के लिए कृपया FAQ देखें", "MaximumSize": "अधिकतम आकार", "MegabytesPerMinute": "प्रति मिनट मेगाबाइट", "MetadataSettingsMovieSummary": "जब फ़िल्में आयात या ताज़ा की जाती हैं तो मेटाडेटा फ़ाइलें बनाएँ", @@ -565,7 +565,7 @@ "RestoreBackup": "बैकअप बहाल", "RootFolder": "मूल फ़ोल्डर", "RootFolderCheckMultipleMessage": "एकाधिक रूट फ़ोल्डर गायब हैं: {rootFolderPaths}", - "StartTypingOrSelectAPathBelow": "टाइप करना शुरू करें या नीचे एक पथ चुनें", + "FileBrowserPlaceholderText": "टाइप करना शुरू करें या नीचे एक पथ चुनें", "StartupDirectory": "स्टार्टअप निर्देशिका", "System": "प्रणाली", "SystemTimeCheckMessage": "सिस्टम का समय 1 दिन से अधिक बंद है। जब तक समय सही नहीं होगा तब तक शेड्यूल किए गए कार्य सही तरीके से नहीं चल सकते हैं", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 1ee068d311..d35b413d50 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -244,7 +244,7 @@ "Studio": "Stúdió", "Status": "Állapot", "StartupDirectory": "Indítási könyvtár", - "StartTypingOrSelectAPathBelow": "Kezdd el gépelni, vagy válassz az alábbi útvonalak közül", + "FileBrowserPlaceholderText": "Kezdd el gépelni, vagy válassz az alábbi útvonalak közül", "StartSearchForMissingMovie": "Indítsd el a hiányzó film(ek) keresését", "StartProcessing": "Indítsa el a feldolgozást", "StartImport": "Indítsa el az Importálást", @@ -761,7 +761,7 @@ "ListSyncLevelHelpTextWarning": "A filmfájlok véglegesen törlődnek, ez a könyvtár törlését eredményezheti, ha a listád üres", "ConsideredAvailable": "Feltételezhetően elérhető", "Announced": "Bejelentett", - "MappedDrivesRunningAsService": "A hozzárendelt hálózati meghajtók nem érhetők el, ha Windows szolgáltatásként futnak. További információkért olvasd át a GYIK-et", + "MappedNetworkDrivesWindowsService": "A hozzárendelt hálózati meghajtók nem érhetők el, ha Windows szolgáltatásként futnak. További információkért olvasd át a GYIK-et", "CouldNotConnectSignalR": "Nem sikerült csatlakozni a SignalR-hez, a felhasználói felület nem frissül", "ChownGroupHelpTextWarning": "Ez csak akkor működik, ha a {appName}t futtató felhasználó a fájl tulajdonosa. Jobb, ha a letöltési kliens ugyanazt a csoportot használja, mint a {appName}.", "ChownGroupHelpText": "Csoport neve vagy gid. A gid használata távoli fájlrendszerekhez.", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index f8c008fbfc..4a9251a1a2 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -424,7 +424,7 @@ "RestartRequiredHelpTextWarning": "Krefst endurræsingar til að taka gildi", "RootFolderCheckMultipleMessage": "Margar rótarmöppur vantar: {rootFolderPaths}", "SendAnonymousUsageData": "Sendu nafnlaus notkunargögn", - "StartTypingOrSelectAPathBelow": "Byrjaðu að slá eða veldu leið hér að neðan", + "FileBrowserPlaceholderText": "Byrjaðu að slá eða veldu leið hér að neðan", "StartupDirectory": "Ræsiskrá", "System": "Kerfi", "SystemTimeCheckMessage": "Slökkt er á tíma kerfisins meira en 1 dag. Skipulögð verkefni ganga kannski ekki rétt fyrr en tíminn er leiðréttur", @@ -663,7 +663,7 @@ "ManualImportSelectLanguage": "Handvirkur innflutningur - Veldu tungumál", "ManualImportSelectMovie": "Handvirkur innflutningur - Veldu kvikmynd", "ManualImportSelectQuality": " Handvirkur innflutningur - Veldu gæði", - "MappedDrivesRunningAsService": "Kortlagðar netdrif eru ekki fáanlegar þegar þær eru keyrðar sem Windows þjónusta. Vinsamlegast skoðaðu algengar spurningar fyrir frekari upplýsingar", + "MappedNetworkDrivesWindowsService": "Kortlagðar netdrif eru ekki fáanlegar þegar þær eru keyrðar sem Windows þjónusta. Vinsamlegast skoðaðu algengar spurningar fyrir frekari upplýsingar", "MarkAsFailedMessageText": "Ertu viss um að þú viljir merkja '{0}' sem mistókst?", "MaximumLimits": "Hámarksmörk", "MaximumSize": "Hámarksstærð", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index f862ea1b06..109a9f91a4 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -667,7 +667,7 @@ "SuggestTranslationChange": "Suggerisci un cambio nella traduzione", "SubfolderWillBeCreatedAutomaticallyInterp": "La sottocartella '{0}' verrà creata automaticamente", "StartupDirectory": "Cartella di Avvio", - "StartTypingOrSelectAPathBelow": "Comincia a digitare o seleziona un percorso sotto", + "FileBrowserPlaceholderText": "Comincia a digitare o seleziona un percorso sotto", "StandardMovieFormat": "Formato Film Standard", "SslPort": "Porta SSL", "SslCertPathHelpText": "Percorso file pfx", @@ -760,7 +760,7 @@ "MovieIsRecommend": "Il film è raccomandato in base alle aggiunte recenti", "ConsideredAvailable": "Considerato Disponibile", "Announced": "Annunciato", - "MappedDrivesRunningAsService": "Le unità di rete mappate non sono disponibili eseguendo come servizio di Windows. Vedere le FAQ per maggiori informazioni", + "MappedNetworkDrivesWindowsService": "Le unità di rete mappate non sono disponibili eseguendo come servizio di Windows. Vedere le FAQ per maggiori informazioni", "CouldNotConnectSignalR": "Non ho potuto connettermi a SignalR, l'interfaccia non si aggiornerà", "ChownGroupHelpTextWarning": "Funziona solo se l'utente di {appName} è il proprietario del file. E' meglio assicurarsi che il client di download usi lo stesso gruppo di {appName}.", "ChownGroupHelpText": "Nome del gruppo o gid. Usa gid per sistemi di file remoti.", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index a413424a4c..abc50e0b55 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -390,7 +390,7 @@ "RestoreBackup": "バックアップを復元", "RootFolder": "ルートフォルダ", "RootFolderCheckMultipleMessage": "複数のルートフォルダがありません:{rootFolderPaths}", - "StartTypingOrSelectAPathBelow": "入力を開始するか、以下のパスを選択してください", + "FileBrowserPlaceholderText": "入力を開始するか、以下のパスを選択してください", "StartupDirectory": "スタートアップディレクトリ", "System": "システム", "EditMovie": "映画の編集", @@ -615,7 +615,7 @@ "ManualImportSelectLanguage": "手動インポート-言語を選択", "ManualImportSelectMovie": "手動インポート-ムービーを選択", "ManualImportSelectQuality": " 手動インポート-品質を選択", - "MappedDrivesRunningAsService": "マップされたネットワークドライブは、Windowsサービスとして実行している場合は使用できません。詳細については、FAQを参照してください", + "MappedNetworkDrivesWindowsService": "マップされたネットワークドライブは、Windowsサービスとして実行している場合は使用できません。詳細については、FAQを参照してください", "MarkAsFailedMessageText": "'{0}'を失敗としてマークしてもよろしいですか?", "MassMovieSearch": "マスムービー検索", "MaximumLimits": "最大制限", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index b59b275f54..f4df924bb5 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -390,7 +390,7 @@ "RootFolder": "루트 폴더", "RootFolderCheckMultipleMessage": "여러 루트 폴더가 누락 됨 : {rootFolderPaths}", "SendAnonymousUsageData": "익명 사용 데이터 보내기", - "StartTypingOrSelectAPathBelow": "입력을 시작하거나 아래 경로를 선택하세요.", + "FileBrowserPlaceholderText": "입력을 시작하거나 아래 경로를 선택하세요.", "StartupDirectory": "시작 디렉토리", "System": "시스템", "SystemTimeCheckMessage": "시스템 시간이 1 일 이상 꺼져 있습니다. 예약 된 작업은 시간이 수정 될 때까지 올바르게 실행되지 않을 수 있습니다.", @@ -625,7 +625,7 @@ "ManualImportSelectLanguage": "수동 가져오기 - 언어 선택", "ManualImportSelectMovie": "수동 가져오기 - 동영상 선택", "ManualImportSelectQuality": " 수동 가져오기-품질 선택", - "MappedDrivesRunningAsService": "Windows 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다. 자세한 내용은 FAQ를 참조하십시오.", + "MappedNetworkDrivesWindowsService": "Windows 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다. 자세한 내용은 FAQ를 참조하십시오.", "MarkAsFailedMessageText": "'{0}'을(를) 실패한 것으로 표시 하시겠습니까?", "MassMovieSearch": "대량 영화 검색", "MaximumLimits": "최대 한도", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 8b9ed71a98..2ce6703479 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -680,7 +680,7 @@ "ApplyTagsHelpTextHowToApplyMovies": "Hoe tags toe te passen op de geselecteerd films", "BackupsLoadError": "Kon geen veiligheidskopieën laden", "TagIsNotUsedAndCanBeDeleted": "Tag is niet in gebruik en kan verwijderd worden", - "StartTypingOrSelectAPathBelow": "Begin met typen of selecteer een pad hier beneden", + "FileBrowserPlaceholderText": "Begin met typen of selecteer een pad hier beneden", "Restore": "Herstellen", "NoUpdatesAreAvailable": "Geen updates beschikbaar", "NoLogFiles": "Geen logbestanden", @@ -767,7 +767,7 @@ "MegabytesPerMinute": "Megabytes Per Minuut", "Medium": "Gemiddeld", "Max": "Max", - "MappedDrivesRunningAsService": "Toegewezen netwerkstation is niet beschikbaar wanneer Prowlarr wordt uitgevoerd als een Windows Service. Bekijk de Veelgestelde Vragen voor meer informatie", + "MappedNetworkDrivesWindowsService": "Toegewezen netwerkstation is niet beschikbaar wanneer Prowlarr wordt uitgevoerd als een Windows Service. Bekijk de Veelgestelde Vragen voor meer informatie", "ManualImportSelectQuality": " Manuele Import - Selecteer Kwaliteit", "ManualImportSelectLanguage": "Manuele import - Selecteer Taal", "ManualImportSelectMovie": "Manuele import - Selecteer Film", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 0fb3b07c9d..c43c73688d 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -386,7 +386,7 @@ "RootFolder": "Folder główny", "RootFolderCheckMultipleMessage": "Brakuje wielu folderów głównych: {rootFolderPaths}", "SendAnonymousUsageData": "Wysyłaj anonimowe dane dotyczące użytkowania", - "StartTypingOrSelectAPathBelow": "Zacznij pisać lub wybierz ścieżkę poniżej", + "FileBrowserPlaceholderText": "Zacznij pisać lub wybierz ścieżkę poniżej", "ApiKey": "Klucz API", "StartupDirectory": "Katalog Startowy", "AddImportListExclusion": "Dodaj wykluczenie z listy", @@ -640,7 +640,7 @@ "Lowercase": "Z małej litery", "ManualImportSelectLanguage": "Import ręczny - wybierz język", "ManualImportSelectMovie": "Import ręczny - wybierz film", - "MappedDrivesRunningAsService": "Zmapowane dyski sieciowe nie są dostępne, gdy działają jako usługa systemu Windows. Więcej informacji można znaleźć w FAQ", + "MappedNetworkDrivesWindowsService": "Zmapowane dyski sieciowe nie są dostępne, gdy działają jako usługa systemu Windows. Więcej informacji można znaleźć w FAQ", "MassMovieSearch": "Masowe wyszukiwanie filmów", "MaximumLimits": "Maksymalne limity", "MaximumSize": "Największy rozmiar", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index f3f5601c38..ecf70ee3c2 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -613,7 +613,7 @@ "ICalTagsMoviesHelpText": "Aplica-se a filmes com pelo menos uma etiqueta correspondente", "TagIsNotUsedAndCanBeDeleted": "A etiqueta não é utilizada e pode ser eliminada", "SubfolderWillBeCreatedAutomaticallyInterp": "A subpasta \"{0}\" será criada automaticamente", - "StartTypingOrSelectAPathBelow": "Começa a digitar ou seleciona um caminho abaixo", + "FileBrowserPlaceholderText": "Começa a digitar ou seleciona um caminho abaixo", "StandardMovieFormat": "Formato padrão de filme", "SslCertPathHelpText": "Caminho para o ficheiro PFX", "SslCertPath": "Caminho do certificado SSL", @@ -879,7 +879,7 @@ "ManualImportSelectLanguage": "Importação manual - Seleciona o idioma", "ManualImportSelectMovie": "Importação manual - Seleciona o filme", "ManualImportSelectQuality": " Importação manual - Seleciona a qualidade", - "MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Veja as Perguntas mais frequentes para obter mais informações", + "MappedNetworkDrivesWindowsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Veja as Perguntas mais frequentes para obter mais informações", "MegabytesPerMinute": "Megabytes por minuto", "Min": "Mín.", "MinimumCustomFormatScore": "Pontuação mínima de formato personalizado", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index fffe034da3..dc70d6ece4 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -390,7 +390,7 @@ "MassMovieSearch": "Pesquisar filmes em massa", "MarkAsFailed": "Marcar como falha", "MarkAsFailedMessageText": "Tem certeza que deseja marcar \"{0}\" como falhado?", - "MappedDrivesRunningAsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais", + "MappedNetworkDrivesWindowsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais", "ManualImportSelectQuality": " Importação manual - Selecionar qualidade", "ManualImportSelectMovie": "Importação manual - Selecionar filme", "ManualImportSelectLanguage": "Importação manual - Selecionar idioma", @@ -609,7 +609,7 @@ "Studio": "Studio", "Status": "Status", "StartupDirectory": "Diretório de Inicialização", - "StartTypingOrSelectAPathBelow": "Comece a digitar ou selecione um caminho abaixo", + "FileBrowserPlaceholderText": "Comece a digitar ou selecione um caminho abaixo", "StartSearchForMissingMovie": "Iniciar a pesquisa pelo filme ausente", "StartProcessing": "Iniciar Processamento", "StartImport": "Iniciar Importação", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 0ac903daaf..01fea72e92 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -288,7 +288,7 @@ "SupportedListsMoreInfo": "Pentru mai multe informații despre listele de import individuale, faceți clic pe butoanele de informații.", "LogLevelTraceHelpTextWarning": "Înregistrarea urmăririi trebuie activată doar temporar", "Lowercase": "Minuscule", - "MappedDrivesRunningAsService": "Unitățile de rețea mapate nu sunt disponibile atunci când rulează ca serviciu Windows. Vă rugăm să consultați FAQ pentru mai multe informații", + "MappedNetworkDrivesWindowsService": "Unitățile de rețea mapate nu sunt disponibile atunci când rulează ca serviciu Windows. Vă rugăm să consultați FAQ pentru mai multe informații", "MinutesHundredTwenty": "120 de minute: {0}", "MinutesNinety": "90 de minute: {0}", "Months": "Luni", @@ -558,7 +558,7 @@ "RestartRequiredHelpTextWarning": "Necesită repornire pentru a intra în vigoare", "Restore": "Restabili", "SendAnonymousUsageData": "Trimiteți date de utilizare anonime", - "StartTypingOrSelectAPathBelow": "Începeți să tastați sau selectați o cale de mai jos", + "FileBrowserPlaceholderText": "Începeți să tastați sau selectați o cale de mai jos", "StartupDirectory": "Director de pornire", "Posters": "Afise", "PosterSize": "Dimensiunea posterului", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index be0a922e09..a33d83c443 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -167,7 +167,7 @@ "LoadingMovieFilesFailed": "Неудачная загрузка файлов фильма", "Interval": "Интервал", "ManualImportSelectLanguage": "Ручной импорт - выбрать язык", - "MappedDrivesRunningAsService": "Сопоставленные сетевые диски недоступны при запуске в качестве службы Windows. См. FAQ для получения дополнительной информации", + "MappedNetworkDrivesWindowsService": "Сопоставленные сетевые диски недоступны при запуске в качестве службы Windows. См. FAQ для получения дополнительной информации", "DeleteDownloadClient": "Удалить клиент загрузки", "CouldNotConnectSignalR": "Не удалось подключиться к SignalR, интерфейс не будет обновляться", "DeleteRestriction": "Удалить ограничение", @@ -860,7 +860,7 @@ "Studio": "Студия", "Status": "Статус", "StartupDirectory": "Каталог автозапуска", - "StartTypingOrSelectAPathBelow": "Начните вводить или выберите путь ниже", + "FileBrowserPlaceholderText": "Начните вводить или выберите путь ниже", "StartSearchForMissingMovie": "Начать поиск пропавшего фильма", "StartProcessing": "Начать обработку", "StartImport": "Начать импорт", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 83dcf6ff35..d1550667a5 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -266,7 +266,7 @@ "Grab": "Hämta", "AgeWhenGrabbed": "Ålder (när den hämtades)", "Hostname": "Värdnamn", - "StartTypingOrSelectAPathBelow": "Börja skriva eller välj en sökväg nedan", + "FileBrowserPlaceholderText": "Börja skriva eller välj en sökväg nedan", "StartSearchForMissingMovie": "Börja söka efter saknad film", "StartProcessing": "Börja bearbeta", "StartImport": "Börja importera", @@ -817,7 +817,7 @@ "Lowercase": "Små bokstäver", "ManualImportSelectLanguage": "Manuell import - Välj språk", "ManualImportSelectMovie": "Manuell import - Välj film", - "MappedDrivesRunningAsService": "Mappade nätverksenheter är inte tillgängliga när de körs som en Windows-tjänst. Se FAQ för mer information", + "MappedNetworkDrivesWindowsService": "Mappade nätverksenheter är inte tillgängliga när de körs som en Windows-tjänst. Se FAQ för mer information", "MaximumLimits": "Maximala gränser", "MaximumSize": "Maximal storlek", "MegabytesPerMinute": "Megabyte per minut", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 5a5037e074..aae1f6923c 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -100,7 +100,7 @@ "LogLevel": "ระดับบันทึก", "LookingForReleaseProfiles1": "กำลังมองหาโปรไฟล์การเปิดตัว? ลอง", "ManualImportSelectMovie": "นำเข้าด้วยตนเอง - เลือกภาพยนตร์", - "MappedDrivesRunningAsService": "ไดรฟ์เครือข่ายที่แมปไม่พร้อมใช้งานเมื่อเรียกใช้เป็นบริการ Windows โปรดดูคำถามที่พบบ่อยสำหรับข้อมูลเพิ่มเติม", + "MappedNetworkDrivesWindowsService": "ไดรฟ์เครือข่ายที่แมปไม่พร้อมใช้งานเมื่อเรียกใช้เป็นบริการ Windows โปรดดูคำถามที่พบบ่อยสำหรับข้อมูลเพิ่มเติม", "MassMovieSearch": "ค้นหาภาพยนตร์จำนวนมาก", "ImportListExclusions": "รายการการยกเว้น", "Metadata": "ข้อมูลเมตา", @@ -491,7 +491,7 @@ "RestoreBackup": "คืนค่าการสำรองข้อมูล", "RootFolder": "โฟลเดอร์รูท", "RootFolderCheckMultipleMessage": "ไม่มีโฟลเดอร์รากหลายโฟลเดอร์: {rootFolderPaths}", - "StartTypingOrSelectAPathBelow": "เริ่มพิมพ์หรือเลือกเส้นทางด้านล่าง", + "FileBrowserPlaceholderText": "เริ่มพิมพ์หรือเลือกเส้นทางด้านล่าง", "StartupDirectory": "ไดเร็กทอรีเริ่มต้น", "System": "ระบบ", "SystemTimeCheckMessage": "เวลาของระบบปิดมากกว่า 1 วัน งานที่ตั้งเวลาไว้อาจทำงานไม่ถูกต้องจนกว่าจะมีการแก้ไขเวลา", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index bc2cfc65c7..e6aa725ce7 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -613,7 +613,7 @@ "Restore": "Onarmak", "RestoreBackup": "Yedeği Geri Yükle", "SendAnonymousUsageData": "Anonim Kullanım Verilerini Gönderin", - "StartTypingOrSelectAPathBelow": "Yazmaya başlayın veya aşağıdan bir yol seçin", + "FileBrowserPlaceholderText": "Yazmaya başlayın veya aşağıdan bir yol seçin", "StartupDirectory": "Başlangıç Dizini", "SystemTimeCheckMessage": "Sistem saati 1 günden fazla kapalı. Zamanlanan görevler, saat düzeltilene kadar doğru çalışmayabilir", "Posters": "Posterler", @@ -801,7 +801,7 @@ "ManualImportSelectLanguage": "Manuel İçe Aktar - Dil Seçin", "ManualImportSelectMovie": "Manuel İçe Aktar - Film Seçin", "ManualImportSelectQuality": " Manuel İçe Aktar - Kaliteyi Seçin", - "MappedDrivesRunningAsService": "Eşlenen ağ sürücüleri, bir Windows Hizmeti olarak çalışırken kullanılamaz. Daha fazla bilgi için lütfen SSS bölümüne bakın", + "MappedNetworkDrivesWindowsService": "Eşlenen ağ sürücüleri, bir Windows Hizmeti olarak çalışırken kullanılamaz. Daha fazla bilgi için lütfen SSS bölümüne bakın", "MarkAsFailedMessageText": "'{0}' başarısız olarak işaretlemek istediğinizden emin misiniz?", "MaximumLimits": "Maksimum Sınırlar", "MaximumSize": "En büyük boy", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 3882323ae0..bfa87bd864 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -666,7 +666,7 @@ "ManualImportSelectMovie": "Імпорт вручну - виберіть фільм", "ManualImportSelectQuality": " Імпорт вручну - Виберіть якість", "ManualImportSetReleaseGroup": "Імпорт вручну - встановити групу випуску", - "MappedDrivesRunningAsService": "Підключені мережеві диски недоступні під час роботи як служби Windows. Щоб отримати додаткову інформацію, перегляньте FAQ", + "MappedNetworkDrivesWindowsService": "Підключені мережеві диски недоступні під час роботи як служби Windows. Щоб отримати додаткову інформацію, перегляньте FAQ", "MarkAsFailed": "Позначити як помилку", "MarkAsFailedMessageText": "Ви впевнені, що бажаєте позначити \"{0}\" як невдале?", "MassMovieSearch": "Масовий пошук фільмів", @@ -846,7 +846,7 @@ "StandardMovieFormat": "Стандартний формат фільму", "Started": "Розпочато", "StartSearchForMissingMovie": "Почніть пошук зниклого фільму", - "StartTypingOrSelectAPathBelow": "Почніть вводити текст або виберіть шлях нижче", + "FileBrowserPlaceholderText": "Почніть вводити текст або виберіть шлях нижче", "Status": "Статус", "Studio": "Студія", "Style": "Стиль", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 6b074ca785..adbc44aed6 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -92,7 +92,7 @@ "ManualImportSelectLanguage": "Nhập thủ công - Chọn ngôn ngữ", "ManualImportSelectMovie": "Nhập thủ công - Chọn phim", "ManualImportSelectQuality": " Nhập thủ công - Chọn chất lượng", - "MappedDrivesRunningAsService": "Các ổ đĩa mạng được ánh xạ không khả dụng khi chạy dưới dạng Dịch vụ Windows. Vui lòng xem Câu hỏi thường gặp để biết thêm thông tin", + "MappedNetworkDrivesWindowsService": "Các ổ đĩa mạng được ánh xạ không khả dụng khi chạy dưới dạng Dịch vụ Windows. Vui lòng xem Câu hỏi thường gặp để biết thêm thông tin", "MarkAsFailedMessageText": "Bạn có chắc chắn muốn đánh dấu '{0}' là không thành công không?", "MassMovieSearch": "Tìm kiếm phim hàng loạt", "MaximumLimits": "Giới hạn tối đa", @@ -606,7 +606,7 @@ "RootFolder": "Thư mục gốc", "RootFolderCheckMultipleMessage": "Nhiều thư mục gốc bị thiếu: {rootFolderPaths}", "SendAnonymousUsageData": "Gửi dữ liệu sử dụng ẩn danh", - "StartTypingOrSelectAPathBelow": "Bắt đầu nhập hoặc chọn một đường dẫn bên dưới", + "FileBrowserPlaceholderText": "Bắt đầu nhập hoặc chọn một đường dẫn bên dưới", "StartupDirectory": "Thư mục khởi động", "System": "Hệ thống", "SystemTimeCheckMessage": "Thời gian hệ thống tắt hơn 1 ngày. Các tác vụ đã lên lịch có thể không chạy chính xác cho đến khi thời gian được sửa", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 0835c04f64..d3dd6a802a 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -760,7 +760,7 @@ "RadarrTags": "{appName} 标签", "QualityProfile": "质量配置", "RecentChanges": "最近修改", - "StartTypingOrSelectAPathBelow": "输入路径或者从下面选择", + "FileBrowserPlaceholderText": "输入路径或者从下面选择", "ImportRootPath": "将 {appName} 指向包含所有电影的文件夹,而非某部特定电影的文件夹。例如:“{0}” 而非 “{1}”。此外,每部电影必须在「根/资源库」目录中有独立文件夹。", "TableOptionsColumnsMessage": "选择显示哪些列并排序", "Forecast": "预报表", @@ -915,7 +915,7 @@ "MIA": "MIA", "MegabytesPerMinute": "每分钟MB", "Mechanism": "机制", - "MappedDrivesRunningAsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", + "MappedNetworkDrivesWindowsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", "LogOnly": "只有日志", "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", From d9f508280de74c48cf534c47fc6472edd011e0a6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 2 Nov 2024 19:08:27 +0000 Subject: [PATCH 060/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Co-authored-by: Daniel Co-authored-by: GkhnGRBZ Co-authored-by: HUi Co-authored-by: Kuzmich Co-authored-by: Moon55 Co-authored-by: Weblate Translate-URL: http://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/lv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 5 ++- src/NzbDrone.Core/Localization/Core/bg.json | 5 ++- src/NzbDrone.Core/Localization/Core/de.json | 3 +- src/NzbDrone.Core/Localization/Core/el.json | 4 +- src/NzbDrone.Core/Localization/Core/fr.json | 14 ++++++- src/NzbDrone.Core/Localization/Core/he.json | 5 ++- src/NzbDrone.Core/Localization/Core/hi.json | 5 ++- src/NzbDrone.Core/Localization/Core/hr.json | 4 +- src/NzbDrone.Core/Localization/Core/id.json | 4 +- src/NzbDrone.Core/Localization/Core/is.json | 5 ++- src/NzbDrone.Core/Localization/Core/ko.json | 5 ++- src/NzbDrone.Core/Localization/Core/lv.json | 3 +- .../Localization/Core/nb_NO.json | 4 +- src/NzbDrone.Core/Localization/Core/pl.json | 3 +- src/NzbDrone.Core/Localization/Core/ro.json | 4 +- src/NzbDrone.Core/Localization/Core/ru.json | 15 +++++--- src/NzbDrone.Core/Localization/Core/sk.json | 5 ++- src/NzbDrone.Core/Localization/Core/sv.json | 5 ++- src/NzbDrone.Core/Localization/Core/th.json | 5 ++- src/NzbDrone.Core/Localization/Core/tr.json | 38 ++++++++++++++++--- src/NzbDrone.Core/Localization/Core/vi.json | 38 ++++++++++++++++++- .../Localization/Core/zh_TW.json | 4 +- 22 files changed, 152 insertions(+), 31 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 03debb6de5..b00ff949bc 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1072,5 +1072,8 @@ "ShowDigitalReleaseHelpText": "عرض تاريخ الإصدار تحت الملصق", "ShowPhysicalRelease": "تاريخ الإصدار المادي", "ShowPhysicalReleaseHelpText": "عرض تاريخ الإصدار تحت الملصق", - "FolderNameTokens": "رموز اسم الملف" + "FolderNameTokens": "رموز اسم الملف", + "EditReleaseProfile": "تحرير ملف تعريف التأخير", + "Clone": "قريب", + "AllTitles": "كل الملفات" } diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index b396a65493..6d274927b2 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1069,5 +1069,8 @@ "ShowDigitalRelease": "Показване на датата на излизане на киното", "ShowDigitalReleaseHelpText": "Показване на датата на пускане под постер", "ShowPhysicalRelease": "Дата на физическото издаване", - "FolderNameTokens": "Токени за име на файл" + "FolderNameTokens": "Токени за име на файл", + "EditReleaseProfile": "Редактиране на профил за забавяне", + "Clone": "Близо", + "AllTitles": "Всички файлове" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 32f52e0ce5..f6e5af1851 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1468,5 +1468,6 @@ "FolderNameTokens": "Dateinamen Teile", "DefaultNotFoundMessage": "Sie müssen verloren sein, hier gibt es nichts zu sehen.", "ToggleMonitoredToUnmonitored": "Überwacht, klicken Sie, um die Überwachung aufzuheben", - "ToggleUnmonitoredToMonitored": "Nicht überwacht, klicke zum Überwachen" + "ToggleUnmonitoredToMonitored": "Nicht überwacht, klicke zum Überwachen", + "DownloadIgnored": "Importiere herunterladen" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 5da8a5438f..b5ce922fe2 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1231,5 +1231,7 @@ "ShowDigitalRelease": "Εμφάνιση ημερομηνίας κυκλοφορίας κινηματογράφου", "SmartReplace": "Έξυπνη Αντικατάσταση", "SmartReplaceHint": "Παύλα ή Κενό-Παύλα ανάλογα με το όνομα", - "FolderNameTokens": "Διακριτικά ονόματος αρχείου" + "FolderNameTokens": "Διακριτικά ονόματος αρχείου", + "DownloadIgnored": "Λήψη Εισήχθη", + "AllTitles": "Ολα τα αρχεία" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index aad0637220..c1f1001d5c 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1831,5 +1831,17 @@ "ToggleMonitoredToUnmonitored": "Surveillé, cliquez pour annuler la surveillance", "ToggleUnmonitoredToMonitored": "Non surveillé, cliquez pour surveiller", "OnFileImport": "Lors de l'importation du fichier", - "OnFileUpgrade": "Lors de la mise à jour du fichier" + "OnFileUpgrade": "Lors de la mise à jour du fichier", + "ShowTraktRating": "Affiche la note Trakt", + "ReleasedMovieAvailabilityDescription": "Les films sont considérés comme disponibles dès la sortie de la version Blu-Ray ou streaming.", + "LastSearched": "Dernière recherche", + "SkipFreeSpaceCheckHelpText": "Utiliser quand {appName} ne parvient pas à détecter l'espace disponible de votre dossier racine", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Inclure le nom de la collection dans le .nfo", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo avec les métadonnées complètes du film", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Inclure la langue sélectionnée si disponible dans le .nfo", + "MetadataSettingsMovieMetadata": "Métadonnées du film", + "MetadataSettingsMovieMetadataCollectionName": "Nom de la collection de films", + "MetadataSettingsMovieMetadataUrl": "Lien des métadonnées du film", + "InCinemasMovieAvailabilityDescription": "Les films sont considérés comme disponibles dès leur sortie en salles.", + "Disposition": "Disposition" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 23fd29ef72..f5ca3654b3 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1114,5 +1114,8 @@ "ShowPhysicalRelease": "תאריך שחרור פיזי", "ShowPhysicalReleaseHelpText": "הצג תאריך יציאה תחת הכרזה", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "מספר תיקיות אב חסרות לייבוא רשימות: {rootFoldersInfo}", - "FolderNameTokens": "אסימונים לשם קובץ" + "FolderNameTokens": "אסימונים לשם קובץ", + "AllTitles": "כל הקבצים", + "Clone": "סגור", + "EditReleaseProfile": "ערוך פרופיל עיכוב" } diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 6f837617a7..f4cb70953c 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1067,5 +1067,8 @@ "ShowPhysicalRelease": "शारीरिक रिलीज की तारीख", "ShowPhysicalReleaseHelpText": "पोस्टर के तहत रिलीज की तारीख दिखाएं", "ShowDigitalRelease": "सिनेमा रिलीज की तारीख दिखाएँ", - "FolderNameTokens": "फ़ाइल नाम टोकन" + "FolderNameTokens": "फ़ाइल नाम टोकन", + "Clone": "बंद करे", + "AllTitles": "सारे दस्तावेज", + "EditReleaseProfile": "देरी प्रोफ़ाइल संपादित करें" } diff --git a/src/NzbDrone.Core/Localization/Core/hr.json b/src/NzbDrone.Core/Localization/Core/hr.json index 70031a2e3b..0dca473e23 100644 --- a/src/NzbDrone.Core/Localization/Core/hr.json +++ b/src/NzbDrone.Core/Localization/Core/hr.json @@ -362,5 +362,7 @@ "EditIndexerImplementation": "Dodaj Indexer - {implementationName}", "EditConnectionImplementation": "Dodaj Vezu - {implementationName}", "EditConditionImplementation": "Dodaj Vezu - {implementationName}", - "DownloadFailed": "Ponovno preuzimanje neuspješno" + "DownloadFailed": "Ponovno preuzimanje neuspješno", + "Clone": "Zatvori", + "Reason": "Sezona" } diff --git a/src/NzbDrone.Core/Localization/Core/id.json b/src/NzbDrone.Core/Localization/Core/id.json index 831b04104b..232b2abad5 100644 --- a/src/NzbDrone.Core/Localization/Core/id.json +++ b/src/NzbDrone.Core/Localization/Core/id.json @@ -172,5 +172,7 @@ "File": "File", "Weeks": "Minggu", "ToggleMonitoredToUnmonitored": "Dimonitor, klik untuk berhenti monitor", - "ToggleUnmonitoredToMonitored": "Tidak dimonitor, klik untuk monitor" + "ToggleUnmonitoredToMonitored": "Tidak dimonitor, klik untuk monitor", + "Clone": "Tutup", + "EnableSsl": "Aktifkan RSS" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 4a9251a1a2..304c96c689 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1069,5 +1069,8 @@ "ShowDigitalReleaseHelpText": "Sýnið útgáfudagsetningu undir veggspjaldi", "ShowPhysicalRelease": "Líkamlegur útgáfudagur", "ShowPhysicalReleaseHelpText": "Sýnið útgáfudagsetningu undir veggspjaldi", - "FolderNameTokens": "Auðkenni skráarheita" + "FolderNameTokens": "Auðkenni skráarheita", + "Clone": "Lokaðu", + "EditReleaseProfile": "Breyta seinkunarprófíl", + "AllTitles": "Allar skrár" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index f4df924bb5..213786ada4 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1054,5 +1054,8 @@ "DeleteSelectedCustomFormats": "사용자 지정 형식 삭제", "ReleaseDate": "출시일", "MovieFileDeleted": "영화 파일 삭제", - "MovieFileDeletedTooltip": "영화 파일 삭제" + "MovieFileDeletedTooltip": "영화 파일 삭제", + "Clone": "닫기", + "EditReleaseProfile": "지연 프로필 편집", + "AllTitles": "모든 파일" } diff --git a/src/NzbDrone.Core/Localization/Core/lv.json b/src/NzbDrone.Core/Localization/Core/lv.json index 84a68135ad..af7943e7ed 100644 --- a/src/NzbDrone.Core/Localization/Core/lv.json +++ b/src/NzbDrone.Core/Localization/Core/lv.json @@ -22,5 +22,6 @@ "EditIndexerImplementation": "Pievienot Nosacījumu - {implementationName}", "EditConditionImplementation": "Pievienot Nosacījumu - {implementationName}", "ExportCustomFormat": "Pievienot Pielāgotu Formātu", - "New": "Jauns" + "New": "Jauns", + "EditReleaseProfile": "Pievienot Aizkaves Profilu" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index 76d54a8978..7c45bff0b7 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -317,5 +317,7 @@ "DeleteSelectedCustomFormats": "Klon egendefinert format", "DeleteSelectedCustomFormatsMessageText": "Er du sikker på at du vil slette formattaggen {0}?", "Discord": "Discord", - "TMDb": "TMDb" + "TMDb": "TMDb", + "Clone": "Lukk", + "Reason": "Sesong" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index c43c73688d..18a076608c 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1185,5 +1185,6 @@ "ShowPhysicalRelease": "Fizyczna data wydania", "ShowPhysicalReleaseHelpText": "Pokaż datę premiery pod plakatem", "YesterdayAt": "Wczoraj o {time}", - "FolderNameTokens": "Tokeny nazw plików" + "FolderNameTokens": "Tokeny nazw plików", + "Clone": "Zamknij" } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 01fea72e92..0929f79500 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1147,5 +1147,7 @@ "ShowPhysicalReleaseHelpText": "Afișați data lansării sub afiș", "FolderNameTokens": "Jetoane pentru nume de folder", "OnFileImport": "La import fișier", - "OnFileUpgrade": "La actualizare fișier" + "OnFileUpgrade": "La actualizare fișier", + "EditReleaseProfile": "Editați profilul de întârziere", + "Clone": "Închide" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index a33d83c443..c349dcbe96 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -205,7 +205,7 @@ "ListTagsHelpText": "Тэги листа будут добавлены с", "LoadingMovieCreditsFailed": "Неудачная загрузка информации о фильме", "CustomFormatsLoadError": "Невозможно загрузить Специальные Форматы", - "UpdateMechanismHelpText": "Использовать встроенный инструмент обновления {appName} или скрипт.", + "UpdateMechanismHelpText": "Использовать встроенный инструмент обновления {appName} или скрипт", "UpdateScriptPathHelpText": "Путь к пользовательскому скрипту, который извлекает пакет обновления и обрабатывает оставшуюся часть процесса обновления", "Add": "Добавить", "AddCustomFormat": "Добавить свой формат", @@ -262,7 +262,7 @@ "IndexerLongTermStatusCheckSingleClientMessage": "Все индексаторы недоступны из-за ошибок за последние 6 часов: {indexerNames}", "IndexerPriority": "Приоритет индексатора", "IndexerStatusCheckAllClientMessage": "Все индексаторы недоступны из-за ошибок", - "InstallLatest": "Установить последнюю версию", + "InstallLatest": "Установить последнюю", "InvalidFormat": "Неправильный формат", "KeepAndUnmonitorMovie": "Оставить фильм и не отслеживать", "LanguageHelpText": "Язык релизов", @@ -609,7 +609,7 @@ "ExtraFileExtensionsHelpText": "Список дополнительных файлов для импорта, разделенных запятыми (.nfo будет импортирован как .nfo-orig)", "ExternalUpdater": "{appName} настроен на использование внешнего механизма обновления", "Extension": "Расширение", - "ErrorRestoringBackup": "Восстановить резервную копию", + "ErrorRestoringBackup": "Ошибка восстановления резервной копии", "EnableColorImpairedModeHelpText": "Измененный стиль, позволяющий пользователям с нарушением цвета лучше различать информацию с цветовой кодировкой", "EnableColorImpairedMode": "Включить режим для слабовидящих", "EnableAutomaticSearchHelpText": "Будет использовано при автоматическом поиске через интерфейс или {appName}", @@ -1777,12 +1777,15 @@ "SmartReplaceHint": "Тире или пробел в зависимости от имени", "FolderNameTokens": "Токены имени файла", "Install": "Установить", - "InstallMajorVersionUpdateMessageLink": "Пожалуйста, проверьте [{domain}]({url}) для получения дополнительной информации.", + "InstallMajorVersionUpdateMessageLink": "Для получения дополнительной информации посетите [{domain}]({url}).", "InstallMajorVersionUpdate": "Установить обновление", - "InstallMajorVersionUpdateMessage": "Это обновление установит новую основную версию и может быть несовместимо с вашей системой. Вы уверены, что хотите установить это обновление?", + "InstallMajorVersionUpdateMessage": "Это обновление установит новую версию, которая может не поддерживаться вашей системой. Вы уверены, что хотите установить это обновление?", "DefaultNotFoundMessage": "Вы, должно быть, заблудились, здесь не на что смотреть.", "ToggleMonitoredToUnmonitored": "Отслеживается, нажмите, чтобы отключить отслеживание", "ToggleUnmonitoredToMonitored": "Не отслеживается, нажмите, чтобы отслеживать", "OnFileImport": "При импорте файла", - "OnFileUpgrade": "При обновлении файла" + "OnFileUpgrade": "При обновлении файла", + "AnnouncedMovieAvailabilityDescription": "Фильмы считаются доступными, как только они добавляются в {appName}.", + "CountCustomFormatsSelected": "{count} пользовательских форматов выбрано", + "CustomFormatsSpecificationExceptLanguage": "Исключить язык" } diff --git a/src/NzbDrone.Core/Localization/Core/sk.json b/src/NzbDrone.Core/Localization/Core/sk.json index 786cf80adb..2b89b291f0 100644 --- a/src/NzbDrone.Core/Localization/Core/sk.json +++ b/src/NzbDrone.Core/Localization/Core/sk.json @@ -295,5 +295,8 @@ "DeleteSelectedImportListExclusionsMessageText": "Naozaj chcete toto vylúčenie importného zoznamu zmazať?", "DeleteSelectedCustomFormats": "Klonovať vlastný formát", "Discord": "Discord", - "TMDb": "TMDb" + "TMDb": "TMDb", + "Reason": "Séria", + "Clone": "Zatvoriť", + "AllTitles": "Všetky súbory" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index d1550667a5..a622186022 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1095,5 +1095,8 @@ "ShowDigitalReleaseHelpText": "Visa släppdatum under affischen", "ShowPhysicalRelease": "Fysiskt utgivningsdatum", "ShowPhysicalReleaseHelpText": "Visa släppdatum under affischen", - "FolderNameTokens": "Filnamn tokens" + "FolderNameTokens": "Filnamn tokens", + "Clone": "Avsluta", + "AllTitles": "Samtliga filer", + "EditReleaseProfile": "Redigera fördröjningsprofil" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index aae1f6923c..2c27ee2655 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1067,5 +1067,8 @@ "ShowDigitalReleaseHelpText": "แสดงวันที่วางจำหน่ายใต้โปสเตอร์", "ShowPhysicalRelease": "วันที่วางจำหน่ายจริง", "ShowPhysicalReleaseHelpText": "แสดงวันที่วางจำหน่ายใต้โปสเตอร์", - "FolderNameTokens": "โทเค็นชื่อไฟล์" + "FolderNameTokens": "โทเค็นชื่อไฟล์", + "Clone": "ปิด", + "AllTitles": "เอกสารทั้งหมด", + "EditReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index e6aa725ce7..a15254e2e7 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -397,7 +397,7 @@ "DetailedProgressBar": "Ayrıntılı İlerleme Çubuğu", "EditGroups": "Grupları Düzenle", "ICalFeedHelpText": "Bu URL'yi müşterilerinize kopyalayın veya tarayıcınız webcal'i destekliyorsa abone olmak için tıklayın", - "ImportIncludeQuality": "Dosyalarınızın dosya adlarında kaliteyi içerdiğinden emin olun. Örneğin. {0}", + "ImportIncludeQuality": "Dosyalarınızın dosya adlarında kaliteyi içerdiğinden emin olun. Örneğin {0}", "Info": "Bilgi", "LastExecution": "Son Yürütme", "Max": "Max", @@ -708,7 +708,7 @@ "EditMovieFile": "Film Dosyasını Düzenle", "EditRemotePathMapping": "Uzak Yol Eşlemeyi Düzenle", "EditRestriction": "Kısıtlamayı Düzenle", - "Enable": "etkinleştirme", + "Enable": "Etkinleştir", "EnableAutomaticAddMovieHelpText": "Etkinleştirilirse, Filmler bu listeden {appName}'a otomatik olarak eklenecektir", "EnableAutomaticAdd": "Otomatik Eklemeyi Etkinleştir", "EnableAutomaticSearch": "Otomatik Aramayı Etkinleştir", @@ -1127,7 +1127,7 @@ "DownloadClientDownloadStationValidationFolderMissing": "Klasör mevcut değil", "DownloadClientDownloadStationValidationSharedFolderMissing": "Paylaşılan klasör mevcut değil", "DeleteReleaseProfile": "Yayımlama Profilini Sil", - "DeleteReleaseProfileMessageText": "'{name}' bu yayımlama profilini silmek istediğinizden emin misiniz?", + "DeleteReleaseProfileMessageText": "'{name}' sürüm profilini silmek istediğinizden emin misiniz?", "DelayMinutes": "{delay} Dakika", "DelayProfileMovieTagsHelpText": "En az bir eşleşen etiketli filmlere uygulanır", "DelayProfileProtocol": "Protokol: {preferredProtocol}", @@ -1755,7 +1755,7 @@ "IncludePopularMoviesHelpText": "Popüler filmleri TMDb'ye dahil edin", "IncludeTrending": "Trendleri Dahil Et", "IncludeTrendingMoviesHelpText": "Trend olan filmleri TMDb'ye dahil edin", - "NoMovieReleaseDatesAvailable": "Bu film için TMDb'de yayın tarihi yok.", + "NoMovieReleaseDatesAvailable": "Bu filmin [TMDb]({url}) üzerinde herhangi bir yayın tarihi mevcut değil.", "BlocklistFilterHasNoItems": "Seçilen engelleme listesi filtresi hiçbir öğe içermiyor", "IndexerSettingsSeedTime": "Seed Süresi", "IndexerSettingsSeedRatio": "Seed Oranı", @@ -1826,5 +1826,33 @@ "NoBlocklistItems": "Engellenenler listesi öğesi yok", "LastSearched": "Son Aranan", "ShowTraktRatingPosterHelpText": "Posterin altında Tomato derecelendirmesini göster", - "FolderNameTokens": "Dosya Adı Belirteçleri" + "FolderNameTokens": "Dosya Adı Belirteçleri", + "MetadataSettingsMovieImages": "Film Görüntüleri", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Koleksiyon adını .nfo'ya ekle", + "ToggleMonitoredToUnmonitored": "İzleniyor, izlemeyi bırakmak için tıklayın", + "InCinemasMovieAvailabilityDescription": "Filmler sinemalarda gösterime girdiği anda vizyona girmiş sayılır.", + "TraktRating": "Trakt Puanı", + "TraktVotes": "Trakt Oyları", + "Install": "Kur", + "InstallMajorVersionUpdate": "Güncellemeyi Kur", + "ReleasedMovieAvailabilityDescription": "Filmler Blu-Ray veya streaming versiyonu yayınlanır yayınlanmaz yayınlanabilir kabul edilir.", + "AnnouncedMovieAvailabilityDescription": "Filmler {appName} uygulamasına eklendiği anda kullanılabilir olarak kabul edilir.", + "SmartReplace": "Akıllı Değiştir", + "SmartReplaceHint": "İsme bağlı olarak Dash veya Space Dash", + "DefaultNotFoundMessage": "Kaybolmuş olmalısın, burada görülecek bir şey yok.", + "ShowTraktRating": "Trakt Puanını Göster", + "OnFileImport": "Dosya İçe Aktarımı", + "OnFileUpgrade": "Dosyada Yükseltme", + "InstallMajorVersionUpdateMessage": "Bu güncelleştirme yeni bir ana sürüm yükleyecek ve sisteminizle uyumlu olmayabilir. Bu güncelleştirmeyi yüklemek istediğinizden emin misiniz?", + "InstallMajorVersionUpdateMessageLink": "Daha fazla bilgi için lütfen [{domain}]({url}) adresini kontrol edin.", + "MetadataSettingsMovieMetadata": "Film Meta Verisi", + "MetadataSettingsMovieMetadataCollectionName": "Film Koleksiyonu Adı", + "MetadataSettingsMovieMetadataLanguage": "Film Meta Veri Dili", + "MetadataSettingsMovieMetadataNfo": "movie.nfo'yu kullanın", + "MetadataSettingsMovieMetadataUrl": "Film Meta Veri URL'si", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo tam film meta verileriyle", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": ".nfo'da mevcutsa seçili dili ekleyin", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Meta verileri varsayılan .nfo yerine movie.nfo'ya yaz", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "TMDb ve IMDb film URL'lerini .nfo'ya ekleyin", + "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index adbc44aed6..d6ba547cbf 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1073,5 +1073,41 @@ "ShowDigitalRelease": "Ngày phát hành rạp chiếu phim", "ShowDigitalReleaseHelpText": "Hiển thị ngày phát hành dưới áp phích", "ShowPhysicalRelease": "Ngày phát hành vật lý", - "FolderNameTokens": "Mã thông báo tên tệp" + "FolderNameTokens": "Mã thông báo tên tệp", + "AudioLanguages": "Ngôn ngữ của âm thanh", + "AuthenticationRequired": "Bắt buộc phải xác thực", + "AuthenticationMethod": "Phương thức xác thực", + "AuthenticationRequiredPasswordHelpTextWarning": "Nhập mật khẩu mới", + "AuthenticationRequiredUsernameHelpTextWarning": "Nhập tên người dùng mới", + "AddIndexerImplementation": "Thêm trình lập chỉ mục - {implementationName}", + "AddImportListImplementation": "Thêm danh sách nhập - {implementationName}", + "AuthenticationRequiredWarning": "Để ngăn truy cập từ xa mà không cần xác thực, {appName} hiện yêu cầu bật xác thực. Bạn có thể tùy ý tắt xác thực từ các địa chỉ cục bộ.", + "UpdateAvailableHealthCheckMessage": "Có cập nhật mới: {version}", + "WantMoreControlAddACustomFormat": "Bạn muốn kiểm soát nhiều hơn những nội dung tải xuống nào được ưu tiên? Thêm [Custom Format](/settings/customformats)", + "AppUpdated": "{appName} đã cập nhật", + "AppUpdatedVersion": "{appName} đã được cập nhật lên phiên bản `{version}`, để nhận được những thay đổi mới nhất, bạn cần tải lại {appName}", + "AddCondition": "Thêm điều kiện", + "AddAutoTag": "Thêm thẻ tự động", + "AutoTagging": "Tự động gắn thẻ", + "Unknown": "Không rõ", + "Waiting": "Đang chờ", + "AutomaticUpdatesDisabledDocker": "Cập nhật tự động không được hỗ trợ trực tiếp khi sử dụng cơ chế cập nhật Docker. Bạn sẽ cần cập nhật container image của {appName} hoặc sử dụng tập lệnh", + "AddConnection": "Thêm kết nối", + "AddConditionImplementation": "Thêm điều kiện - {implementationName}", + "AddConnectionImplementation": "Thêm điều kiện - {implementationName}", + "AddImportList": "Thêm danh sách nhập", + "AddDownloadClientImplementation": "Thêm trình tải xuống - {implementationName}", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Xác nhận mật khẩu mới", + "UseSsl": "Dùng SSL", + "UpdaterLogFiles": "Tệp nhật ký của trình cập nhật", + "AnnouncedMovieAvailabilityDescription": "Phim được coi là có sẵn ngay khi chúng được thêm vào {appName}.", + "AuthenticationMethodHelpTextWarning": "Vui lòng chọn một phương thức xác thực hợp lệ", + "AutoTaggingLoadError": "Không thể tải tính năng tự động gắn thẻ", + "BlocklistAndSearch": "Danh sách chặn và tìm kiếm", + "YesterdayAt": "Hôm qua lúc {time}", + "WhySearchesCouldBeFailing": "Nhấp vào đây để tìm hiểu lý do tại sao tìm kiếm thất bại", + "UnknownEventTooltip": "Sự kiện không rõ", + "EditReleaseProfile": "Chỉnh sửa hồ sơ độ trễ", + "Clone": "Đóng", + "AllTitles": "Tất cả các tệp" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index ded9981007..e614c01d5a 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -249,5 +249,7 @@ "DeleteImportListExclusion": "新增排除清單", "Letterboxd": "文字方框", "Discord": "Discord", - "TMDb": "TMDb" + "TMDb": "TMDb", + "EditReleaseProfile": "新增延時配置", + "Reason": "季" } From 394f34eb2ac5677d64e232431667a63287fb79cc Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 2 Nov 2024 21:56:59 +0200 Subject: [PATCH 061/579] Fixed: Root folder existence for import lists and movie collections --- .../Checks/ImportListRootFolderCheck.cs | 15 +++++++++++++-- .../Checks/MovieCollectionRootFolderCheck.cs | 11 +++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/ImportListRootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/ImportListRootFolderCheck.cs index 599ed391e2..3005647084 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/ImportListRootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/ImportListRootFolderCheck.cs @@ -2,15 +2,19 @@ using System.Linq; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Datastore.Events; using NzbDrone.Core.ImportLists; using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles.Events; using NzbDrone.Core.Movies.Events; +using NzbDrone.Core.RootFolders; using NzbDrone.Core.ThingiProvider.Events; namespace NzbDrone.Core.HealthCheck.Checks { [CheckOn(typeof(ProviderUpdatedEvent))] + [CheckOn(typeof(ProviderDeletedEvent))] + [CheckOn(typeof(ModelEvent))] [CheckOn(typeof(MoviesDeletedEvent))] [CheckOn(typeof(MovieMovedEvent))] [CheckOn(typeof(MovieFileImportedEvent), CheckOnCondition.FailedOnly)] @@ -19,17 +23,21 @@ public class ImportListRootFolderCheck : HealthCheckBase { private readonly IImportListFactory _importListFactory; private readonly IDiskProvider _diskProvider; + private readonly IRootFolderService _rootFolderService; - public ImportListRootFolderCheck(IImportListFactory importListFactory, IDiskProvider diskProvider, ILocalizationService localizationService) + public ImportListRootFolderCheck(IImportListFactory importListFactory, IDiskProvider diskProvider, IRootFolderService rootFolderService, ILocalizationService localizationService) : base(localizationService) { _importListFactory = importListFactory; _diskProvider = diskProvider; + _rootFolderService = rootFolderService; } public override HealthCheck Check() { var importLists = _importListFactory.All(); + var rootFolders = _rootFolderService.All(); + var missingRootFolders = new Dictionary>(); foreach (var importList in importLists) @@ -43,7 +51,10 @@ public override HealthCheck Check() continue; } - if (rootFolderPath.IsNullOrWhiteSpace() || !_diskProvider.FolderExists(rootFolderPath)) + if (rootFolderPath.IsNullOrWhiteSpace() || + !rootFolderPath.IsPathValid(PathValidationType.CurrentOs) || + !rootFolders.Any(r => r.Path.PathEquals(rootFolderPath)) || + !_diskProvider.FolderExists(rootFolderPath)) { missingRootFolders.Add(rootFolderPath, new List { importList }); } diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs index 4adb4f96e9..58524c45cc 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/MovieCollectionRootFolderCheck.cs @@ -18,17 +18,21 @@ public class MovieCollectionRootFolderCheck : HealthCheckBase { private readonly IMovieCollectionService _collectionService; private readonly IDiskProvider _diskProvider; + private readonly IRootFolderService _rootFolderService; - public MovieCollectionRootFolderCheck(IMovieCollectionService collectionService, IDiskProvider diskProvider, ILocalizationService localizationService) + public MovieCollectionRootFolderCheck(IMovieCollectionService collectionService, IDiskProvider diskProvider, IRootFolderService rootFolderService, ILocalizationService localizationService) : base(localizationService) { _collectionService = collectionService; _diskProvider = diskProvider; + _rootFolderService = rootFolderService; } public override HealthCheck Check() { var collections = _collectionService.GetAllCollections(); + var rootFolders = _rootFolderService.All(); + var missingRootFolders = new Dictionary>(); foreach (var collection in collections) @@ -42,7 +46,10 @@ public override HealthCheck Check() continue; } - if (rootFolderPath.IsNullOrWhiteSpace() || !rootFolderPath.IsPathValid(PathValidationType.CurrentOs) || !_diskProvider.FolderExists(rootFolderPath)) + if (rootFolderPath.IsNullOrWhiteSpace() || + !rootFolderPath.IsPathValid(PathValidationType.CurrentOs) || + !rootFolders.Any(r => r.Path.PathEquals(rootFolderPath)) || + !_diskProvider.FolderExists(rootFolderPath)) { missingRootFolders.Add(rootFolderPath, new List { collection }); } From 186e9cdd2317673634152fc3d20b9957b426c60f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 3 Nov 2024 11:41:20 +0200 Subject: [PATCH 062/579] Bump version to 5.15.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 6f8fc327ed..547e17be7d 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.15.0' + majorVersion: '5.15.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From f23c2dbaba100bf05de47db667b76e94e84ef3a9 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 3 Nov 2024 14:46:31 -0800 Subject: [PATCH 063/579] Increase retries for DebouncerFixture (cherry picked from commit 78cf13d341e6690bf6079dd1819d060d002155a7) --- src/NzbDrone.Common.Test/TPLTests/DebouncerFixture.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Common.Test/TPLTests/DebouncerFixture.cs b/src/NzbDrone.Common.Test/TPLTests/DebouncerFixture.cs index 4b7349f4a1..47bc3ca424 100644 --- a/src/NzbDrone.Common.Test/TPLTests/DebouncerFixture.cs +++ b/src/NzbDrone.Common.Test/TPLTests/DebouncerFixture.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading; using FluentAssertions; using NUnit.Framework; @@ -21,7 +21,7 @@ public void Hit() } [Test] - [Retry(3)] + [Retry(10)] public void should_hold_the_call_for_debounce_duration() { var counter = new Counter(); @@ -39,7 +39,7 @@ public void should_hold_the_call_for_debounce_duration() } [Test] - [Retry(3)] + [Retry(10)] public void should_throttle_calls() { var counter = new Counter(); @@ -63,7 +63,7 @@ public void should_throttle_calls() } [Test] - [Retry(3)] + [Retry(10)] public void should_hold_the_call_while_paused() { var counter = new Counter(); @@ -97,7 +97,7 @@ public void should_hold_the_call_while_paused() } [Test] - [Retry(3)] + [Retry(10)] public void should_handle_pause_reentrancy() { var counter = new Counter(); From def6950db4f9262e5e106ebfe3e4f0384fb1efb3 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 28 Oct 2024 16:04:48 -0700 Subject: [PATCH 064/579] Fixed: Use download client name for history column (cherry picked from commit 1df0ba9e5aef2d2745a45c546c869837ac8e68db) --- frontend/src/Activity/History/HistoryRow.tsx | 7 ++++++- frontend/src/typings/History.ts | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/frontend/src/Activity/History/HistoryRow.tsx b/frontend/src/Activity/History/HistoryRow.tsx index 45d0766b02..1f253cac9b 100644 --- a/frontend/src/Activity/History/HistoryRow.tsx +++ b/frontend/src/Activity/History/HistoryRow.tsx @@ -154,9 +154,14 @@ function HistoryRow(props: HistoryRowProps) { } if (name === 'downloadClient') { + const downloadClientName = + 'downloadClientName' in data ? data.downloadClientName : null; + const downloadClient = + 'downloadClient' in data ? data.downloadClient : null; + return ( - {'downloadClient' in data ? data.downloadClient : ''} + {downloadClientName ?? downloadClient ?? ''} ); } diff --git a/frontend/src/typings/History.ts b/frontend/src/typings/History.ts index de244bb1b5..a9ce30b831 100644 --- a/frontend/src/typings/History.ts +++ b/frontend/src/typings/History.ts @@ -39,6 +39,8 @@ export interface DownloadFailedHistory { export interface DownloadFolderImportedHistory { customFormatScore?: string; + downloadClient: string; + downloadClientName: string; droppedPath: string; importedPath: string; } From b30efd0c62fc3f12bd3ca6bd5383b5f1cfb4dc63 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 27 Oct 2024 16:48:53 -0700 Subject: [PATCH 065/579] Use current time for cache break in development (cherry picked from commit 020ed32fcfab1c6fbe57af5ea650300272c93fd7) --- src/Radarr.Http/Frontend/Mappers/CacheBreakerProvider.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/Radarr.Http/Frontend/Mappers/CacheBreakerProvider.cs b/src/Radarr.Http/Frontend/Mappers/CacheBreakerProvider.cs index 74328f4978..1ae8d8cfa6 100644 --- a/src/Radarr.Http/Frontend/Mappers/CacheBreakerProvider.cs +++ b/src/Radarr.Http/Frontend/Mappers/CacheBreakerProvider.cs @@ -1,6 +1,8 @@ +using System; using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Crypto; +using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; namespace Radarr.Http.Frontend.Mappers @@ -28,6 +30,11 @@ public string AddCacheBreakerToPath(string resourceUrl) return resourceUrl; } + if (!RuntimeInfo.IsProduction) + { + return resourceUrl + "?t=" + DateTime.UtcNow.Ticks; + } + var mapper = _diskMappers.Single(m => m.CanHandle(resourceUrl)); var pathToFile = mapper.Map(resourceUrl); var hash = _hashProvider.ComputeMd5(pathToFile).ToBase64(); From 1414a09111b7684ba8c90bd645bfe416e080c91c Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 26 Oct 2024 21:47:54 -0700 Subject: [PATCH 066/579] New: Add individual edit to Manage Custom Formats (cherry picked from commit e006b405323c276eb5b7f2dd97b97c80394a6930) --- .../EditCustomFormatModalConnector.js | 2 + .../ManageCustomFormatsModalContent.tsx | 5 ++ .../Manage/ManageCustomFormatsModalRow.css | 6 ++ .../ManageCustomFormatsModalRow.css.d.ts | 1 + .../Manage/ManageCustomFormatsModalRow.tsx | 78 ++++++++++++++++++- 5 files changed, 89 insertions(+), 3 deletions(-) diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalConnector.js b/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalConnector.js index 52b2f09f67..3e79425cdf 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalConnector.js +++ b/frontend/src/Settings/CustomFormats/CustomFormats/EditCustomFormatModalConnector.js @@ -3,6 +3,7 @@ import React, { Component } from 'react'; import { connect } from 'react-redux'; import { clearPendingChanges } from 'Store/Actions/baseActions'; import EditCustomFormatModal from './EditCustomFormatModal'; +import EditCustomFormatModalContentConnector from './EditCustomFormatModalContentConnector'; function mapStateToProps() { return {}; @@ -36,6 +37,7 @@ class EditCustomFormatModalConnector extends Component { } EditCustomFormatModalConnector.propTypes = { + ...EditCustomFormatModalContentConnector.propTypes, onModalClose: PropTypes.func.isRequired, clearPendingChanges: PropTypes.func.isRequired }; diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalContent.tsx b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalContent.tsx index bd16c74e9c..891c9941f7 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalContent.tsx +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalContent.tsx @@ -47,6 +47,11 @@ const COLUMNS = [ isSortable: true, isVisible: true, }, + { + name: 'actions', + label: '', + isVisible: true, + }, ]; interface ManageCustomFormatsModalContentProps { diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css index a7c85e340b..355c70378f 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css @@ -4,3 +4,9 @@ word-break: break-all; } + +.actions { + composes: cell from '~Components/Table/Cells/TableRowCell.css'; + + width: 40px; +} diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css.d.ts b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css.d.ts index 906d2dc54c..d1719edd88 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css.d.ts +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.css.d.ts @@ -1,6 +1,7 @@ // This file is automatically generated. // Please do not change this file! interface CssExports { + 'actions': string; 'includeCustomFormatWhenRenaming': string; 'name': string; } diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.tsx b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.tsx index 32b1359703..57bb7fda0f 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.tsx +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsModalRow.tsx @@ -1,10 +1,18 @@ -import React, { useCallback } from 'react'; +import React, { useCallback, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import IconButton from 'Components/Link/IconButton'; +import ConfirmModal from 'Components/Modal/ConfirmModal'; import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import Column from 'Components/Table/Column'; import TableRow from 'Components/Table/TableRow'; +import { icons } from 'Helpers/Props'; +import { deleteCustomFormat } from 'Store/Actions/settingsActions'; import { SelectStateInputProps } from 'typings/props'; import translate from 'Utilities/String/translate'; +import EditCustomFormatModalConnector from '../EditCustomFormatModalConnector'; import styles from './ManageCustomFormatsModalRow.css'; interface ManageCustomFormatsModalRowProps { @@ -16,6 +24,15 @@ interface ManageCustomFormatsModalRowProps { onSelectedChange(result: SelectStateInputProps): void; } +function isDeletingSelector() { + return createSelector( + (state: AppState) => state.settings.customFormats.isDeleting, + (isDeleting) => { + return isDeleting; + } + ); +} + function ManageCustomFormatsModalRow(props: ManageCustomFormatsModalRowProps) { const { id, @@ -25,7 +42,16 @@ function ManageCustomFormatsModalRow(props: ManageCustomFormatsModalRowProps) { onSelectedChange, } = props; - const onSelectedChangeWrapper = useCallback( + const dispatch = useDispatch(); + const isDeleting = useSelector(isDeletingSelector()); + + const [isEditCustomFormatModalOpen, setIsEditCustomFormatModalOpen] = + useState(false); + + const [isDeleteCustomFormatModalOpen, setIsDeleteCustomFormatModalOpen] = + useState(false); + + const handlelectedChange = useCallback( (result: SelectStateInputProps) => { onSelectedChange({ ...result, @@ -34,12 +60,33 @@ function ManageCustomFormatsModalRow(props: ManageCustomFormatsModalRowProps) { [onSelectedChange] ); + const handleEditCustomFormatModalOpen = useCallback(() => { + setIsEditCustomFormatModalOpen(true); + }, [setIsEditCustomFormatModalOpen]); + + const handleEditCustomFormatModalClose = useCallback(() => { + setIsEditCustomFormatModalOpen(false); + }, [setIsEditCustomFormatModalOpen]); + + const handleDeleteCustomFormatPress = useCallback(() => { + setIsEditCustomFormatModalOpen(false); + setIsDeleteCustomFormatModalOpen(true); + }, [setIsEditCustomFormatModalOpen, setIsDeleteCustomFormatModalOpen]); + + const handleDeleteCustomFormatModalClose = useCallback(() => { + setIsDeleteCustomFormatModalOpen(false); + }, [setIsDeleteCustomFormatModalOpen]); + + const handleConfirmDeleteCustomFormat = useCallback(() => { + dispatch(deleteCustomFormat({ id })); + }, [id, dispatch]); + return ( {name} @@ -47,6 +94,31 @@ function ManageCustomFormatsModalRow(props: ManageCustomFormatsModalRowProps) { {includeCustomFormatWhenRenaming ? translate('Yes') : translate('No')} + + + + + + + + ); } From b4eff4d4f9f20a9e4b3b46c9dbd31914c0a238ed Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 4 Nov 2024 12:31:05 +0200 Subject: [PATCH 067/579] Show a movie path as example in Mount Health Check Closes #10649 --- src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs index 3c3a10c06c..3e88dd7515 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using NzbDrone.Common.Disk; using NzbDrone.Core.Localization; @@ -21,14 +22,17 @@ public override HealthCheck Check() { // Not best for optimization but due to possible symlinks and junctions, we get mounts based on series path so internals can handle mount resolution. var mounts = _movieService.AllMoviePaths() - .Select(p => _diskProvider.GetMount(p.Value)) - .Where(m => m is { MountOptions.IsReadOnly: true }) - .DistinctBy(m => m.RootDirectory) + .Select(p => new Tuple(_diskProvider.GetMount(p.Value), p.Value)) + .Where(m => m.Item1 is { MountOptions.IsReadOnly: true }) + .DistinctBy(m => m.Item1.RootDirectory) .ToList(); if (mounts.Any()) { - return new HealthCheck(GetType(), HealthCheckResult.Error, _localizationService.GetLocalizedString("MountCheckMessage") + string.Join(", ", mounts.Select(m => m.Name)), "#movie-mount-ro"); + return new HealthCheck(GetType(), + HealthCheckResult.Error, + $"{_localizationService.GetLocalizedString("MountCheckMessage")}{string.Join(", ", mounts.Select(m => $"{m.Item1.Name} ({m.Item2})"))}", + "#movie-mount-ro"); } return new HealthCheck(GetType()); From 5976d66511ce1ac5250d7f613517324be5233a35 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 3 Nov 2024 14:43:50 -0800 Subject: [PATCH 068/579] New: Reject files during import that have no audio tracks (cherry picked from commit 978349e24135572889095c743d0e7fac734ba7e0) Closes #10643 --- .../HasAudioTrackSpecificationFixture.cs | 61 +++++++++++++++++++ .../HasAudioTrackSpecification.cs | 35 +++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecificationFixture.cs create mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecificationFixture.cs new file mode 100644 index 0000000000..7be22b839a --- /dev/null +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecificationFixture.cs @@ -0,0 +1,61 @@ +using System.IO; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.MediaFiles.MediaInfo; +using NzbDrone.Core.MediaFiles.MovieImport.Specifications; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.MediaFiles.EpisodeImport.Specifications +{ + [TestFixture] + public class HasAudioTrackSpecificationFixture : CoreTest + { + private Movie _movie; + private LocalMovie _localMovie; + private string _rootFolder; + + [SetUp] + public void Setup() + { + _rootFolder = @"C:\Test\Movies".AsOsAgnostic(); + + _movie = Builder.CreateNew() + .With(s => s.Path = Path.Combine(_rootFolder, "Movie Title")) + .Build(); + + _localMovie = new LocalMovie + { + Path = @"C:\Test\Unsorted\Movie Title\movie.title.2000.avi".AsOsAgnostic(), + Movie = _movie + }; + } + + [Test] + public void should_accept_if_media_info_is_null() + { + _localMovie.MediaInfo = null; + + Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); + } + + [Test] + public void should_reject_if_audio_stream_count_is_0() + { + _localMovie.MediaInfo = Builder.CreateNew().With(m => m.AudioStreamCount = 0).Build(); + + Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeFalse(); + } + + [Test] + public void should_accept_if_audio_stream_count_is_0() + { + _localMovie.MediaInfo = Builder.CreateNew().With(m => m.AudioStreamCount = 1).Build(); + + Subject.IsSatisfiedBy(_localMovie, null).Accepted.Should().BeTrue(); + } + } +} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs new file mode 100644 index 0000000000..2be157725f --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs @@ -0,0 +1,35 @@ +using NLog; +using NzbDrone.Core.DecisionEngine; +using NzbDrone.Core.Download; +using NzbDrone.Core.Parser.Model; + +namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications +{ + public class HasAudioTrackSpecification : IImportDecisionEngineSpecification + { + private readonly Logger _logger; + + public HasAudioTrackSpecification(Logger logger) + { + _logger = logger; + } + + public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + { + if (localMovie.MediaInfo == null) + { + _logger.Debug("Failed to get media info from the file, make sure ffprobe is available, skipping check"); + return Decision.Accept(); + } + + if (localMovie.MediaInfo.AudioStreamCount == 0) + { + _logger.Debug("No audio tracks found in file"); + + return Decision.Reject("No audio tracks detected"); + } + + return Decision.Accept(); + } + } +} From b22a86e1d7059dcafc81bc5d823d186e44bacb5b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 28 Oct 2024 16:05:57 -0700 Subject: [PATCH 069/579] New: Include source path with Webhook import event movie file (cherry picked from commit 73208e2f60263b1236f094a2bf6c47ebd5a8a271) Closes #10635 --- src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs | 5 ++++- src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs index 017eb07466..041da35257 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookBase.cs @@ -60,7 +60,10 @@ protected WebhookImportPayload BuildOnDownloadPayload(DownloadMessage message) ApplicationUrl = _configService.ApplicationUrl, Movie = GetMovie(message.Movie), RemoteMovie = new WebhookRemoteMovie(message.Movie), - MovieFile = new WebhookMovieFile(movieFile), + MovieFile = new WebhookMovieFile(movieFile) + { + SourcePath = message.SourcePath + }, Release = new WebhookGrabbedRelease(message.Release), IsUpgrade = message.OldMovieFiles.Any(), DownloadClient = message.DownloadClientInfo?.Name, diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs index 769777cf54..eff79d1d00 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs @@ -39,6 +39,7 @@ public WebhookMovieFile(MovieFile movieFile) public long Size { get; set; } public DateTime DateAdded { get; set; } public WebhookMovieFileMediaInfo MediaInfo { get; set; } + public string SourcePath { get; set; } public string RecycleBinPath { get; set; } } } From 10e39641118ea98fefb66d312fc91d5c32d2426d Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 26 Oct 2024 20:48:00 -0700 Subject: [PATCH 070/579] New: Use instance name in PWA manifest (cherry picked from commit 1fcfb88d2aa0126c4b3c878c8e310311ea57d04d) Closes #10625 --- frontend/src/Content/manifest.json | 2 +- .../Frontend/Mappers/ManifestMapper.cs | 21 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/frontend/src/Content/manifest.json b/frontend/src/Content/manifest.json index 31dc2ba11d..5c2b3d59d5 100644 --- a/frontend/src/Content/manifest.json +++ b/frontend/src/Content/manifest.json @@ -1,5 +1,5 @@ { - "name": "Radarr", + "name": "__INSTANCE_NAME__", "icons": [ { "src": "__URL_BASE__/Content/Images/Icons/android-chrome-192x192.png", diff --git a/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs b/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs index bbe2e4554d..71f889aaf2 100644 --- a/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs +++ b/src/Radarr.Http/Frontend/Mappers/ManifestMapper.cs @@ -8,9 +8,14 @@ namespace Radarr.Http.Frontend.Mappers { public class ManifestMapper : UrlBaseReplacementResourceMapperBase { + private readonly IConfigFileProvider _configFileProvider; + + private string _generatedContent; + public ManifestMapper(IAppFolderInfo appFolderInfo, IDiskProvider diskProvider, IConfigFileProvider configFileProvider, Logger logger) : base(diskProvider, configFileProvider, logger) { + _configFileProvider = configFileProvider; FilePath = Path.Combine(appFolderInfo.StartUpFolder, configFileProvider.UiFolder, "Content", "manifest.json"); } @@ -23,5 +28,21 @@ public override bool CanHandle(string resourceUrl) { return resourceUrl.StartsWith("/Content/manifest"); } + + protected override string GetFileText() + { + if (RuntimeInfo.IsProduction && _generatedContent != null) + { + return _generatedContent; + } + + var text = base.GetFileText(); + + text = text.Replace("__INSTANCE_NAME__", _configFileProvider.InstanceName); + + _generatedContent = text; + + return _generatedContent; + } } } From ca724836ce1355df91cf64063b45043c91788c2c Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 26 Oct 2024 21:48:18 -0700 Subject: [PATCH 071/579] Rename Manage Custom Formats to Manage Formats (cherry picked from commit 0f225b05c00add562c9a6aa8cc4cf494e83176c1) Closes #10629 --- .../CustomFormats/Manage/ManageCustomFormatsToolbarButton.tsx | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsToolbarButton.tsx b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsToolbarButton.tsx index f27f9e503e..91f41dc445 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsToolbarButton.tsx +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Manage/ManageCustomFormatsToolbarButton.tsx @@ -12,7 +12,7 @@ function ManageCustomFormatsToolbarButton() { return ( <> diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 86075d43a9..071a85ef45 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -880,6 +880,7 @@ "ManageCustomFormats": "Manage Custom Formats", "ManageDownloadClients": "Manage Download Clients", "ManageFiles": "Manage Files", + "ManageFormats": "Manage Formats", "ManageImportLists": "Manage Import Lists", "ManageIndexers": "Manage Indexers", "ManageLists": "Manage Lists", From 40d95a04e3ba96a36dded87def8f272764b42653 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 4 Nov 2024 13:01:40 +0200 Subject: [PATCH 072/579] Sync coding style with upstream for join methods Towards #10637 --- .../Datastore/Extensions/BuilderExtensions.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs b/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs index fe650a61cf..a25268b705 100644 --- a/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs +++ b/src/NzbDrone.Core/Datastore/Extensions/BuilderExtensions.cs @@ -57,25 +57,22 @@ public static SqlBuilder OrWhere(this SqlBuilder builder, Expression(this SqlBuilder builder, Expression> filter) { var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence); - var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight)); - return builder.Join($"\"{rightTable}\" ON {wb.ToString()}"); + return builder.Join($"\"{rightTable}\" ON {wb}"); } public static SqlBuilder LeftJoin(this SqlBuilder builder, Expression> filter) { var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence); - var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight)); - return builder.LeftJoin($"\"{rightTable}\" ON {wb.ToString()}"); + return builder.LeftJoin($"\"{rightTable}\" ON {wb}"); } public static SqlBuilder InnerJoin(this SqlBuilder builder, Expression> filter) { var wb = GetWhereBuilder(builder.DatabaseType, filter, false, builder.Sequence); - var rightTable = TableMapping.Mapper.TableNameMapping(typeof(TRight)); return builder.InnerJoin($"\"{rightTable}\" ON {wb}"); From 86f4f86a0ad2241df5602770e473f9efdb954591 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 3 Nov 2024 15:24:06 -0800 Subject: [PATCH 073/579] Fixed: Filtering queue by multiple qualities (cherry picked from commit b8af3af9f16db96337832c2989f4e7ff3dc2ed30) Closes #10647 --- src/Radarr.Api.V3/Queue/QueueController.cs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Radarr.Api.V3/Queue/QueueController.cs b/src/Radarr.Api.V3/Queue/QueueController.cs index 4b7c5b233f..03f95cad8f 100644 --- a/src/Radarr.Api.V3/Queue/QueueController.cs +++ b/src/Radarr.Api.V3/Queue/QueueController.cs @@ -136,7 +136,7 @@ public object RemoveMany([FromBody] QueueBulkResource resource, [FromQuery] bool [HttpGet] [Produces("application/json")] - public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownMovieItems = false, bool includeMovie = false, [FromQuery] int[] movieIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, int? quality = null) + public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownMovieItems = false, bool includeMovie = false, [FromQuery] int[] movieIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null) { var pagingResource = new PagingResource(paging); var pagingSpec = pagingResource.MapToPagingSpec( @@ -160,10 +160,10 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource "timeleft", SortDirection.Ascending); - return pagingSpec.ApplyToPage((spec) => GetQueue(spec, movieIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality, includeUnknownMovieItems), (q) => MapToResource(q, includeMovie)); + return pagingSpec.ApplyToPage((spec) => GetQueue(spec, movieIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality?.ToHashSet(), includeUnknownMovieItems), (q) => MapToResource(q, includeMovie)); } - private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet movieIds, DownloadProtocol? protocol, HashSet languages, int? quality, bool includeUnknownMovieItems) + private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet movieIds, DownloadProtocol? protocol, HashSet languages, HashSet quality, bool includeUnknownMovieItems) { var ascending = pagingSpec.SortDirection == SortDirection.Ascending; var orderByFunc = GetOrderByFunc(pagingSpec); @@ -174,6 +174,8 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource var hasMovieIdFilter = movieIds.Any(); var hasLanguageFilter = languages.Any(); + var hasQualityFilter = quality.Any(); + var fullQueue = filteredQueue.Concat(pending).Where(q => { var include = true; @@ -193,9 +195,9 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource include &= q.Languages.Any(l => languages.Contains(l.Id)); } - if (include && quality.HasValue) + if (include && hasQualityFilter) { - include &= q.Quality.Quality.Id == quality.Value; + include &= quality.Contains(q.Quality.Quality.Id); } return include; From 9ab3e6bab73fa6a21e4d9afb851438c266883e68 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 4 Nov 2024 11:24:19 +0000 Subject: [PATCH 074/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Lars Co-authored-by: Weblate Co-authored-by: mytelegrambot Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/da.json | 3 ++- src/NzbDrone.Core/Localization/Core/es.json | 3 ++- src/NzbDrone.Core/Localization/Core/fi.json | 3 ++- src/NzbDrone.Core/Localization/Core/fr.json | 3 ++- src/NzbDrone.Core/Localization/Core/hu.json | 3 ++- src/NzbDrone.Core/Localization/Core/ja.json | 3 ++- src/NzbDrone.Core/Localization/Core/ko.json | 11 ++++++++++- src/NzbDrone.Core/Localization/Core/nb_NO.json | 2 +- src/NzbDrone.Core/Localization/Core/pt_BR.json | 6 ++++-- src/NzbDrone.Core/Localization/Core/ru.json | 3 ++- src/NzbDrone.Core/Localization/Core/tr.json | 3 ++- src/NzbDrone.Core/Localization/Core/zh_CN.json | 3 ++- 12 files changed, 33 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 2fb9b755aa..1caf847dea 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1091,5 +1091,6 @@ "ShowDigitalRelease": "Vis biografens udgivelsesdato", "ShowDigitalReleaseHelpText": "Vis udgivelsesdato under plakat", "ShowPhysicalRelease": "Fysisk udgivelsesdato", - "FolderNameTokens": "Filnavn tokens" + "FolderNameTokens": "Filnavn tokens", + "Clone": "Luk" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index fa59b6f31e..0b6e762571 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1854,5 +1854,6 @@ "MetadataSettingsMovieMetadataUrl": "URL de los metadatos de la película", "MetadataSettingsMovieMetadataNfo": "Usar película.nfo", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluye las URLs de TMDb e IMDb de la película en el .nfo", - "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Escribe los metadatos en película.nfo en lugar de al archivo .nfo predeterminado" + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Escribe los metadatos en película.nfo en lugar de al archivo .nfo predeterminado", + "FileBrowser": "Explorador de archivos" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 18ad633400..c1b027cd2f 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1761,5 +1761,6 @@ "FolderNameTokens": "Tiedostonimen muuttujat", "DefaultNotFoundMessage": "Lienet eksyksissä, koska täällä ei ole mitään nähtävää.", "ToggleMonitoredToUnmonitored": "Valvotaan (lopeta painamalla)", - "ToggleUnmonitoredToMonitored": "Ei valvota (aloita painamalla)" + "ToggleUnmonitoredToMonitored": "Ei valvota (aloita painamalla)", + "FileBrowser": "Tiedostoselain" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index c1f1001d5c..b56e681f51 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1843,5 +1843,6 @@ "MetadataSettingsMovieMetadataCollectionName": "Nom de la collection de films", "MetadataSettingsMovieMetadataUrl": "Lien des métadonnées du film", "InCinemasMovieAvailabilityDescription": "Les films sont considérés comme disponibles dès leur sortie en salles.", - "Disposition": "Disposition" + "Disposition": "Disposition", + "FileBrowser": "Explorateur de fichiers" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index d35b413d50..8dbec6feac 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1445,5 +1445,6 @@ "FolderNameTokens": "Fájlnév-tokenek", "DefaultNotFoundMessage": "Biztosan eltévedtél, nincs itt semmi látnivaló.", "ToggleMonitoredToUnmonitored": "Felügyelt, kattintson a figyelés megszüntetéséhez", - "ToggleUnmonitoredToMonitored": "Nem figyelt, kattintson a figyeléshez" + "ToggleUnmonitoredToMonitored": "Nem figyelt, kattintson a figyeléshez", + "FileBrowser": "Fájl Böngésző" } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index abc50e0b55..e9c1f6e5f9 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1069,5 +1069,6 @@ "ShowPhysicalRelease": "物理的なリリース日", "ShowPhysicalReleaseHelpText": "ポスターの下にリリース日を表示する", "ShowDigitalReleaseHelpText": "ポスターの下にリリース日を表示する", - "FolderNameTokens": "ファイル名トークン" + "FolderNameTokens": "ファイル名トークン", + "Clone": "閉じる" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 213786ada4..5e855d0528 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1057,5 +1057,14 @@ "MovieFileDeletedTooltip": "영화 파일 삭제", "Clone": "닫기", "EditReleaseProfile": "지연 프로필 편집", - "AllTitles": "모든 파일" + "AllTitles": "모든 파일", + "AppUpdated": "{appName} 업데이트", + "AddIndexerImplementation": "인덱서 추가 - {implementationName}", + "Any": "모두", + "AddConnection": "연결 추가", + "AddConnectionImplementation": "연결 추가 - {implementationName}", + "AddDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", + "ApiKeyValidationHealthCheckMessage": "API 키를 {length}자 이상으로 업데이트하세요. 설정 또는 구성 파일을 통해 이 작업을 수행할 수 있습니다.", + "AppUpdatedVersion": "{appName}이 버전 `{version}`으로 업데이트되었습니다. 최신 변경 사항을 받으려면 {appName}을 다시 로드해야 합니다", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "해시에 의해 토렌트가 차단된 경우 일부 인덱서의 RSS/검색 중에 토렌트가 제대로 거부되지 않을 수 있습니다. 이 기능을 활성화하면 토렌트를 가져온 후 클라이언트로 전송하기 전에 토렌트를 거부할 수 있습니다." } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index 7c45bff0b7..860a153ad4 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -275,7 +275,7 @@ "DeleteAutoTagHelpText": "Er du sikker på at du vil slette formattaggen {0}?", "DeleteSelectedDownloadClientsMessageText": "Er du sikker på at du vil slette formattaggen {0}?", "DeleteRootFolderMessageText": "Er du sikker på at du vil slette formattaggen {0}?", - "AddConnection": "Legg til kobling", + "AddConnection": "Legg til tilkobling", "DisabledForLocalAddresses": "Deaktivert for lokale adresser", "Released": "utgivelse", "ConnectionLostReconnect": "{appName} vil forsøke å koble til automatisk, eller du kan klikke oppdater nedenfor.", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index dc70d6ece4..74e66b24d8 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -773,7 +773,7 @@ "Socks4": "Socks4", "ShownClickToHide": "Mostrado, clique para ocultar", "RecyclingBinCleanupHelpText": "Defina como 0 para desabilitar a limpeza automática", - "RecentFolders": "Pastas recentes", + "RecentFolders": "Pastas Recentes", "RecentChanges": "Mudanças Recentes", "Reason": "Razão", "Real": "Real", @@ -1854,5 +1854,7 @@ "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo com metadados completos do filme", "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Incluir o idioma selecionado, se disponível em .nfo", "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Grave metadados em movie.nfo em vez do nome de arquivo de filme padrão .nfo", - "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluir URLs de filmes TMDb e IMDb no .nfo" + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluir URLs de filmes TMDb e IMDb no .nfo", + "FileBrowser": "Navegador de Arquivos", + "ManageFormats": "Gerenciar Formatos" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index c349dcbe96..b8f6268712 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1787,5 +1787,6 @@ "OnFileUpgrade": "При обновлении файла", "AnnouncedMovieAvailabilityDescription": "Фильмы считаются доступными, как только они добавляются в {appName}.", "CountCustomFormatsSelected": "{count} пользовательских форматов выбрано", - "CustomFormatsSpecificationExceptLanguage": "Исключить язык" + "CustomFormatsSpecificationExceptLanguage": "Исключить язык", + "FileBrowser": "Файловый браузер" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index a15254e2e7..4c31719ae7 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1854,5 +1854,6 @@ "MetadataXmbcSettingsMovieMetadataLanguageHelpText": ".nfo'da mevcutsa seçili dili ekleyin", "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Meta verileri varsayılan .nfo yerine movie.nfo'ya yaz", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "TMDb ve IMDb film URL'lerini .nfo'ya ekleyin", - "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın" + "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın", + "FileBrowser": "Dosya Yöneticisi" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index d3dd6a802a..789eb94a5b 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1851,5 +1851,6 @@ "MetadataXmbcSettingsMovieMetadataHelpText": "包含电影所有元数据的 .nfo 文件", "MetadataSettingsMovieImages": "电影图片", "MetadataXmbcSettingsMovieMetadataNfoHelpText": "将元数据写入 movie.nfo 而非默认的 .nfo", - "MetadataXmbcSettingsMovieMetadataUrlHelpText": "在 .nfo 文件中包含电影的 TMDb 和 IMDb URLs" + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "在 .nfo 文件中包含电影的 TMDb 和 IMDb URLs", + "FileBrowser": "文件浏览器" } From 3b9bd696fbb1743a57a3d330eb960b82e2d44013 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 26 Oct 2024 21:57:03 -0700 Subject: [PATCH 075/579] New: Favorite folders in Manual Import (cherry picked from commit 3ddc6ac6de5c27a9aab915672321c8818dc5da48) Closes #10630 --- .../App/State/InteractiveImportAppState.ts | 11 ++- frontend/src/Helpers/Props/icons.ts | 2 + .../Folder/FavoriteFolderRow.css | 5 ++ .../Folder/FavoriteFolderRow.css.d.ts | 7 ++ .../Folder/FavoriteFolderRow.tsx | 48 +++++++++++ ...eractiveImportSelectFolderModalContent.css | 7 +- ...iveImportSelectFolderModalContent.css.d.ts | 3 +- ...eractiveImportSelectFolderModalContent.tsx | 71 ++++++++++++---- .../InteractiveImport/Folder/RecentFolder.ts | 6 -- .../Folder/RecentFolderRow.css | 2 +- .../Folder/RecentFolderRow.js | 65 -------------- .../Folder/RecentFolderRow.tsx | 85 +++++++++++++++++++ .../Store/Actions/interactiveImportActions.js | 29 +++++++ src/NzbDrone.Core/Localization/Core/en.json | 3 + 14 files changed, 251 insertions(+), 93 deletions(-) create mode 100644 frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css create mode 100644 frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css.d.ts create mode 100644 frontend/src/InteractiveImport/Folder/FavoriteFolderRow.tsx delete mode 100644 frontend/src/InteractiveImport/Folder/RecentFolder.ts delete mode 100644 frontend/src/InteractiveImport/Folder/RecentFolderRow.js create mode 100644 frontend/src/InteractiveImport/Folder/RecentFolderRow.tsx diff --git a/frontend/src/App/State/InteractiveImportAppState.ts b/frontend/src/App/State/InteractiveImportAppState.ts index cf86f620dc..84fd9f4c14 100644 --- a/frontend/src/App/State/InteractiveImportAppState.ts +++ b/frontend/src/App/State/InteractiveImportAppState.ts @@ -1,11 +1,20 @@ import AppSectionState from 'App/State/AppSectionState'; -import RecentFolder from 'InteractiveImport/Folder/RecentFolder'; import ImportMode from 'InteractiveImport/ImportMode'; import InteractiveImport from 'InteractiveImport/InteractiveImport'; +interface FavoriteFolder { + folder: string; +} + +interface RecentFolder { + folder: string; + lastUsed: string; +} + interface InteractiveImportAppState extends AppSectionState { originalItems: InteractiveImport[]; importMode: ImportMode; + favoriteFolders: FavoriteFolder[]; recentFolders: RecentFolder[]; } diff --git a/frontend/src/Helpers/Props/icons.ts b/frontend/src/Helpers/Props/icons.ts index fda4363e2f..b43420bd07 100644 --- a/frontend/src/Helpers/Props/icons.ts +++ b/frontend/src/Helpers/Props/icons.ts @@ -15,6 +15,7 @@ import { faFileVideo as farFileVideo, faFolder as farFolder, faHdd as farHdd, + faHeart as farHeart, faKeyboard as farKeyboard, faObjectGroup as farObjectGroup, faObjectUngroup as farObjectUngroup, @@ -174,6 +175,7 @@ export const GENRE = fasTheaterMasks; export const GROUP = farObjectGroup; export const HEALTH = fasMedkit; export const HEART = fasHeart; +export const HEART_OUTLINE = farHeart; export const HISTORY = fasHistory; export const HOUSEKEEPING = fasHome; export const IGNORE = fasTimesCircle; diff --git a/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css new file mode 100644 index 0000000000..2839ea3891 --- /dev/null +++ b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css @@ -0,0 +1,5 @@ +.actions { + composes: cell from '~Components/Table/Cells/TableRowCell.css'; + + width: 70px; +} diff --git a/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css.d.ts b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css.d.ts new file mode 100644 index 0000000000..d8ea83dc1f --- /dev/null +++ b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'actions': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.tsx b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.tsx new file mode 100644 index 0000000000..e39635623c --- /dev/null +++ b/frontend/src/InteractiveImport/Folder/FavoriteFolderRow.tsx @@ -0,0 +1,48 @@ +import React, { SyntheticEvent, useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import IconButton from 'Components/Link/IconButton'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import TableRowButton from 'Components/Table/TableRowButton'; +import { icons } from 'Helpers/Props'; +import { removeFavoriteFolder } from 'Store/Actions/interactiveImportActions'; +import translate from 'Utilities/String/translate'; +import styles from './FavoriteFolderRow.css'; + +interface FavoriteFolderRowProps { + folder: string; + onPress: (folder: string) => unknown; +} + +function FavoriteFolderRow({ folder, onPress }: FavoriteFolderRowProps) { + const dispatch = useDispatch(); + + const handlePress = useCallback(() => { + onPress(folder); + }, [folder, onPress]); + + const handleRemoveFavoritePress = useCallback( + (e: SyntheticEvent) => { + e.stopPropagation(); + + dispatch(removeFavoriteFolder({ folder })); + }, + [folder, dispatch] + ); + + return ( + + {folder} + + + + + + ); +} + +export default FavoriteFolderRow; diff --git a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css index 5f9033a18b..8a7b5a5410 100644 --- a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css +++ b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css @@ -1,7 +1,12 @@ -.recentFoldersContainer { +.foldersContainer { margin-top: 15px; } +.foldersTitle { + border-bottom: 1px solid var(--borderColor); + font-size: 21px; +} + .buttonsContainer { margin-top: 30px; } diff --git a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css.d.ts b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css.d.ts index 46abdcb9b6..0e304b1b1c 100644 --- a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css.d.ts +++ b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.css.d.ts @@ -5,7 +5,8 @@ interface CssExports { 'buttonContainer': string; 'buttonIcon': string; 'buttonsContainer': string; - 'recentFoldersContainer': string; + 'foldersContainer': string; + 'foldersTitle': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.tsx b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.tsx index 0ff2d58f98..03c2a892d1 100644 --- a/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.tsx +++ b/frontend/src/InteractiveImport/Folder/InteractiveImportSelectFolderModalContent.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; @@ -14,14 +14,23 @@ import Table from 'Components/Table/Table'; import TableBody from 'Components/Table/TableBody'; import { icons, kinds, sizes } from 'Helpers/Props'; import { executeCommand } from 'Store/Actions/commandActions'; -import { - addRecentFolder, - removeRecentFolder, -} from 'Store/Actions/interactiveImportActions'; +import { addRecentFolder } from 'Store/Actions/interactiveImportActions'; import translate from 'Utilities/String/translate'; +import FavoriteFolderRow from './FavoriteFolderRow'; import RecentFolderRow from './RecentFolderRow'; import styles from './InteractiveImportSelectFolderModalContent.css'; +const favoriteFoldersColumns = [ + { + name: 'folder', + label: () => translate('Folder'), + }, + { + name: 'actions', + label: '', + }, +]; + const recentFoldersColumns = [ { name: 'folder', @@ -49,15 +58,22 @@ function InteractiveImportSelectFolderModalContent( const { modalTitle, onFolderSelect, onModalClose } = props; const [folder, setFolder] = useState(''); const dispatch = useDispatch(); - const recentFolders = useSelector( + const { favoriteFolders, recentFolders } = useSelector( createSelector( - (state: AppState) => state.interactiveImport.recentFolders, - (recentFolders) => { - return recentFolders; + (state: AppState) => state.interactiveImport, + (interactiveImport) => { + return { + favoriteFolders: interactiveImport.favoriteFolders, + recentFolders: interactiveImport.recentFolders, + }; } ) ); + const favoriteFolderMap = useMemo(() => { + return new Map(favoriteFolders.map((f) => [f.folder, f])); + }, [favoriteFolders]); + const onPathChange = useCallback( ({ value }: { value: string }) => { setFolder(value); @@ -90,13 +106,6 @@ function InteractiveImportSelectFolderModalContent( onFolderSelect(folder); }, [folder, onFolderSelect, dispatch]); - const onRemoveRecentFolderPress = useCallback( - (folderToRemove: string) => { - dispatch(removeRecentFolder({ folder: folderToRemove })); - }, - [dispatch] - ); - return ( @@ -110,8 +119,34 @@ function InteractiveImportSelectFolderModalContent( onChange={onPathChange} /> + {favoriteFolders.length ? ( +
+
+ {translate('FavoriteFolders')} +
+ + + + {favoriteFolders.map((favoriteFolder) => { + return ( + + ); + })} + +
+
+ ) : null} + {recentFolders.length ? ( -
+
+
+ {translate('RecentFolders')} +
+ {recentFolders @@ -123,8 +158,8 @@ function InteractiveImportSelectFolderModalContent( key={recentFolder.folder} folder={recentFolder.folder} lastUsed={recentFolder.lastUsed} + isFavorite={favoriteFolderMap.has(recentFolder.folder)} onPress={onRecentPathPress} - onRemoveRecentFolderPress={onRemoveRecentFolderPress} /> ); })} diff --git a/frontend/src/InteractiveImport/Folder/RecentFolder.ts b/frontend/src/InteractiveImport/Folder/RecentFolder.ts deleted file mode 100644 index 9c6e295f61..0000000000 --- a/frontend/src/InteractiveImport/Folder/RecentFolder.ts +++ /dev/null @@ -1,6 +0,0 @@ -interface RecentFolder { - folder: string; - lastUsed: string; -} - -export default RecentFolder; diff --git a/frontend/src/InteractiveImport/Folder/RecentFolderRow.css b/frontend/src/InteractiveImport/Folder/RecentFolderRow.css index 58eb9a8e44..2839ea3891 100644 --- a/frontend/src/InteractiveImport/Folder/RecentFolderRow.css +++ b/frontend/src/InteractiveImport/Folder/RecentFolderRow.css @@ -1,5 +1,5 @@ .actions { composes: cell from '~Components/Table/Cells/TableRowCell.css'; - width: 40px; + width: 70px; } diff --git a/frontend/src/InteractiveImport/Folder/RecentFolderRow.js b/frontend/src/InteractiveImport/Folder/RecentFolderRow.js deleted file mode 100644 index 83c7493c4e..0000000000 --- a/frontend/src/InteractiveImport/Folder/RecentFolderRow.js +++ /dev/null @@ -1,65 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import IconButton from 'Components/Link/IconButton'; -import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; -import TableRowCell from 'Components/Table/Cells/TableRowCell'; -import TableRowButton from 'Components/Table/TableRowButton'; -import { icons } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import styles from './RecentFolderRow.css'; - -class RecentFolderRow extends Component { - - // - // Listeners - - onPress = () => { - this.props.onPress(this.props.folder); - }; - - onRemovePress = (event) => { - event.stopPropagation(); - - const { - folder, - onRemoveRecentFolderPress - } = this.props; - - onRemoveRecentFolderPress(folder); - }; - - // - // Render - - render() { - const { - folder, - lastUsed - } = this.props; - - return ( - - {folder} - - - - - - - - ); - } -} - -RecentFolderRow.propTypes = { - folder: PropTypes.string.isRequired, - lastUsed: PropTypes.string.isRequired, - onPress: PropTypes.func.isRequired, - onRemoveRecentFolderPress: PropTypes.func.isRequired -}; - -export default RecentFolderRow; diff --git a/frontend/src/InteractiveImport/Folder/RecentFolderRow.tsx b/frontend/src/InteractiveImport/Folder/RecentFolderRow.tsx new file mode 100644 index 0000000000..31d164e1a3 --- /dev/null +++ b/frontend/src/InteractiveImport/Folder/RecentFolderRow.tsx @@ -0,0 +1,85 @@ +import React, { SyntheticEvent, useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import IconButton from 'Components/Link/IconButton'; +import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import TableRowButton from 'Components/Table/TableRowButton'; +import { icons } from 'Helpers/Props'; +import { + addFavoriteFolder, + removeFavoriteFolder, + removeRecentFolder, +} from 'Store/Actions/interactiveImportActions'; +import translate from 'Utilities/String/translate'; +import styles from './RecentFolderRow.css'; + +interface RecentFolderRowProps { + folder: string; + lastUsed: string; + isFavorite: boolean; + onPress: (folder: string) => unknown; +} + +function RecentFolderRow({ + folder, + lastUsed, + isFavorite, + onPress, +}: RecentFolderRowProps) { + const dispatch = useDispatch(); + + const handlePress = useCallback(() => { + onPress(folder); + }, [folder, onPress]); + + const handleFavoritePress = useCallback( + (e: SyntheticEvent) => { + e.stopPropagation(); + + if (isFavorite) { + dispatch(removeFavoriteFolder({ folder })); + } else { + dispatch(addFavoriteFolder({ folder })); + } + }, + [folder, isFavorite, dispatch] + ); + + const handleRemovePress = useCallback( + (e: SyntheticEvent) => { + e.stopPropagation(); + + dispatch(removeRecentFolder({ folder })); + }, + [folder, dispatch] + ); + + return ( + + {folder} + + + + + + + + + + ); +} + +export default RecentFolderRow; diff --git a/frontend/src/Store/Actions/interactiveImportActions.js b/frontend/src/Store/Actions/interactiveImportActions.js index 448c85e584..264f7f0890 100644 --- a/frontend/src/Store/Actions/interactiveImportActions.js +++ b/frontend/src/Store/Actions/interactiveImportActions.js @@ -3,6 +3,7 @@ import { createAction } from 'redux-actions'; import { batchActions } from 'redux-batched-actions'; import { sortDirections } from 'Helpers/Props'; import { createThunk, handleThunks } from 'Store/thunks'; +import sortByProp from 'Utilities/Array/sortByProp'; import createAjaxRequest from 'Utilities/createAjaxRequest'; import naturalExpansion from 'Utilities/String/naturalExpansion'; import { set, update, updateItem } from './baseActions'; @@ -30,6 +31,7 @@ export const defaultState = { items: [], sortKey: 'relativePath', sortDirection: sortDirections.ASCENDING, + favoriteFolders: [], recentFolders: [], importMode: 'chooseImportMode', sortPredicates: { @@ -58,6 +60,7 @@ export const defaultState = { export const persistState = [ 'interactiveImport.sortKey', 'interactiveImport.sortDirection', + 'interactiveImport.favoriteFolders', 'interactiveImport.recentFolders', 'interactiveImport.importMode' ]; @@ -73,6 +76,8 @@ export const UPDATE_INTERACTIVE_IMPORT_ITEMS = 'interactiveImport/updateInteract export const CLEAR_INTERACTIVE_IMPORT = 'interactiveImport/clearInteractiveImport'; export const ADD_RECENT_FOLDER = 'interactiveImport/addRecentFolder'; export const REMOVE_RECENT_FOLDER = 'interactiveImport/removeRecentFolder'; +export const ADD_FAVORITE_FOLDER = 'interactiveImport/addFavoriteFolder'; +export const REMOVE_FAVORITE_FOLDER = 'interactiveImport/removeFavoriteFolder'; export const SET_INTERACTIVE_IMPORT_MODE = 'interactiveImport/setInteractiveImportMode'; // @@ -86,6 +91,8 @@ export const updateInteractiveImportItems = createAction(UPDATE_INTERACTIVE_IMPO export const clearInteractiveImport = createAction(CLEAR_INTERACTIVE_IMPORT); export const addRecentFolder = createAction(ADD_RECENT_FOLDER); export const removeRecentFolder = createAction(REMOVE_RECENT_FOLDER); +export const addFavoriteFolder = createAction(ADD_FAVORITE_FOLDER); +export const removeFavoriteFolder = createAction(REMOVE_FAVORITE_FOLDER); export const setInteractiveImportMode = createAction(SET_INTERACTIVE_IMPORT_MODE); // @@ -264,9 +271,31 @@ export const reducers = createHandleActions({ return Object.assign({}, state, { recentFolders }); }, + [ADD_FAVORITE_FOLDER]: function(state, { payload }) { + const folder = payload.folder; + const favoriteFolder = { folder }; + const favoriteFolders = [...state.favoriteFolders, favoriteFolder].sort(sortByProp('folder')); + + return Object.assign({}, state, { favoriteFolders }); + }, + + [REMOVE_FAVORITE_FOLDER]: function(state, { payload }) { + const folder = payload.folder; + const favoriteFolders = state.favoriteFolders.reduce((acc, item) => { + if (item.folder !== folder) { + acc.push(item); + } + + return acc; + }, []); + + return Object.assign({}, state, { favoriteFolders }); + }, + [CLEAR_INTERACTIVE_IMPORT]: function(state) { const newState = { ...defaultState, + favoriteFolders: state.favoriteFolders, recentFolders: state.recentFolders, importMode: state.importMode }; diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 071a85ef45..86e7267ca7 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -629,6 +629,9 @@ "FailedToLoadMovieFromAPI": "Failed to load movie from API", "FailedToUpdateSettings": "Failed to update settings", "False": "False", + "FavoriteFolderAdd": "Add Favorite Folder", + "FavoriteFolderRemove": "Remove Favorite Folder", + "FavoriteFolders": "Favorite Folders", "FeatureRequests": "Feature Requests", "File": "File", "FileBrowser": "File Browser", From ff09da3a69ce312da38a43c824f1768a84fafefa Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 3 Nov 2024 15:28:48 -0800 Subject: [PATCH 076/579] New: Filter queue by status (cherry picked from commit fb540040ef66e90c55b82539b85df378d6c76bd3) Closes #10648 --- .../Filter/Builder/FilterBuilderRow.js | 4 ++ .../QueueStatusFilterBuilderRowValue.tsx | 67 +++++++++++++++++++ .../ReleaseStatusFilterBuilderRowValue.js | 4 +- .../Helpers/Props/filterBuilderValueTypes.js | 1 + frontend/src/Store/Actions/queueActions.js | 6 ++ .../Download/Pending/PendingReleaseService.cs | 3 +- src/NzbDrone.Core/Localization/Core/ar.json | 1 - src/NzbDrone.Core/Localization/Core/bg.json | 1 - src/NzbDrone.Core/Localization/Core/ca.json | 1 - src/NzbDrone.Core/Localization/Core/cs.json | 1 - src/NzbDrone.Core/Localization/Core/da.json | 1 - src/NzbDrone.Core/Localization/Core/de.json | 1 - src/NzbDrone.Core/Localization/Core/el.json | 1 - src/NzbDrone.Core/Localization/Core/en.json | 6 +- src/NzbDrone.Core/Localization/Core/es.json | 1 - src/NzbDrone.Core/Localization/Core/fi.json | 1 - src/NzbDrone.Core/Localization/Core/fr.json | 1 - src/NzbDrone.Core/Localization/Core/he.json | 1 - src/NzbDrone.Core/Localization/Core/hi.json | 1 - src/NzbDrone.Core/Localization/Core/hu.json | 1 - src/NzbDrone.Core/Localization/Core/is.json | 1 - src/NzbDrone.Core/Localization/Core/it.json | 1 - src/NzbDrone.Core/Localization/Core/ja.json | 1 - src/NzbDrone.Core/Localization/Core/ko.json | 1 - src/NzbDrone.Core/Localization/Core/nl.json | 1 - src/NzbDrone.Core/Localization/Core/pl.json | 1 - src/NzbDrone.Core/Localization/Core/pt.json | 1 - .../Localization/Core/pt_BR.json | 1 - src/NzbDrone.Core/Localization/Core/ro.json | 1 - src/NzbDrone.Core/Localization/Core/ru.json | 1 - src/NzbDrone.Core/Localization/Core/sv.json | 1 - src/NzbDrone.Core/Localization/Core/th.json | 1 - src/NzbDrone.Core/Localization/Core/tr.json | 1 - src/NzbDrone.Core/Localization/Core/uk.json | 1 - src/NzbDrone.Core/Localization/Core/vi.json | 1 - .../Localization/Core/zh_CN.json | 1 - src/NzbDrone.Core/Queue/Queue.cs | 2 +- src/NzbDrone.Core/Queue/QueueService.cs | 2 +- src/NzbDrone.Core/Queue/QueueStatus.cs | 16 +++++ src/Radarr.Api.V3/Queue/QueueController.cs | 14 ++-- src/Radarr.Api.V3/Queue/QueueResource.cs | 6 +- 41 files changed, 118 insertions(+), 42 deletions(-) create mode 100644 frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx create mode 100644 src/NzbDrone.Core/Queue/QueueStatus.cs diff --git a/frontend/src/Components/Filter/Builder/FilterBuilderRow.js b/frontend/src/Components/Filter/Builder/FilterBuilderRow.js index b5f52bf8be..9fd450d2ef 100644 --- a/frontend/src/Components/Filter/Builder/FilterBuilderRow.js +++ b/frontend/src/Components/Filter/Builder/FilterBuilderRow.js @@ -16,6 +16,7 @@ import MovieFilterBuilderRowValue from './MovieFilterBuilderRowValue'; import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue'; import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector'; import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue'; +import QueueStatusFilterBuilderRowValue from './QueueStatusFilterBuilderRowValue'; import ReleaseStatusFilterBuilderRowValue from './ReleaseStatusFilterBuilderRowValue'; import TagFilterBuilderRowValueConnector from './TagFilterBuilderRowValueConnector'; import styles from './FilterBuilderRow.css'; @@ -80,6 +81,9 @@ function getRowValueConnector(selectedFilterBuilderProp) { case filterBuilderValueTypes.QUALITY_PROFILE: return QualityProfileFilterBuilderRowValue; + case filterBuilderValueTypes.QUEUE_STATUS: + return QueueStatusFilterBuilderRowValue; + case filterBuilderValueTypes.MOVIE: return MovieFilterBuilderRowValue; diff --git a/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx b/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx new file mode 100644 index 0000000000..1127493a5c --- /dev/null +++ b/frontend/src/Components/Filter/Builder/QueueStatusFilterBuilderRowValue.tsx @@ -0,0 +1,67 @@ +import React from 'react'; +import translate from 'Utilities/String/translate'; +import FilterBuilderRowValue from './FilterBuilderRowValue'; +import FilterBuilderRowValueProps from './FilterBuilderRowValueProps'; + +const statusTagList = [ + { + id: 'queued', + get name() { + return translate('Queued'); + }, + }, + { + id: 'paused', + get name() { + return translate('Paused'); + }, + }, + { + id: 'downloading', + get name() { + return translate('Downloading'); + }, + }, + { + id: 'completed', + get name() { + return translate('Completed'); + }, + }, + { + id: 'failed', + get name() { + return translate('Failed'); + }, + }, + { + id: 'warning', + get name() { + return translate('Warning'); + }, + }, + { + id: 'delay', + get name() { + return translate('Delay'); + }, + }, + { + id: 'downloadClientUnavailable', + get name() { + return translate('DownloadClientUnavailable'); + }, + }, + { + id: 'fallback', + get name() { + return translate('Fallback'); + }, + }, +]; + +function QueueStatusFilterBuilderRowValue(props: FilterBuilderRowValueProps) { + return ; +} + +export default QueueStatusFilterBuilderRowValue; diff --git a/frontend/src/Components/Filter/Builder/ReleaseStatusFilterBuilderRowValue.js b/frontend/src/Components/Filter/Builder/ReleaseStatusFilterBuilderRowValue.js index a2aabae20c..d3feadb4f9 100644 --- a/frontend/src/Components/Filter/Builder/ReleaseStatusFilterBuilderRowValue.js +++ b/frontend/src/Components/Filter/Builder/ReleaseStatusFilterBuilderRowValue.js @@ -2,7 +2,7 @@ import React from 'react'; import translate from 'Utilities/String/translate'; import FilterBuilderRowValue from './FilterBuilderRowValue'; -const protocols = [ +const statusTagList = [ { id: 'tba', name: 'TBA' }, { id: 'announced', @@ -33,7 +33,7 @@ const protocols = [ function ReleaseStatusFilterBuilderRowValue(props) { return ( ); diff --git a/frontend/src/Helpers/Props/filterBuilderValueTypes.js b/frontend/src/Helpers/Props/filterBuilderValueTypes.js index 3e2d599ba3..a27b11dfc3 100644 --- a/frontend/src/Helpers/Props/filterBuilderValueTypes.js +++ b/frontend/src/Helpers/Props/filterBuilderValueTypes.js @@ -8,6 +8,7 @@ export const LANGUAGE = 'language'; export const PROTOCOL = 'protocol'; export const QUALITY = 'quality'; export const QUALITY_PROFILE = 'qualityProfile'; +export const QUEUE_STATUS = 'queueStatus'; export const MOVIE = 'movie'; export const RELEASE_STATUS = 'releaseStatus'; export const MINIMUM_AVAILABILITY = 'minimumAvailability'; diff --git a/frontend/src/Store/Actions/queueActions.js b/frontend/src/Store/Actions/queueActions.js index 214ea92abf..1196eff50f 100644 --- a/frontend/src/Store/Actions/queueActions.js +++ b/frontend/src/Store/Actions/queueActions.js @@ -201,6 +201,12 @@ export const defaultState = { label: () => translate('Protocol'), type: filterBuilderTypes.EQUAL, valueType: filterBuilderValueTypes.PROTOCOL + }, + { + name: 'status', + label: () => translate('Status'), + type: filterBuilderTypes.EQUAL, + valueType: filterBuilderValueTypes.QUEUE_STATUS } ] }, diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 9ea33e5ce9..75299e6c54 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -17,6 +17,7 @@ using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Profiles.Delay; using NzbDrone.Core.Qualities; +using NzbDrone.Core.Queue; namespace NzbDrone.Core.Download.Pending { @@ -340,7 +341,7 @@ private Queue.Queue GetQueueItem(PendingRelease pendingRelease, Lazy n Timeleft = timeleft, EstimatedCompletionTime = ect, Added = pendingRelease.Added, - Status = pendingRelease.Reason.ToString(), + Status = Enum.TryParse(pendingRelease.Reason.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown, Protocol = pendingRelease.RemoteMovie.Release.DownloadProtocol, Indexer = pendingRelease.RemoteMovie.Release.Indexer, DownloadClient = downloadClientName diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index b00ff949bc..bcbad92123 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -923,7 +923,6 @@ "DownloadedButNotMonitored": "تم التنزيل (غير مراقب)", "DownloadedAndMonitored": "تم التنزيل (مراقب)", "Downloaded": "تم التنزيل", - "DownloadClientUnavailable": "عميل التنزيل غير متوفر", "DownloadClientStatusCheckSingleClientMessage": "برامج التنزيل غير متاحة بسبب الإخفاقات: {downloadClientNames}", "DownloadClientStatusCheckAllClientMessage": "جميع عملاء التنزيل غير متاحين بسبب الفشل", "DownloadClientsSettingsSummary": "تنزيل العملاء وتنزيل المناولة وتعيينات المسار البعيد", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 6d274927b2..56fd6e3e41 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -177,7 +177,6 @@ "DownloadClients": "Изтеглете клиенти", "DownloadClientSettings": "Изтеглете настройките на клиента", "DownloadClientsSettingsSummary": "Изтегляне на клиенти, обработка на изтегляния и отдалечени картографски пътища", - "DownloadClientUnavailable": "Клиентът за изтегляне не е наличен", "Downloaded": "Изтеглено", "DownloadedAndMonitored": "Изтеглено (контролирано)", "DownloadedButNotMonitored": "Изтеглено (Без наблюдение)", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 643729a68c..7372592c99 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -449,7 +449,6 @@ "DownloadClientCheckDownloadingToRoot": "El client de baixada {downloadClientName} col·loca les baixades a la carpeta arrel {path}. No s'hauria de baixar a una carpeta arrel.", "DownloadClientCheckUnableToCommunicateMessage": "No es pot comunicar amb {downloadClientName}. {errorMessage}", "DownloadClientsSettingsSummary": "Descàrrega de clients, gestió de descàrregues i mapes de camins remots", - "DownloadClientUnavailable": "El client de descàrrega no està disponible", "Downloaded": "S'ha baixat", "DownloadedAndMonitored": "S'ha baixat (nonitorat)", "DownloadedButNotMonitored": "S'ha baixat (no monitorat)", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index b09adad33d..3f4a4854d8 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -49,7 +49,6 @@ "Discord": "Svár", "DownloadClients": "Stáhnout klienty", "DownloadClientsSettingsSummary": "Stahování klientů, zpracování stahování a mapování vzdálených cest", - "DownloadClientUnavailable": "Stahovací klient není k dispozici", "DownloadPropersAndRepacks": "Sponzoři a přebalení", "DownloadPropersAndRepacksHelpTextWarning": "Použijte automatické formáty pro automatické upgrady na Propers / Repacks", "EditPerson": "Upravit osobu", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 1caf847dea..7a8d2b97f4 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -522,7 +522,6 @@ "DoneEditingGroups": "Udført redigering af grupper", "DoNotPrefer": "Foretrækker ikke", "DownloadClientSettings": "Download klientindstillinger", - "DownloadClientUnavailable": "Downloadklienten er ikke tilgængelig", "DownloadedAndMonitored": "Downloadet (overvåget)", "DownloadedButNotMonitored": "Downloadet (ikke overvåget)", "Downloading": "Downloader", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index f6e5af1851..0660da23ec 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -619,7 +619,6 @@ "DownloadWarning": "Download Warnung: {0}", "Downloading": "Lädt herunter", "DownloadFailed": "Download fehlgeschlagen", - "DownloadClientUnavailable": "Downloader ist nicht verfügbar", "DeleteTagMessageText": "Bist du sicher, dass du den Tag '{label}' wirklich löschen willst?", "DeleteRestrictionHelpText": "Beschränkung '{0}' wirklich löschen?", "DeleteNotificationMessageText": "Bist du sicher, dass du die Benachrichtigung '{name}' wirklich löschen willst?", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index b5ce922fe2..ca97f319d1 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -510,7 +510,6 @@ "DoneEditingGroups": "Έγινε επεξεργασία ομάδων", "DoNotPrefer": "Μην προτιμάτε", "DoNotUpgradeAutomatically": "Μην κάνετε αυτόματη αναβάθμιση", - "DownloadClientUnavailable": "Ο πελάτης λήψης δεν είναι διαθέσιμος", "DownloadedAndMonitored": "Λήψη (Παρακολούθηση)", "DownloadedButNotMonitored": "Λήψη (Χωρίς παρακολούθηση)", "Downloading": "Λήψη", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 86e7267ca7..2f92b35dd0 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -222,6 +222,7 @@ "ColonReplacementFormatHelpText": "Change how {appName} handles colon replacement", "Columns": "Columns", "Complete": "Complete", + "Completed": "Completed", "CompletedDownloadHandling": "Completed Download Handling", "Component": "Component", "ConditionUsingRegularExpressions": "This condition matches using Regular Expressions. Note that the characters `\\^$.|?*+()[{` have special meanings and need escaping with a `\\`", @@ -291,6 +292,7 @@ "DefaultNameCopiedProfile": "{name} - Copy", "DefaultNameCopiedSpecification": "{name} - Copy", "DefaultNotFoundMessage": "You must be lost, nothing to see here.", + "Delay": "Delay", "DelayMinutes": "{delay} Minutes", "DelayProfile": "Delay Profile", "DelayProfileMovieTagsHelpText": "Applies to movies with at least one matching tag", @@ -517,7 +519,7 @@ "DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location", "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'", "DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error", - "DownloadClientUnavailable": "Download client is unavailable", + "DownloadClientUnavailable": "Download Client Unavailable", "DownloadClientValidationApiKeyIncorrect": "API Key Incorrect", "DownloadClientValidationApiKeyRequired": "API Key Required", "DownloadClientValidationAuthenticationFailure": "Authentication Failure", @@ -628,6 +630,7 @@ "FailedToFetchUpdates": "Failed to fetch updates", "FailedToLoadMovieFromAPI": "Failed to load movie from API", "FailedToUpdateSettings": "Failed to update settings", + "Fallback": "Fallback", "False": "False", "FavoriteFolderAdd": "Add Favorite Folder", "FavoriteFolderRemove": "Remove Favorite Folder", @@ -1842,6 +1845,7 @@ "WantMoreControlAddACustomFormat": "Want more control over which downloads are preferred? Add a [Custom Format](/settings/customformats)", "Wanted": "Wanted", "Warn": "Warn", + "Warning": "Warning", "Week": "Week", "WeekColumnHeader": "Week Column Header", "WeekColumnHeaderHelpText": "Shown above each column when week is the active view", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 0b6e762571..c4b2f95b76 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -620,7 +620,6 @@ "DownloadWarning": "Alerta de descarga: {warningMessage}", "Downloading": "Descargando", "DownloadFailed": "La descarga ha fallado", - "DownloadClientUnavailable": "El cliente de descargas no está disponible", "DeleteTagMessageText": "¿Estás seguro que quieres eliminar la etiqueta '{label}'?", "DeleteRestrictionHelpText": "¿Estás seguro que quieres eliminar esta restricción?", "DeleteNotificationMessageText": "¿Estás seguro que quieres eliminar la notificación '{name}'?", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index c1b027cd2f..42f51d2941 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -502,7 +502,6 @@ "EditCustomFormat": "Muokkaa mukautettua muotoa", "DownloadClientsSettingsSummary": "Lataustyökalut, latausten käsittely ja etäsijaintien kohdistukset.", "DownloadClientStatusCheckSingleClientMessage": "Lataustyökaluja ei ole ongelmien vuoksi käytettävissä: {downloadClientNames}", - "DownloadClientUnavailable": "Lataustyökalu ei ole käytettävissä", "Downloaded": "Ladattu", "DownloadedAndMonitored": "Ladattu (valvottu)", "DownloadedButNotMonitored": "Ladattu (valvomaton)", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index b56e681f51..f487342b3f 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -421,7 +421,6 @@ "EnableAutomaticSearchHelpText": "Sera utilisé lorsque les recherches automatiques sont effectuées via l'interface utilisateur ou par {appName}", "DownloadWarning": "Avertissement de téléchargement : {warningMessage}", "Downloading": "Téléchargement", - "DownloadClientUnavailable": "Le client de téléchargement n'est pas disponible", "DeleteRestrictionHelpText": "Voulez-vous vraiment supprimer cette restriction ?", "DeleteIndexerMessageText": "Voulez-vous vraiment supprimer l'indexeur « {name} » ?", "CopyToClipboard": "Copier dans le presse-papier", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index f5ca3654b3..68da6154d4 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -40,7 +40,6 @@ "DeleteEmptyFolders": "מחק תיקיות ריקות", "DeleteFile": "מחק קובץ", "DestinationPath": "נתיב יעד", - "DownloadClientUnavailable": "לקוח ההורדות אינו זמין", "EditMovie": "ערוך את הסרט", "EnableCompletedDownloadHandlingHelpText": "ייבא אוטומטית הורדות שהושלמו מלקוח ההורדות", "AnalyseVideoFilesHelpText": "חלץ מידע וידאו כגון רזולוציה, זמן ריצה ומידע קודק מקבצים. זה מחייב את {appName} לקרוא חלקים מהקובץ שעלולים לגרום לדיסק גבוה או לפעילות רשת במהלך הסריקות.", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index f4cb70953c..fbabfabb9a 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -63,7 +63,6 @@ "DeleteTagMessageText": "क्या आप वाकई '{0}' टैग हटाना चाहते हैं?", "DestinationRelativePath": "गंतव्य सापेक्ष पथ", "DetailedProgressBar": "विस्तृत प्रगति पट्टी", - "DownloadClientUnavailable": "डाउनलोड क्लाइंट अनुपलब्ध है", "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks में स्वचालित उन्नयन के लिए कस्टम स्वरूपों का उपयोग करें", "EditQualityProfile": "गुणवत्ता प्रोफ़ाइल संपादित करें", "EditRemotePathMapping": "दूरस्थ पथ मानचित्रण संपादित करें", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 8dbec6feac..00bb365301 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -42,7 +42,6 @@ "DownloadedButNotMonitored": "Letöltve, (nincs Figyelve)", "DownloadedAndMonitored": "Letöltve (Figyelve)", "Downloaded": "Letöltve", - "DownloadClientUnavailable": "Letöltőkliens nem elérhető", "DownloadClientStatusCheckSingleClientMessage": "Letöltőkliens hiba miatt nem elérhető: {downloadClientNames}", "DownloadClientStatusCheckAllClientMessage": "Az összes letöltőkliens elérhetetlen, hiba miatt", "DownloadClientsSettingsSummary": "Kliensek letöltése, letöltéskezelés és távoli útvonalleképezések", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 304c96c689..c81a2d8102 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -537,7 +537,6 @@ "AnalyseVideoFiles": "Greindu vídeóskrár", "AnalyticsEnabledHelpText": "Sendu nafnlausar upplýsingar um notkun og villur á netþjóna {appName}. Þetta felur í sér upplýsingar í vafranum þínum, hvaða {appName} WebUI síður þú notar, villuskýrslur sem og stýrikerfi og keyrsluútgáfu. Við munum nota þessar upplýsingar til að forgangsraða eiginleikum og villuleiðréttingum.", "AppDataDirectory": "AppData skrá", - "DownloadClientUnavailable": "Niðurhalsþjónn er ekki tiltækur", "Downloaded": "Sótt", "DownloadedAndMonitored": "Sótt (fylgst með)", "DownloadedButNotMonitored": "Sótt (óeftirlit)", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 109a9f91a4..779757c0ac 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -579,7 +579,6 @@ "DownloadFailed": "Download fallito", "DownloadedButNotMonitored": "Scaricato (non monitorato)", "DownloadedAndMonitored": "Scaricato (Monitorato)", - "DownloadClientUnavailable": "Il client di download non è disponibile", "DeleteTagMessageText": "Sei sicuro di voler eliminare l'etichetta '{label}'?", "DeleteRestrictionHelpText": "Sei sicuro di voler eliminare questa restrizione?", "DeleteNotificationMessageText": "Sei sicuro di voler eliminare la notifica '{name}'?", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index e9c1f6e5f9..a994ae89bc 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -39,7 +39,6 @@ "DeleteSelectedMovieFiles": "選択したムービーファイルを削除する", "DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName}と通信できません。", "DownloadClientsSettingsSummary": "クライアントのダウンロード、ダウンロード処理、リモートパスマッピング", - "DownloadClientUnavailable": "ダウンロードクライアントは利用できません", "DownloadedAndMonitored": "ダウンロード(監視)", "DownloadPropersAndRepacks": "適切なものと再梱包", "EditCustomFormat": "カスタムフォーマットの編集", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 5e855d0528..4fcaf89893 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -500,7 +500,6 @@ "DownloadClientSettings": "클라이언트 설정 다운로드", "DownloadClientsSettingsSummary": "클라이언트 다운로드, 다운로드 처리 및 원격 경로 매핑", "DownloadClientStatusCheckSingleClientMessage": "실패로 인해 다운 불러올 수 없는 클라이언트 : {downloadClientNames}", - "DownloadClientUnavailable": "다운로드 클라이언트를 사용할 수 없습니다.", "Downloaded": "다운로드됨", "DownloadedAndMonitored": "다운로드됨 (모니터링됨)", "DownloadedButNotMonitored": "다운로드됨 (모니터링되지 않음)", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 2ce6703479..7291b9f3bb 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -626,7 +626,6 @@ "DownloadWarning": "Download waarschuwing: {warningMessage}", "Downloading": "Downloaden", "DownloadFailed": "Download mislukt", - "DownloadClientUnavailable": "Downloader is onbeschikbaar", "DeleteTagMessageText": "Weet je zeker dat je de tag '{label}' wil verwijderen?", "DeleteRestrictionHelpText": "Bent u zeker dat u deze restrictie wilt verwijderen?", "DeleteNotificationMessageText": "Weet je zeker dat je de notificatie ‘{name}’ wil verwijderen?", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 18a076608c..96330360d6 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -512,7 +512,6 @@ "DownloadClientSettings": "Pobierz ustawienia klienta", "DownloadClientsSettingsSummary": "Pobieranie klientów, obsługa pobierania i mapowanie ścieżek zdalnych", "DownloadClientStatusCheckSingleClientMessage": "Klienci pobierania niedostępni z powodu błędów: {downloadClientNames}", - "DownloadClientUnavailable": "Klient pobierania jest niedostępny", "Downloaded": "Pobrano", "DownloadedAndMonitored": "Pobrane (monitorowane)", "DownloadedButNotMonitored": "Pobrane (niemonitorowane)", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index ecf70ee3c2..c4c6761aab 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -588,7 +588,6 @@ "DownloadFailed": "Falha na transferência", "DownloadedButNotMonitored": "Transferido (Não monitorado)", "DownloadedAndMonitored": "Transferido (Monitorado)", - "DownloadClientUnavailable": "O cliente de transferências está indisponível", "Disabled": "Desativado", "DeleteTagMessageText": "Tem a certeza que quer eliminar a etiqueta \"{label}\"?", "DeleteRestrictionHelpText": "Tem a certeza de que quer eliminar esta restrição?", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 74e66b24d8..0c4ecda79b 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -174,7 +174,6 @@ "DownloadedButNotMonitored": "Baixado (não monitorado)", "DownloadedAndMonitored": "Baixado (monitorado)", "Downloaded": "Baixado", - "DownloadClientUnavailable": "O cliente de download está indisponível", "DownloadClientStatusCheckSingleClientMessage": "Clientes de download indisponíveis devido a falhas: {downloadClientNames}", "DownloadClientStatusCheckAllClientMessage": "Todos os clientes de download estão indisponíveis devido a falhas", "DownloadClientsSettingsSummary": "Clientes de download, gerenciamento de download e mapeamentos de caminhos remotos", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 0929f79500..c1bf343730 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -638,7 +638,6 @@ "DoNotPrefer": "Nu preferați", "DoNotUpgradeAutomatically": "Nu faceți upgrade automat", "DownloadClientSettings": "Setări client de descărcare", - "DownloadClientUnavailable": "Clientul de descărcare nu este disponibil", "DownloadedAndMonitored": "Descărcat (monitorizat)", "DownloadedButNotMonitored": "Descărcat (fără monitorizare)", "Downloading": "Descărcarea", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index b8f6268712..0822344288 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -634,7 +634,6 @@ "DownloadedButNotMonitored": "Скачано (неотслеживается)", "DownloadedAndMonitored": "Скачано (Отслежено)", "Downloaded": "Скачано", - "DownloadClientUnavailable": "Программа для скачивания недоступна", "PhysicalRelease": "Релиз на носителе", "PhysicalReleaseDate": "Дата релиза на носителе", "MountCheckMessage": "Смонтированный путь к фильму смонтировано режиме только для чтения: ", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index a622186022..0f9c433468 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -301,7 +301,6 @@ "Edition": "Utgåva", "Downloading": "Laddar ner", "DownloadFailed": "Misslyckad nedladdning", - "DownloadClientUnavailable": "Nedladdningsklient är otillgänglig", "DownloadClientSettings": "Inställningar för Nedladdningsklient", "Docker": "Docker", "Disabled": "Inaktiverad", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 2c27ee2655..eb159fbd3a 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -587,7 +587,6 @@ "DownloadClientSettings": "ดาวน์โหลด Client Settings", "DownloadClientsSettingsSummary": "ดาวน์โหลดไคลเอนต์การจัดการการดาวน์โหลดและการแมปเส้นทางระยะไกล", "DownloadClientStatusCheckSingleClientMessage": "ดาวน์โหลดไคลเอ็นต์ไม่ได้เนื่องจากความล้มเหลว: {downloadClientNames}", - "DownloadClientUnavailable": "ไม่สามารถดาวน์โหลดไคลเอนต์ได้", "Downloaded": "ดาวน์โหลดแล้ว", "DownloadedButNotMonitored": "ดาวน์โหลด (ไม่ได้ตรวจสอบ)", "DownloadFailed": "ดาวน์โหลดล้มเหลว", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 4c31719ae7..c716df3daf 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -694,7 +694,6 @@ "DownloadClientSettings": "İstemci Ayarlarını İndir", "DownloadClientsSettingsSummary": "İndirme İstemcileri, indirme işlemleri ve uzaktan yol eşlemeleri", "DownloadClientStatusCheckSingleClientMessage": "Hatalar nedeniyle indirilemeyen istemciler: {downloadClientNames}", - "DownloadClientUnavailable": "İndirme istemcisi kullanılamıyor", "DownloadedAndMonitored": "İndirildi (Takip Ediliyor)", "DownloadedButNotMonitored": "İndirildi (Takip Edilmiyor)", "DownloadFailed": "Yükleme başarısız", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index bfa87bd864..f1238e8b10 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -569,7 +569,6 @@ "DeleteQualityProfile": "Видалити профіль якості", "DeleteRestriction": "Видалити обмеження", "DownloadedAndMonitored": "Завантажено (Відстежується)", - "DownloadClientUnavailable": "Клієнт завантажувача недоступний", "DownloadedButNotMonitored": "Завантажено (Не відстежується)", "DownloadFailed": "Помилка завантаження", "DownloadWarning": "Попередження про завантаження: {0}", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index d6ba547cbf..6b1d33ebfe 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -59,7 +59,6 @@ "DeleteSelectedMovieFiles": "Xóa các tệp phim đã chọn", "DownloadClient": "Tải xuống ứng dụng khách", "DownloadClientSettings": "Tải xuống cài đặt ứng dụng khách", - "DownloadClientUnavailable": "Ứng dụng khách tải xuống không khả dụng", "DownloadPropersAndRepacksHelpTextWarning": "Sử dụng các định dạng tùy chỉnh để tự động nâng cấp lên Người ủng hộ / Đóng gói lại", "EditImportListExclusion": "Chỉnh sửa Loại trừ Danh sách", "EditRemotePathMapping": "Chỉnh sửa ánh xạ đường dẫn từ xa", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 789eb94a5b..5a82b02a9e 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -408,7 +408,6 @@ "DownloadWarning": "下载警告:{warningMessage}", "DownloadedButNotMonitored": "已下载(未追踪)", "DownloadedAndMonitored": "已下载(已追踪)", - "DownloadClientUnavailable": "下载客户端不可用", "DownloadClientStatusCheckSingleClientMessage": "所有下载客户端都不可用: {downloadClientNames}", "DownloadClientStatusCheckAllClientMessage": "下载客户端因故障均不可用", "DownloadClientsSettingsSummary": "下载客户端、下载处理和远程路径映射", diff --git a/src/NzbDrone.Core/Queue/Queue.cs b/src/NzbDrone.Core/Queue/Queue.cs index 41612a793e..acfd7bbd97 100644 --- a/src/NzbDrone.Core/Queue/Queue.cs +++ b/src/NzbDrone.Core/Queue/Queue.cs @@ -21,7 +21,7 @@ public class Queue : ModelBase public TimeSpan? Timeleft { get; set; } public DateTime? EstimatedCompletionTime { get; set; } public DateTime? Added { get; set; } - public string Status { get; set; } + public QueueStatus Status { get; set; } public TrackedDownloadStatus? TrackedDownloadStatus { get; set; } public TrackedDownloadState? TrackedDownloadState { get; set; } public List StatusMessages { get; set; } diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs index e33e794961..92ec872371 100644 --- a/src/NzbDrone.Core/Queue/QueueService.cs +++ b/src/NzbDrone.Core/Queue/QueueService.cs @@ -64,7 +64,7 @@ private Queue MapMovie(TrackedDownload trackedDownload, Movie movie) Size = trackedDownload.DownloadItem.TotalSize, Sizeleft = trackedDownload.DownloadItem.RemainingSize, Timeleft = trackedDownload.DownloadItem.RemainingTime, - Status = trackedDownload.DownloadItem.Status.ToString(), + Status = Enum.TryParse(trackedDownload.DownloadItem.Status.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown, TrackedDownloadStatus = trackedDownload.Status, TrackedDownloadState = trackedDownload.State, StatusMessages = trackedDownload.StatusMessages.ToList(), diff --git a/src/NzbDrone.Core/Queue/QueueStatus.cs b/src/NzbDrone.Core/Queue/QueueStatus.cs new file mode 100644 index 0000000000..77b0751d95 --- /dev/null +++ b/src/NzbDrone.Core/Queue/QueueStatus.cs @@ -0,0 +1,16 @@ +namespace NzbDrone.Core.Queue +{ + public enum QueueStatus + { + Unknown, + Queued, + Paused, + Downloading, + Completed, + Failed, + Warning, + Delay, + DownloadClientUnavailable, + Fallback + } +} diff --git a/src/Radarr.Api.V3/Queue/QueueController.cs b/src/Radarr.Api.V3/Queue/QueueController.cs index 03f95cad8f..0b506fea43 100644 --- a/src/Radarr.Api.V3/Queue/QueueController.cs +++ b/src/Radarr.Api.V3/Queue/QueueController.cs @@ -136,7 +136,7 @@ public object RemoveMany([FromBody] QueueBulkResource resource, [FromQuery] bool [HttpGet] [Produces("application/json")] - public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownMovieItems = false, bool includeMovie = false, [FromQuery] int[] movieIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null) + public PagingResource GetQueue([FromQuery] PagingRequestResource paging, bool includeUnknownMovieItems = false, bool includeMovie = false, [FromQuery] int[] movieIds = null, DownloadProtocol? protocol = null, [FromQuery] int[] languages = null, [FromQuery] int[] quality = null, [FromQuery] QueueStatus[] status = null) { var pagingResource = new PagingResource(paging); var pagingSpec = pagingResource.MapToPagingSpec( @@ -160,10 +160,10 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource "timeleft", SortDirection.Ascending); - return pagingSpec.ApplyToPage((spec) => GetQueue(spec, movieIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality?.ToHashSet(), includeUnknownMovieItems), (q) => MapToResource(q, includeMovie)); + return pagingSpec.ApplyToPage((spec) => GetQueue(spec, movieIds?.ToHashSet(), protocol, languages?.ToHashSet(), quality?.ToHashSet(), status?.ToHashSet(), includeUnknownMovieItems), (q) => MapToResource(q, includeMovie)); } - private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet movieIds, DownloadProtocol? protocol, HashSet languages, HashSet quality, bool includeUnknownMovieItems) + private PagingSpec GetQueue(PagingSpec pagingSpec, HashSet movieIds, DownloadProtocol? protocol, HashSet languages, HashSet quality, HashSet status, bool includeUnknownMovieItems) { var ascending = pagingSpec.SortDirection == SortDirection.Ascending; var orderByFunc = GetOrderByFunc(pagingSpec); @@ -175,6 +175,7 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource var hasMovieIdFilter = movieIds.Any(); var hasLanguageFilter = languages.Any(); var hasQualityFilter = quality.Any(); + var hasStatusFilter = status.Any(); var fullQueue = filteredQueue.Concat(pending).Where(q => { @@ -200,6 +201,11 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource include &= quality.Contains(q.Quality.Quality.Id); } + if (include && hasStatusFilter) + { + include &= status.Contains(q.Status); + } + return include; }).ToList(); @@ -279,7 +285,7 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource switch (pagingSpec.SortKey) { case "status": - return q => q.Status; + return q => q.Status.ToString(); case "movies.sortTitle": return q => q.Movie?.MovieMetadata.Value.SortTitle ?? q.Title; case "title": diff --git a/src/Radarr.Api.V3/Queue/QueueResource.cs b/src/Radarr.Api.V3/Queue/QueueResource.cs index d19ab42fce..e3826396b9 100644 --- a/src/Radarr.Api.V3/Queue/QueueResource.cs +++ b/src/Radarr.Api.V3/Queue/QueueResource.cs @@ -1,11 +1,11 @@ using System; using System.Collections.Generic; using System.Linq; -using NzbDrone.Common.Extensions; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Indexers; using NzbDrone.Core.Languages; using NzbDrone.Core.Qualities; +using NzbDrone.Core.Queue; using Radarr.Api.V3.CustomFormats; using Radarr.Api.V3.Movies; using Radarr.Http.REST; @@ -26,7 +26,7 @@ public class QueueResource : RestResource public TimeSpan? Timeleft { get; set; } public DateTime? EstimatedCompletionTime { get; set; } public DateTime? Added { get; set; } - public string Status { get; set; } + public QueueStatus Status { get; set; } public TrackedDownloadStatus? TrackedDownloadStatus { get; set; } public TrackedDownloadState? TrackedDownloadState { get; set; } public List StatusMessages { get; set; } @@ -66,7 +66,7 @@ public static QueueResource ToResource(this NzbDrone.Core.Queue.Queue model, boo Timeleft = model.Timeleft, EstimatedCompletionTime = model.EstimatedCompletionTime, Added = model.Added, - Status = model.Status.FirstCharToLower(), + Status = model.Status, TrackedDownloadStatus = model.TrackedDownloadStatus, TrackedDownloadState = model.TrackedDownloadState, StatusMessages = model.StatusMessages, From b1df9b2401e0e2d593dc681b5292b7a3b8adca85 Mon Sep 17 00:00:00 2001 From: Servarr Date: Mon, 4 Nov 2024 13:16:19 +0000 Subject: [PATCH 077/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 35 ++++++++++++++++++++++++++++++---- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 80b72ce54f..1634327679 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -6569,8 +6569,21 @@ "name": "quality", "in": "query", "schema": { - "type": "integer", - "format": "int32" + "type": "array", + "items": { + "type": "integer", + "format": "int32" + } + } + }, + { + "name": "status", + "in": "query", + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/QueueStatus" + } } } ], @@ -11676,8 +11689,7 @@ "nullable": true }, "status": { - "type": "string", - "nullable": true + "$ref": "#/components/schemas/QueueStatus" }, "trackedDownloadStatus": { "$ref": "#/components/schemas/TrackedDownloadStatus" @@ -11753,6 +11765,21 @@ }, "additionalProperties": false }, + "QueueStatus": { + "enum": [ + "unknown", + "queued", + "paused", + "downloading", + "completed", + "failed", + "warning", + "delay", + "downloadClientUnavailable", + "fallback" + ], + "type": "string" + }, "QueueStatusResource": { "type": "object", "properties": { From c8301d425c9b4b227a45b0376a13c63c581a92ba Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 4 Nov 2024 19:26:13 +0200 Subject: [PATCH 078/579] Fix translation token for Mount Health Check --- src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs | 2 +- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 2 +- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- src/NzbDrone.Core/Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- src/NzbDrone.Core/Localization/Core/zh_CN.json | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs index 3e88dd7515..5163b78d2e 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/MountCheck.cs @@ -31,7 +31,7 @@ public override HealthCheck Check() { return new HealthCheck(GetType(), HealthCheckResult.Error, - $"{_localizationService.GetLocalizedString("MountCheckMessage")}{string.Join(", ", mounts.Select(m => $"{m.Item1.Name} ({m.Item2})"))}", + $"{_localizationService.GetLocalizedString("MountMovieHealthCheckMessage")}{string.Join(", ", mounts.Select(m => $"{m.Item1.Name} ({m.Item2})"))}", "#movie-mount-ro"); } diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index bcbad92123..095204085d 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -832,7 +832,7 @@ "MoveFolders2": "هل تريد نقل ملفات الأفلام من \"{0}\" إلى \"{1}\"؟", "MoveFolders1": "هل تريد نقل مجلدات الفيلم إلى \"{0}\"؟", "MoveFiles": "نقل الملفات", - "MountCheckMessage": "تم تثبيت الحامل الذي يحتوي على مسار فيلم للقراءة فقط: ", + "MountMovieHealthCheckMessage": "تم تثبيت الحامل الذي يحتوي على مسار فيلم للقراءة فقط: ", "MoreInfo": "مزيد من المعلومات", "MoreDetails": "المزيد من التفاصيل", "Months": "الشهور", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 56fd6e3e41..398d9eae7f 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -59,7 +59,7 @@ "Month": "Месец", "MoreDetails": "Повече информация", "EditDelayProfile": "Редактиране на профил за забавяне", - "MountCheckMessage": "Монтажът, съдържащ път на филм, е монтиран само за четене: ", + "MountMovieHealthCheckMessage": "Монтажът, съдържащ път на филм, е монтиран само за четене: ", "MovieFolderFormat": "Формат на папка за филми", "MovieInfoLanguageHelpText": "Език, който {appName} ще използва за информация за филми в потребителския интерфейс", "IncludeCustomFormatWhenRenamingHelpText": "Включете във формат за преименуване на {Custom Formats}", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 7372592c99..35af218e2e 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -606,7 +606,7 @@ "MonitorMovie": "Monitora pel·lícula", "MoreDetails": "Més detalls", "MoreInfo": "Més informació", - "MountCheckMessage": "El muntatge que conté una ruta de pel·lícula es munta com a només de lectura: ", + "MountMovieHealthCheckMessage": "El muntatge que conté una ruta de pel·lícula es munta com a només de lectura: ", "MoveFiles": "Mou arxius", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Falta la carpeta arrel per a la col·lecció de pel·lícules: {rootFolderInfo}", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Falten diverses carpetes arrel per a les col·leccions de pel·lícules: {rootFoldersInfo}", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 3f4a4854d8..ce2f9bfcb8 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -141,7 +141,7 @@ "Import": "Import", "Manual": "Manuál", "MinimumFreeSpace": "Minimální volné místo", - "MountCheckMessage": "Mount obsahující filmovou cestu je připojen jen pro čtení: ", + "MountMovieHealthCheckMessage": "Mount obsahující filmovou cestu je připojen jen pro čtení: ", "Announced": "Oznámeno", "AvailabilityDelayHelpText": "Množství času před nebo po dostupném datu pro vyhledání filmu", "ImportExistingMovies": "Importovat existující filmy", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 7a8d2b97f4..d35f04276c 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -362,7 +362,7 @@ "Missing": "Mangler", "Month": "Måned", "MoreDetails": "Flere detaljer", - "MountCheckMessage": "Mount, der indeholder en filmsti, er monteret skrivebeskyttet: ", + "MountMovieHealthCheckMessage": "Mount, der indeholder en filmsti, er monteret skrivebeskyttet: ", "MovieFolderFormat": "Filmmappeformat", "MovieID": "Film-ID", "MovieIndex": "Filmindeks", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 0660da23ec..93899f74f5 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -77,7 +77,7 @@ "Monitor": "Beobachten", "Month": "Monat", "MoreInfo": "Mehr Infos", - "MountCheckMessage": "Der Einhängepunkt, welcher einen Filmpfad enthält, ist schreibgeschützt eingehängt: ", + "MountMovieHealthCheckMessage": "Der Einhängepunkt, welcher einen Filmpfad enthält, ist schreibgeschützt eingehängt: ", "Movie": "Film", "MovieEditor": "Filmeditor", "MovieIndex": "Filmindex", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index ca97f319d1..8f481fab83 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -345,7 +345,7 @@ "Missing": "Λείπει", "Month": "Μήνας", "MoreDetails": "Περισσότερες λεπτομέρειες", - "MountCheckMessage": "Το προσάρτημα που περιέχει μια διαδρομή ταινίας είναι τοποθετημένο μόνο για ανάγνωση: ", + "MountMovieHealthCheckMessage": "Το προσάρτημα που περιέχει μια διαδρομή ταινίας είναι τοποθετημένο μόνο για ανάγνωση: ", "MovieID": "Αναγνωριστικό ταινίας", "MovieIndex": "Ευρετήριο ταινιών", "MovieInfoLanguageHelpText": "Γλώσσα που θα χρησιμοποιήσει ο {appName} για πληροφορίες ταινίας στο περιβάλλον χρήστη", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 2f92b35dd0..5160649fe2 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -971,7 +971,7 @@ "More": "More", "MoreDetails": "More details", "MoreInfo": "More Info", - "MountCheckMessage": "Mount containing a movie path is mounted read-only: ", + "MountMovieHealthCheckMessage": "Mount containing a movie path is mounted read-only: ", "MoveAutomatically": "Move Automatically", "MoveFiles": "Move Files", "MoveFolders1": "Would you like to move the movie folders to '{0}' ?", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index c4b2f95b76..8c75fdb1c7 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -168,7 +168,7 @@ "PhysicalRelease": "Estreno Físico", "OutputPath": "Ruta de salida", "MovieTitle": "Título de la Película", - "MountCheckMessage": "El punto de montaje que contiene la ruta de una película es de solo lectura: ", + "MountMovieHealthCheckMessage": "El punto de montaje que contiene la ruta de una película es de solo lectura: ", "MonitoredOnly": "Solo monitorizados", "MetadataSettingsMovieSummary": "Crea archivos de metadatos cuando las películas se importen o actualicen", "MediaManagementSettingsSummary": "Ajustes de nombrado y gestión de archivos", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 42f51d2941..0a891bba4f 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -279,7 +279,7 @@ "Missing": "Puuttuu", "Month": "Kuukausi", "MoreDetails": "Lisätietoja", - "MountCheckMessage": "Kohteen sijainnin sisältävä media on kytketty vain luku -tilassa: ", + "MountMovieHealthCheckMessage": "Kohteen sijainnin sisältävä media on kytketty vain luku -tilassa: ", "MovieID": "Elokuvan tunnus", "MovieIndex": "Elokuvakirjasto", "MovieInfoLanguageHelpText": "{appName}in käyttöliittymässä näkyvien elokuvatietojen kieli.", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index f487342b3f..e4ac88e5fb 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -138,7 +138,7 @@ "MovieIndex": "Index des films", "MovieEditor": "Éditeur de films", "Movie": "Film", - "MountCheckMessage": "Le montage contenant un chemin de film est monté en lecture seule : ", + "MountMovieHealthCheckMessage": "Le montage contenant un chemin de film est monté en lecture seule : ", "MoreInfo": "Plus d'informations", "Month": "Mois", "ImportListsSettingsSummary": "Importer depuis une autre instance {appName} ou des listes Trakt et gérer les exclusions de listes", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 68da6154d4..154f0dfa21 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -273,7 +273,7 @@ "MinutesSixty": "60 דקות: {0}", "Missing": "חָסֵר", "MoreDetails": "פרטים נוספים", - "MountCheckMessage": "הר המכיל נתיב סרט מותקן לקריאה בלבד: ", + "MountMovieHealthCheckMessage": "הר המכיל נתיב סרט מותקן לקריאה בלבד: ", "MovieFolderFormat": "פורמט תיקיית סרטים", "MovieID": "מזהה סרט", "MovieIndex": "אינדקס סרטים", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index fbabfabb9a..5038d36998 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -463,7 +463,7 @@ "MinutesSixty": "60 मिनट: {0}", "Missing": "लापता", "MoreDetails": "अधिक जानकारी", - "MountCheckMessage": "मूवी पथ पर माउंट माउंट केवल पढ़ने योग्य है: ", + "MountMovieHealthCheckMessage": "मूवी पथ पर माउंट माउंट केवल पढ़ने योग्य है: ", "MovieIndex": "मूवी इंडेक्स", "MovieInfoLanguageHelpText": "यूआई में मूवी की जानकारी के लिए {appName} जो भाषा का उपयोग करेगा", "MovieInfoLanguageHelpTextWarning": "ब्राउज़र रीलोड आवश्यक है", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 00bb365301..6097a68e9a 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -507,7 +507,7 @@ "MovieAlreadyExcluded": "A film már ki lett zárva", "Movie": "Film", "MoveFiles": "Fájlok áthelyezése", - "MountCheckMessage": "A filmútvonalat tartalmazó mappa csak olvasható: ", + "MountMovieHealthCheckMessage": "A filmútvonalat tartalmazó mappa csak olvasható: ", "MoreInfo": "Több információ", "YouCanAlsoSearch": "Kereshetsz a film TMDb azonosítójával vagy IMDb azonosítójával is. Például. \"tmdb: 71663\"", "MonitorMovie": "Film Monitorozása", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index c81a2d8102..ea3cc90025 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -9,7 +9,7 @@ "SuggestTranslationChange": "Legg til þýðingabreytingu", "IndexerStatusCheckAllClientMessage": "Allir verðtryggingaraðilar eru ekki tiltækir vegna bilana", "Level": "Stig", - "MountCheckMessage": "Fjall sem inniheldur kvikmyndaslóð er aðeins skrifvarið: ", + "MountMovieHealthCheckMessage": "Fjall sem inniheldur kvikmyndaslóð er aðeins skrifvarið: ", "MovieInfoLanguageHelpTextWarning": "Endurhlaða vafra krafist", "ProtocolHelpText": "Veldu hvaða samskiptareglur (s) á að nota og hver er valinn þegar þú velur á milli annars jafnra útgáfa", "SupportedDownloadClients": "{appName} styður hvaða niðurhals viðskiptavinur sem notar Newznab staðalinn, auk annarra niðurhals viðskiptavina sem taldir eru upp hér að neðan.", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 779757c0ac..fd90acdcc8 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -35,7 +35,7 @@ "NoChanges": "Nessun Cambiamento", "NoChange": "Nessun Cambio", "MovieNaming": "Nomi dei Film", - "MountCheckMessage": "La destinazione contenente il percorso di un film è montata in sola lettura: ", + "MountMovieHealthCheckMessage": "La destinazione contenente il percorso di un film è montata in sola lettura: ", "MonitoredOnly": "Solo Monitorati", "Monitor": "Segui", "MediaManagementSettingsSummary": "Impostazioni di ridenominazione e gestione file", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index a994ae89bc..5dc3a3d467 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -315,7 +315,7 @@ "Missing": "行方不明", "Month": "月", "MoreDetails": "詳細", - "MountCheckMessage": "ムービーパスを含むマウントは読み取り専用でマウントされます。 ", + "MountMovieHealthCheckMessage": "ムービーパスを含むマウントは読み取り専用でマウントされます。 ", "MovieFolderFormat": "ムービーフォルダ形式", "MovieID": "映画ID", "MovieIndex": "映画インデックス", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 4fcaf89893..f7fce91639 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -315,7 +315,7 @@ "MinutesSixty": "60 분 : {0}", "Missing": "잃어버린", "Month": "달", - "MountCheckMessage": "동영상 경로가 포함된 마운트는 읽기 전용으로 마운트됩니다. ", + "MountMovieHealthCheckMessage": "동영상 경로가 포함된 마운트는 읽기 전용으로 마운트됩니다. ", "MovieID": "영화 ID", "MovieIndex": "영화 색인", "MovieInfoLanguageHelpText": "{appName}가 UI의 영화 정보에 사용할 언어", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 7291b9f3bb..2a82a2bd1f 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -148,7 +148,7 @@ "ProxyCheckResolveIpMessage": "Achterhalen van het IP-adres voor de geconfigureerde proxy host {proxyHostName} is mislukt", "ProxyCheckFailedToTestMessage": "Testen van proxy is mislukt: {url}", "ProxyCheckBadRequestMessage": "Testen van proxy is mislukt. Statuscode: {statusCode}", - "MountCheckMessage": "Een mount dat een film pad bevat is gemount als alleen-lezen: ", + "MountMovieHealthCheckMessage": "Een mount dat een film pad bevat is gemount als alleen-lezen: ", "Wanted": "Gezocht", "UpdateSelected": "Selectie Bijwerken", "UiSettingsSummary": "Kalender, datum en tijd, kleurenblindheid en taal instellingen", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 96330360d6..874dcfe00a 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -61,7 +61,7 @@ "DeleteTag": "Usuń tag", "IncludeCustomFormatWhenRenaming": "Uwzględnij format niestandardowy podczas zmiany nazwy", "LoadingMovieExtraFilesFailed": "Ładowanie dodatkowych plików filmowych nie powiodło się", - "MountCheckMessage": "Montaż zawierający ścieżkę filmu jest montowany tylko do odczytu: ", + "MountMovieHealthCheckMessage": "Montaż zawierający ścieżkę filmu jest montowany tylko do odczytu: ", "SupportedListsMovie": "{appName} obsługuje wszystkie listy filmów RSS, jak również wymienione poniżej.", "RecyclingBinHelpText": "Pliki filmowe trafią tutaj po usunięciu, a nie na stałe", "Restore": "Przywracać", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index c4c6761aab..af10c3a66a 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -155,7 +155,7 @@ "MovieEditor": "Editor de filmes", "Movie": "Filme", "MoveFiles": "Mover ficheiros", - "MountCheckMessage": "O volume que contém um caminho de filme é somente leitura: ", + "MountMovieHealthCheckMessage": "O volume que contém um caminho de filme é somente leitura: ", "MoreInfo": "Mais informações", "Month": "Mês", "MonitorMovie": "Monitorar filme", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 0c4ecda79b..d5488d357d 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -494,7 +494,7 @@ "MoveFolders2": "Deseja mover os arquivos de filmes de \"{0}\" para \"{1}\"?", "MoveFolders1": "Deseja mover as pastas de filmes para \"{0}\"?", "MoveFiles": "Mover arquivos", - "MountCheckMessage": "A montagem que contém um caminho de filme é montada somente para leitura: ", + "MountMovieHealthCheckMessage": "A montagem que contém um caminho de filme é montada somente para leitura: ", "MoreInfo": "Mais informações", "MoreDetails": "Mais detalhes", "Months": "Meses", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index c1bf343730..2214381d26 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -111,7 +111,7 @@ "MovieEditor": "Editor Filme", "Movie": "Film", "MoveFiles": "Mută Fișiere", - "MountCheckMessage": "Calea ce conține filme este montată în mod de read-only: ", + "MountMovieHealthCheckMessage": "Calea ce conține filme este montată în mod de read-only: ", "MoreInfo": "Mai multe informații", "Month": "Lună", "MonitoredOnly": "Doar monitorizate", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 0822344288..bfc8c1160f 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -636,7 +636,7 @@ "Downloaded": "Скачано", "PhysicalRelease": "Релиз на носителе", "PhysicalReleaseDate": "Дата релиза на носителе", - "MountCheckMessage": "Смонтированный путь к фильму смонтировано режиме только для чтения: ", + "MountMovieHealthCheckMessage": "Смонтированный путь к фильму смонтировано режиме только для чтения: ", "MinimumLimits": "Минимальные ограничения", "MinimumCustomFormatScore": "Минимальная оценка пользовательского формата", "MinimumAgeHelpText": "Только для Usenet: минимальный возраст NZB в минутах до их захвата. Используйте это, чтобы дать новым релизам время распространиться среди вашего провайдера Usenet.", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 0f9c433468..3eeebbeed9 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -199,7 +199,7 @@ "MovieIndex": "Filmindex", "MovieEditor": "Filmredigerare", "Movie": "Film", - "MountCheckMessage": "Montering (eng. Mount) innehållande filmsökväg är monterad med endast Läs-behörighet: ", + "MountMovieHealthCheckMessage": "Montering (eng. Mount) innehållande filmsökväg är monterad med endast Läs-behörighet: ", "Warn": "Varna", "VideoCodec": "Video codec", "Unavailable": "Otillgänglig", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index eb159fbd3a..4774dd7362 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -426,7 +426,7 @@ "Missing": "หายไป", "Month": "เดือน", "MoreDetails": "รายละเอียดเพิ่มเติม", - "MountCheckMessage": "เมาท์ที่มีเส้นทางภาพยนตร์ถูกเมาท์แบบอ่านอย่างเดียว: ", + "MountMovieHealthCheckMessage": "เมาท์ที่มีเส้นทางภาพยนตร์ถูกเมาท์แบบอ่านอย่างเดียว: ", "MovieID": "รหัสภาพยนตร์", "MovieIndex": "ดัชนีภาพยนตร์", "MovieInfoLanguageHelpText": "ภาษาที่ {appName} จะใช้สำหรับข้อมูลภาพยนตร์ใน UI", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index c716df3daf..d3ac8b301a 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -208,7 +208,7 @@ "MarkAsFailed": "Başarısız olarak işaretle", "MaximumSizeHelpText": "MB cinsinden alınacak bir sürüm için maksimum boyut. Sınırsız olarak ayarlamak için sıfıra ayarlayın", "MediaManagementSettings": "Medya Yönetimi Ayarları", - "MountCheckMessage": "Bir film yolu içeren bağlama, salt okunur olarak bağlanır: ", + "MountMovieHealthCheckMessage": "Bir film yolu içeren bağlama, salt okunur olarak bağlanır: ", "RadarrTags": "{appName} Etiketleri", "VideoCodec": "Video Codec", "NoLimitForAnyRuntime": "Herhangi bir çalışma zamanı için sınır yok", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index f1238e8b10..5240f21343 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -223,7 +223,7 @@ "Monday": "Понеділок", "MonitoredHelpText": "Завантажте фільм, якщо є", "MoreDetails": "Детальніше", - "MountCheckMessage": "Монтування, що містить шлях до фільму, монтується лише для читання: ", + "MountMovieHealthCheckMessage": "Монтування, що містить шлях до фільму, монтується лише для читання: ", "MovieIsRecommend": "Фільм рекомендовано на основі останнього додавання", "MovieIsOnImportExclusionList": "Фільм у списку винятків для імпорту", "MultiLanguage": "Багатомовність", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 6b1d33ebfe..9d7726d819 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -24,7 +24,7 @@ "MediaManagementSettingsSummary": "Cài đặt đặt tên và quản lý tệp", "MinutesSixty": "60 phút: {0}", "MoreDetails": "Thêm chi tiết", - "MountCheckMessage": "Mount chứa đường dẫn phim được mount ở chế độ chỉ đọc: ", + "MountMovieHealthCheckMessage": "Mount chứa đường dẫn phim được mount ở chế độ chỉ đọc: ", "MovieID": "ID phim", "MovieIndex": "Mục lục phim", "MovieInfoLanguageHelpText": "Ngôn ngữ mà {appName} sẽ sử dụng cho Thông tin phim trong giao diện người dùng", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 5a82b02a9e..9e87faf114 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -797,7 +797,7 @@ "Age": "年龄", "CustomFormatHelpText": "{appName} 会根据满足自定义格式与否给每个发布版本评分,如果一个新的发布版本有更高的分数且有相同或更高的质量,则 {appName} 会抓取该发布版本。", "LookingForReleaseProfiles2": "代替。", - "MountCheckMessage": "包含电影路径的挂载点被设置为只读: ", + "MountMovieHealthCheckMessage": "包含电影路径的挂载点被设置为只读: ", "NoAlternativeTitles": "没有其他标题。", "PreviewRenameHelpText": "小提示:要预览重命名效果,选择 “取消” ,然后点击任何电影标题并使用", "PtpOldSettingsCheckMessage": "以下 PassThePopcorn 索引器的设置已弃用,应更新为:{0}", From 12d50141259e3a73714e8345a0037da6a8a1697b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 5 Nov 2024 14:31:08 +0200 Subject: [PATCH 079/579] New: Track Kometa metadata files Co-authored-by: Stevie Robinson Fixes #10059 Fixes #10419 Closes #10311 --- .../Kometa/FindMetadataFileFixture.cs | 59 +++++++++++++ .../Consumers/Kometa/KometaMetadata.cs | 86 +++++++++++++++++++ .../Kometa/KometaMetadataSettings.cs | 29 +++++++ 3 files changed, 174 insertions(+) create mode 100644 src/NzbDrone.Core.Test/Extras/Metadata/Consumers/Kometa/FindMetadataFileFixture.cs create mode 100644 src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs create mode 100644 src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs diff --git a/src/NzbDrone.Core.Test/Extras/Metadata/Consumers/Kometa/FindMetadataFileFixture.cs b/src/NzbDrone.Core.Test/Extras/Metadata/Consumers/Kometa/FindMetadataFileFixture.cs new file mode 100644 index 0000000000..7a9a8608c0 --- /dev/null +++ b/src/NzbDrone.Core.Test/Extras/Metadata/Consumers/Kometa/FindMetadataFileFixture.cs @@ -0,0 +1,59 @@ +using System.IO; +using FizzWare.NBuilder; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Extras.Metadata; +using NzbDrone.Core.Extras.Metadata.Consumers.Kometa; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Test.Framework; +using NzbDrone.Test.Common; + +namespace NzbDrone.Core.Test.Extras.Metadata.Consumers.Kometa +{ + [TestFixture] + public class FindMetadataFileFixture : CoreTest + { + private Movie _movie; + + [SetUp] + public void Setup() + { + _movie = Builder.CreateNew() + .With(s => s.Path = @"C:\Test\Movies\Movie.Title.2024".AsOsAgnostic()) + .Build(); + } + + [Test] + public void should_return_null_if_filename_is_not_handled() + { + var path = Path.Combine(_movie.Path, "file.jpg"); + + Subject.FindMetadataFile(_movie, path).Should().BeNull(); + } + + [TestCase(".jpg")] + public void should_return_null_if_not_valid_file_for_movie(string extension) + { + var path = Path.Combine(_movie.Path, "movie.title.2024" + extension); + + Subject.FindMetadataFile(_movie, path).Should().BeNull(); + } + + [Test] + public void should_not_return_metadata_if_image_file_is_a_thumb() + { + var path = Path.Combine(_movie.Path, "movie.title.2024-thumb.jpg"); + + Subject.FindMetadataFile(_movie, path).Should().BeNull(); + } + + [TestCase("poster.jpg")] + [TestCase("background.jpg")] + public void should_return_movie_image_for_images_in_movie_folder(string filename) + { + var path = Path.Combine(_movie.Path, filename); + + Subject.FindMetadataFile(_movie, path).Type.Should().Be(MetadataType.MovieImage); + } + } +} diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs new file mode 100644 index 0000000000..5749d45292 --- /dev/null +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs @@ -0,0 +1,86 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using NzbDrone.Common.Extensions; +using NzbDrone.Core.Extras.Metadata.Files; +using NzbDrone.Core.MediaCover; +using NzbDrone.Core.MediaFiles; +using NzbDrone.Core.Movies; + +namespace NzbDrone.Core.Extras.Metadata.Consumers.Kometa +{ + public class KometaMetadata : MetadataBase + { + private static readonly Regex MovieImagesRegex = new (@"^(?:poster|background)\.(?:png|jpe?g)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private readonly IMapCoversToLocal _mediaCoverService; + + public override string Name => "Kometa"; + + public KometaMetadata(IMapCoversToLocal mediaCoverService) + { + _mediaCoverService = mediaCoverService; + } + + public override MetadataFile FindMetadataFile(Movie movie, string path) + { + var filename = Path.GetFileName(path); + + if (filename == null) + { + return null; + } + + var metadata = new MetadataFile + { + MovieId = movie.Id, + Consumer = GetType().Name, + RelativePath = movie.Path.GetRelativePath(path) + }; + + if (MovieImagesRegex.IsMatch(filename)) + { + metadata.Type = MetadataType.MovieImage; + return metadata; + } + + return null; + } + + public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFile) + { + return null; + } + + public override List MovieImages(Movie movie) + { + if (!Settings.MovieImages) + { + return new List(); + } + + return ProcessMovieImages(movie).ToList(); + } + + private IEnumerable ProcessMovieImages(Movie movie) + { + foreach (var image in movie.MovieMetadata.Value.Images.Where(i => i.CoverType is MediaCoverTypes.Poster or MediaCoverTypes.Fanart)) + { + var source = _mediaCoverService.GetCoverPath(movie.Id, image.CoverType); + + var filename = image.CoverType switch + { + MediaCoverTypes.Poster => "poster", + MediaCoverTypes.Fanart => "background", + _ => throw new ArgumentOutOfRangeException($"{image.CoverType} is not supported") + }; + + var destination = filename + Path.GetExtension(source); + + yield return new ImageFileResult(destination, source); + } + } + } +} diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs new file mode 100644 index 0000000000..6eae8c23a7 --- /dev/null +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs @@ -0,0 +1,29 @@ +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.ThingiProvider; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.Extras.Metadata.Consumers.Kometa +{ + public class KometaSettingsValidator : AbstractValidator + { + } + + public class KometaMetadataSettings : IProviderConfig + { + private static readonly KometaSettingsValidator Validator = new (); + + public KometaMetadataSettings() + { + MovieImages = true; + } + + [FieldDefinition(0, Label = "MetadataSettingsMovieImages", Type = FieldType.Checkbox, Section = MetadataSectionType.Image, HelpText = "poster.jpg, background.jpg")] + public bool MovieImages { get; set; } + + public NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +} From 0ef6e56e5d0a69f2a9248b71a5100e7edf2c49df Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 7 Nov 2024 15:02:36 +0000 Subject: [PATCH 080/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Anonymous Co-authored-by: Ardenet <1213193613@qq.com> Co-authored-by: Fixer Co-authored-by: Lizandra Candido da Silva Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/lv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 4 +- src/NzbDrone.Core/Localization/Core/bg.json | 4 +- src/NzbDrone.Core/Localization/Core/ca.json | 5 +- src/NzbDrone.Core/Localization/Core/cs.json | 5 +- src/NzbDrone.Core/Localization/Core/da.json | 6 +- src/NzbDrone.Core/Localization/Core/de.json | 5 +- src/NzbDrone.Core/Localization/Core/el.json | 4 +- src/NzbDrone.Core/Localization/Core/es.json | 12 +- src/NzbDrone.Core/Localization/Core/fi.json | 5 +- src/NzbDrone.Core/Localization/Core/fr.json | 5 +- src/NzbDrone.Core/Localization/Core/he.json | 4 +- src/NzbDrone.Core/Localization/Core/hi.json | 4 +- src/NzbDrone.Core/Localization/Core/hr.json | 4 +- src/NzbDrone.Core/Localization/Core/hu.json | 5 +- src/NzbDrone.Core/Localization/Core/is.json | 4 +- src/NzbDrone.Core/Localization/Core/it.json | 5 +- src/NzbDrone.Core/Localization/Core/ja.json | 6 +- src/NzbDrone.Core/Localization/Core/ko.json | 10 +- src/NzbDrone.Core/Localization/Core/lv.json | 3 +- .../Localization/Core/nb_NO.json | 3 +- src/NzbDrone.Core/Localization/Core/nl.json | 5 +- src/NzbDrone.Core/Localization/Core/pl.json | 4 +- src/NzbDrone.Core/Localization/Core/pt.json | 5 +- .../Localization/Core/pt_BR.json | 574 +++++++++--------- src/NzbDrone.Core/Localization/Core/ro.json | 13 +- src/NzbDrone.Core/Localization/Core/ru.json | 5 +- src/NzbDrone.Core/Localization/Core/sk.json | 3 +- src/NzbDrone.Core/Localization/Core/sv.json | 5 +- src/NzbDrone.Core/Localization/Core/th.json | 4 +- src/NzbDrone.Core/Localization/Core/tr.json | 4 +- src/NzbDrone.Core/Localization/Core/uk.json | 5 +- src/NzbDrone.Core/Localization/Core/vi.json | 5 +- .../Localization/Core/zh_CN.json | 8 +- .../Localization/Core/zh_TW.json | 4 +- 34 files changed, 425 insertions(+), 322 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 095204085d..472d980c34 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1074,5 +1074,7 @@ "FolderNameTokens": "رموز اسم الملف", "EditReleaseProfile": "تحرير ملف تعريف التأخير", "Clone": "قريب", - "AllTitles": "كل الملفات" + "AllTitles": "كل الملفات", + "AddReleaseProfile": "تحرير ملف تعريف التأخير", + "DownloadClientUnavailable": "عميل التنزيل غير متوفر" } diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 398d9eae7f..96b3df42c3 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1071,5 +1071,7 @@ "FolderNameTokens": "Токени за име на файл", "EditReleaseProfile": "Редактиране на профил за забавяне", "Clone": "Близо", - "AllTitles": "Всички файлове" + "AllTitles": "Всички файлове", + "AddReleaseProfile": "Редактиране на профил за забавяне", + "DownloadClientUnavailable": "Клиентът за изтегляне не е наличен" } diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 35af218e2e..48063bd17d 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1384,5 +1384,8 @@ "ShowDigitalReleaseHelpText": "Mostra la data de llançament sota el cartell", "Logout": "Tanca la sessió", "FolderNameTokens": "Testimonis de nom de fitxer", - "DefaultNotFoundMessage": "Deu estar perdut, no hi ha res a veure aquí." + "DefaultNotFoundMessage": "Deu estar perdut, no hi ha res a veure aquí.", + "Completed": "Completat", + "Delay": "Retard", + "DownloadClientUnavailable": "El client de descàrrega no està disponible" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index ce2f9bfcb8..801aaed2d4 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1200,5 +1200,8 @@ "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Několik kořenových adresářů chybí pro seznamy importu: {rootFoldersInfo}", "FolderNameTokens": "Tokeny názvů souborů", "Letterboxd": "Letterboxd", - "DefaultNotFoundMessage": "Asi jsi se ztratil, není tu nic k vidění." + "DefaultNotFoundMessage": "Asi jsi se ztratil, není tu nic k vidění.", + "Completed": "Dokončit", + "Delay": "Zpoždění", + "DownloadClientUnavailable": "Stahovací klient není k dispozici" } diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index d35f04276c..d41b69f2d0 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1091,5 +1091,9 @@ "ShowDigitalReleaseHelpText": "Vis udgivelsesdato under plakat", "ShowPhysicalRelease": "Fysisk udgivelsesdato", "FolderNameTokens": "Filnavn tokens", - "Clone": "Luk" + "Clone": "Luk", + "Delay": "Forsinkelse", + "EditReleaseProfile": "Rediger forsinkelsesprofil", + "DownloadClientUnavailable": "Downloadklienten er ikke tilgængelig", + "AddReleaseProfile": "Rediger forsinkelsesprofil" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 93899f74f5..603e2893c5 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1468,5 +1468,8 @@ "DefaultNotFoundMessage": "Sie müssen verloren sein, hier gibt es nichts zu sehen.", "ToggleMonitoredToUnmonitored": "Überwacht, klicken Sie, um die Überwachung aufzuheben", "ToggleUnmonitoredToMonitored": "Nicht überwacht, klicke zum Überwachen", - "DownloadIgnored": "Importiere herunterladen" + "DownloadIgnored": "Importiere herunterladen", + "Completed": "Vollständig", + "Delay": "Verzögerung", + "DownloadClientUnavailable": "Downloader ist nicht verfügbar" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 8f481fab83..f511e83139 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1232,5 +1232,7 @@ "SmartReplaceHint": "Παύλα ή Κενό-Παύλα ανάλογα με το όνομα", "FolderNameTokens": "Διακριτικά ονόματος αρχείου", "DownloadIgnored": "Λήψη Εισήχθη", - "AllTitles": "Ολα τα αρχεία" + "AllTitles": "Ολα τα αρχεία", + "Completed": "Ολοκληρώθηκαν", + "DownloadClientUnavailable": "Ο πελάτης λήψης δεν είναι διαθέσιμος" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 8c75fdb1c7..3d77bd57d0 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -282,7 +282,7 @@ "SelectFolder": "Seleccionar carpeta", "SearchOnAdd": "Buscar al Añadir", "SearchMovie": "Buscar Película", - "RecentFolders": "Carpetas Recientes", + "RecentFolders": "Carpetas recientes", "QuickImport": "Mover Automáticamente", "PosterSize": "Tamaño de póster", "Posters": "Pósteres", @@ -1854,5 +1854,13 @@ "MetadataSettingsMovieMetadataNfo": "Usar película.nfo", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluye las URLs de TMDb e IMDb de la película en el .nfo", "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Escribe los metadatos en película.nfo en lugar de al archivo .nfo predeterminado", - "FileBrowser": "Explorador de archivos" + "FileBrowser": "Explorador de archivos", + "ManageFormats": "Gestionar formatos", + "Completed": "Completados", + "Delay": "Retardo", + "FavoriteFolderAdd": "Añadir carpeta favorita", + "FavoriteFolders": "Carpetas favoritas", + "Warning": "Aviso", + "FavoriteFolderRemove": "Eliminar carpeta favorita", + "DownloadClientUnavailable": "Cliente de descarga no disponible" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 0a891bba4f..017924ae48 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1761,5 +1761,8 @@ "DefaultNotFoundMessage": "Lienet eksyksissä, koska täällä ei ole mitään nähtävää.", "ToggleMonitoredToUnmonitored": "Valvotaan (lopeta painamalla)", "ToggleUnmonitoredToMonitored": "Ei valvota (aloita painamalla)", - "FileBrowser": "Tiedostoselain" + "FileBrowser": "Tiedostoselain", + "Completed": "Kokonaiset", + "Delay": "Viive", + "DownloadClientUnavailable": "Lataustyökalu ei ole käytettävissä" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index e4ac88e5fb..f64685b827 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1843,5 +1843,8 @@ "MetadataSettingsMovieMetadataUrl": "Lien des métadonnées du film", "InCinemasMovieAvailabilityDescription": "Les films sont considérés comme disponibles dès leur sortie en salles.", "Disposition": "Disposition", - "FileBrowser": "Explorateur de fichiers" + "FileBrowser": "Explorateur de fichiers", + "Completed": "Terminé", + "Delay": "Délai", + "DownloadClientUnavailable": "Le client de téléchargement n'est pas disponible" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 154f0dfa21..62dfe3bfe3 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1116,5 +1116,7 @@ "FolderNameTokens": "אסימונים לשם קובץ", "AllTitles": "כל הקבצים", "Clone": "סגור", - "EditReleaseProfile": "ערוך פרופיל עיכוב" + "EditReleaseProfile": "ערוך פרופיל עיכוב", + "AddReleaseProfile": "ערוך פרופיל עיכוב", + "DownloadClientUnavailable": "לקוח ההורדות אינו זמין" } diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 5038d36998..0630a4b99d 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1069,5 +1069,7 @@ "FolderNameTokens": "फ़ाइल नाम टोकन", "Clone": "बंद करे", "AllTitles": "सारे दस्तावेज", - "EditReleaseProfile": "देरी प्रोफ़ाइल संपादित करें" + "EditReleaseProfile": "देरी प्रोफ़ाइल संपादित करें", + "DownloadClientUnavailable": "डाउनलोड क्लाइंट अनुपलब्ध है", + "AddReleaseProfile": "देरी प्रोफ़ाइल संपादित करें" } diff --git a/src/NzbDrone.Core/Localization/Core/hr.json b/src/NzbDrone.Core/Localization/Core/hr.json index 0dca473e23..0fc4edde8e 100644 --- a/src/NzbDrone.Core/Localization/Core/hr.json +++ b/src/NzbDrone.Core/Localization/Core/hr.json @@ -364,5 +364,7 @@ "EditConditionImplementation": "Dodaj Vezu - {implementationName}", "DownloadFailed": "Ponovno preuzimanje neuspješno", "Clone": "Zatvori", - "Reason": "Sezona" + "Reason": "Sezona", + "Delay": "Odgoda", + "DeleteSelectedMovieFilesHelpText": "Jeste li sigurni da želite obrisati ovaj profil odgode?" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 6097a68e9a..77eca052be 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1445,5 +1445,8 @@ "DefaultNotFoundMessage": "Biztosan eltévedtél, nincs itt semmi látnivaló.", "ToggleMonitoredToUnmonitored": "Felügyelt, kattintson a figyelés megszüntetéséhez", "ToggleUnmonitoredToMonitored": "Nem figyelt, kattintson a figyeléshez", - "FileBrowser": "Fájl Böngésző" + "FileBrowser": "Fájl Böngésző", + "Completed": "Teljes", + "Delay": "Késleltetés", + "DownloadClientUnavailable": "Letöltőkliens nem elérhető" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index ea3cc90025..e91be34650 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1071,5 +1071,7 @@ "FolderNameTokens": "Auðkenni skráarheita", "Clone": "Lokaðu", "EditReleaseProfile": "Breyta seinkunarprófíl", - "AllTitles": "Allar skrár" + "AllTitles": "Allar skrár", + "AddReleaseProfile": "Breyta seinkunarprófíl", + "DownloadClientUnavailable": "Niðurhalsþjónn er ekki tiltækur" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index fd90acdcc8..afd9005429 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1469,5 +1469,8 @@ "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Diverse cartelle principale sono perse per l’importazione: {rootFoldersInfo}", "ShowTraktRatingPosterHelpText": "Mostra valutazione Tomato sotta la locandina", "FolderNameTokens": "Token nome file", - "DefaultNotFoundMessage": "Ti devi essere perso, non c'è nulla da vedere qui." + "DefaultNotFoundMessage": "Ti devi essere perso, non c'è nulla da vedere qui.", + "Completed": "Completo", + "Delay": "Ritardo", + "DownloadClientUnavailable": "Il client di download non è disponibile" } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 5dc3a3d467..ffaef99690 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1069,5 +1069,9 @@ "ShowPhysicalReleaseHelpText": "ポスターの下にリリース日を表示する", "ShowDigitalReleaseHelpText": "ポスターの下にリリース日を表示する", "FolderNameTokens": "ファイル名トークン", - "Clone": "閉じる" + "Clone": "閉じる", + "AllTitles": "すべてのファイル", + "EditReleaseProfile": "遅延プロファイルの編集", + "DownloadClientUnavailable": "ダウンロードクライアントは利用できません", + "AddReleaseProfile": "遅延プロファイルの編集" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index f7fce91639..5c0809ab34 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1065,5 +1065,13 @@ "AddDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", "ApiKeyValidationHealthCheckMessage": "API 키를 {length}자 이상으로 업데이트하세요. 설정 또는 구성 파일을 통해 이 작업을 수행할 수 있습니다.", "AppUpdatedVersion": "{appName}이 버전 `{version}`으로 업데이트되었습니다. 최신 변경 사항을 받으려면 {appName}을 다시 로드해야 합니다", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "해시에 의해 토렌트가 차단된 경우 일부 인덱서의 RSS/검색 중에 토렌트가 제대로 거부되지 않을 수 있습니다. 이 기능을 활성화하면 토렌트를 가져온 후 클라이언트로 전송하기 전에 토렌트를 거부할 수 있습니다." + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "해시에 의해 토렌트가 차단된 경우 일부 인덱서의 RSS/검색 중에 토렌트가 제대로 거부되지 않을 수 있습니다. 이 기능을 활성화하면 토렌트를 가져온 후 클라이언트로 전송하기 전에 토렌트를 거부할 수 있습니다.", + "EditIndexerImplementation": "인덱서 추가 - {implementationName}", + "AddReleaseProfile": "지연 프로필 편집", + "IndexerSettingsRejectBlocklistedTorrentHashes": "동기화 중 차단 목록에 있는 토렌트 해시 거부", + "DownloadClientUnavailable": "다운로드 클라이언트를 사용할 수 없습니다.", + "EditConditionImplementation": "연결 추가 - {implementationName}", + "EditConnectionImplementation": "애플리케이션 추가 - {implementationName}", + "EditDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", + "AddConditionImplementation": "연결 추가 - {implementationName}" } diff --git a/src/NzbDrone.Core/Localization/Core/lv.json b/src/NzbDrone.Core/Localization/Core/lv.json index af7943e7ed..7cd371d5df 100644 --- a/src/NzbDrone.Core/Localization/Core/lv.json +++ b/src/NzbDrone.Core/Localization/Core/lv.json @@ -23,5 +23,6 @@ "EditConditionImplementation": "Pievienot Nosacījumu - {implementationName}", "ExportCustomFormat": "Pievienot Pielāgotu Formātu", "New": "Jauns", - "EditReleaseProfile": "Pievienot Aizkaves Profilu" + "EditReleaseProfile": "Pievienot Aizkaves Profilu", + "AddReleaseProfile": "Pievienot Aizkaves Profilu" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index 860a153ad4..87191e8ad7 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -319,5 +319,6 @@ "Discord": "Discord", "TMDb": "TMDb", "Clone": "Lukk", - "Reason": "Sesong" + "Reason": "Sesong", + "Delay": "Utsett" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 2a82a2bd1f..69220fb649 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1237,5 +1237,8 @@ "ShowPhysicalReleaseHelpText": "Laat releasedatum zien onder poster", "FolderNameTokens": "Bestandsnaam Tokens", "CountVotes": "{votes} Stemmen", - "AnnouncedMovieAvailabilityDescription": "Films worden als beschikbaar getoond zodra deze zijn toegevoegd aan {appName}." + "AnnouncedMovieAvailabilityDescription": "Films worden als beschikbaar getoond zodra deze zijn toegevoegd aan {appName}.", + "Completed": "Compleet", + "Delay": "Uitstel", + "DownloadClientUnavailable": "Downloader is onbeschikbaar" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 874dcfe00a..a004690d37 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1185,5 +1185,7 @@ "ShowPhysicalReleaseHelpText": "Pokaż datę premiery pod plakatem", "YesterdayAt": "Wczoraj o {time}", "FolderNameTokens": "Tokeny nazw plików", - "Clone": "Zamknij" + "Clone": "Zamknij", + "Delay": "Opóźnienie", + "DownloadClientUnavailable": "Klient pobierania jest niedostępny" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index af10c3a66a..487496da1a 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1263,5 +1263,8 @@ "CountCustomFormatsSelected": "{count} formatos selecionados", "BlackholeFolderHelpText": "Pasta em que {appName} guardará o ficheiro {extension}.", "AnnouncedMovieAvailabilityDescription": "Filmes estão disponíveis assim que forem adicionados a {appName}.", - "CountVotes": "{votes} votos" + "CountVotes": "{votes} votos", + "Completed": "Completo", + "Delay": "Atraso", + "DownloadClientUnavailable": "O cliente de transferências está indisponível" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index d5488d357d..806cf80cec 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1,16 +1,16 @@ { - "LastExecution": "Última Execução", + "LastExecution": "Última execução", "Large": "Grande", "Languages": "Idiomas", - "LanguageHelpText": "Idioma das versões", + "LanguageHelpText": "Idioma para lançamentos", "Language": "Idioma", - "KeyboardShortcuts": "Atalhos do Teclado", + "KeyboardShortcuts": "Atalhos do teclado", "KeepAndUnmonitorMovie": "Manter e não monitorar filme", "InvalidFormat": "Formato inválido", "Interval": "Intervalo", "InteractiveSearch": "Pesquisa interativa", "InteractiveImport": "Importação interativa", - "InstallLatest": "Instalar mais recente", + "InstallLatest": "Instalar o mais recente", "Info": "Informações", "IndexerStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas: {indexerNames}", "IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas", @@ -18,18 +18,18 @@ "IndexerSettings": "Configurações do indexador", "IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa Interativa habilitada, {appName} não fornecerá resultados para pesquisas interativas", "IndexerSearchCheckNoAvailableIndexersMessage": "Todos os indexadores com capacidade de pesquisa estão temporariamente indisponíveis devido a erros recentes do indexador", - "IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa Automática habilitada, {appName} não fornecerá nenhum resultado de pesquisa automática", + "IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa automática habilitada, o {appName} não fornecerá nenhum resultado de pesquisa automática", "Indexers": "Indexadores", - "IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com a sincronização RSS habilitada, {appName} não capturará novos lançamentos automaticamente", - "IndexerRssHealthCheckNoAvailableIndexers": "Todos os indexadores compatíveis com rss estão temporariamente indisponíveis devido a erros recentes do indexador", - "IndexerPriorityHelpText": "Prioridade do indexador de 1 (mais alta) a 50 (mais baixa). Padrão: 25. Usado ao capturar lançamentos como desempate para lançamentos iguais, {appName} ainda usará todos os indexadores habilitados para sincronização e pesquisa de RSS", + "IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com a sincronização RSS habilitada, o {appName} não capturará novos lançamentos automaticamente", + "IndexerRssHealthCheckNoAvailableIndexers": "Todos os indexadores compatíveis com RSS estão temporariamente indisponíveis devido a erros recentes do indexador", + "IndexerPriorityHelpText": "Prioridade do indexador de 1 (mais alta) a 50 (mais baixa). Padrão: 25. Usado como um desempate ao capturar lançamentos, o {appName} ainda usará todos os indexadores habilitados para a sincronização RSS e pesquisa", "IndexerPriority": "Prioridade do indexador", "IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {indexerNames}", "IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas", - "IndexerFlags": "Sinalizadores do Indexador", + "IndexerFlags": "Sinalizadores do indexador", "Indexer": "Indexador", "IncludeUnmonitored": "Incluir não monitorados", - "IncludeRecommendationsHelpText": "Incluir filmes recomendados pelo {appName} na exibição de descoberta", + "IncludeRecommendationsHelpText": "Incluir filmes recomendados pelo {appName} na exibição Descobrir", "IncludeRadarrRecommendations": "Incluir recomendações do {appName}", "IncludeCustomFormatWhenRenamingHelpText": "Incluir no formato de renomeação {Custom Formats}", "IncludeCustomFormatWhenRenaming": "Incluir formato personalizado ao renomear", @@ -39,14 +39,14 @@ "ImportTipsMessage": "Algumas dicas para garantir que a importação ocorra sem problemas:", "ImportRootPath": "Aponte o {appName} para a pasta que contém todos os seus filmes, não um específico. Por exemplo: {0}, e não {1}. Além disso, cada filme deve estar contido em sua própria pasta dentro da pasta raiz/biblioteca.", "ImportMovies": "Importar filmes", - "ImportMechanismHealthCheckMessage": "Habilitar Gerenciamento de Download Concluído", + "ImportMechanismHealthCheckMessage": "Habilitar gerenciamento de download concluído", "ImportListStatusCheckSingleClientMessage": "Listas indisponíveis devido a falhas: {importListNames}", "ImportListStatusCheckAllClientMessage": "Todas as listas estão indisponíveis devido a falhas", "Importing": "Importando", "ImportIncludeQuality": "Certifique-se de que seus arquivos incluam a qualidade em seus nomes. Por exemplo: {0}", "ImportHeader": "Importar uma biblioteca organizada existente para adicionar filmes ao {appName}", "ImportFailed": "Falha na importação: {sourceTitle}", - "ImportExtraFilesMovieHelpText": "Importe arquivos extras correspondentes (legendas, nfo, etc.) após importar um arquivo de filme", + "ImportExtraFilesMovieHelpText": "Importe arquivos adicionais correspondentes (legendas, nfo, etc.) após importar um arquivo de filme", "ImportExtraFiles": "Importar arquivos adicionais", "ImportExistingMovies": "Importar filmes existentes", "ImportErrors": "Erros de importação", @@ -64,7 +64,7 @@ "Ignored": "Ignorado", "IconForCutoffUnmet": "Ícone para limite não atendido", "ICalLink": "Link do iCal", - "ICalFeedHelpText": "Copie este URL em seu(s) cliente(s) ou clique para se inscrever se o seu navegador é compatível com webcal", + "ICalFeedHelpText": "Copie este URL para seu(s) cliente(s) ou clique para se inscrever se seu navegador for compatível com webcal", "ICalFeed": "Feed do iCal", "HttpHttps": "HTTP(S)", "Hours": "Horas", @@ -75,13 +75,13 @@ "HideAdvanced": "Ocultar opções avançadas", "HiddenClickToShow": "Oculto, clique para mostrar", "NoIssuesWithYourConfiguration": "Nenhum problema com sua configuração", - "Health": "Saúde", + "Health": "Integridade", "HaveNotAddedMovies": "Você ainda não adicionou nenhum filme, deseja importar alguns ou todos os seus filmes primeiro?", "HardlinkCopyFiles": "Criar hardlink/Copiar arquivos", "Group": "Grupo", - "GrabSelected": "Baixar Selecionado", + "GrabSelected": "Baixar selecionado", "GrabReleaseMessageText": "O {appName} não conseguiu determinar para qual filme é este lançamento. O {appName} pode não conseguir importar automaticamente este lançamento. Deseja obter \"{0}\"?", - "GrabRelease": "Baixar Lançamento", + "GrabRelease": "Baixar lançamento", "Grabbed": "Obtido", "Grab": "Obter", "GoToInterp": "Ir para {0}", @@ -90,15 +90,15 @@ "GeneralSettingsSummary": "Porta, SSL, nome de usuário/senha, proxy, análises e atualizações", "GeneralSettings": "Configurações gerais", "General": "Geral", - "FreeSpace": "Espaço Livre", + "FreeSpace": "Espaço livre", "SupportedIndexersMoreInfo": "Para saber mais sobre cada indexador, clique nos botões de informações.", "SupportedListsMoreInfo": "Para saber mais sobre cada lista de importação, clique nos botões de informação.", - "SupportedDownloadClientsMoreInfo": "Para obter mais informações sobre os clientes de download individuais, clique nos botões de mais informações.", + "SupportedDownloadClientsMoreInfo": "Para saber mais sobre os clientes de download individuais, clique nos botões Mais informações.", "Formats": "Formatos", "Forecast": "Previsão", "FollowPerson": "Seguir pessoa", "Folders": "Pastas", - "FolderMoveRenameWarning": "Isso também renomeará a pasta do filme de acordo com o formato para pastas de filmes nas configurações.", + "FolderMoveRenameWarning": "Isso também renomeará a pasta do filme de acordo com o formato para pastas de filmes nas Configurações.", "Folder": "Pasta", "FocusSearchBox": "Selecionar a caixa de pesquisa", "Fixed": "Corrigido", @@ -121,7 +121,7 @@ "ExternalUpdater": "O {appName} está configurado para usar um mecanismo de atualização externo", "Extension": "Extensão", "ExportCustomFormat": "Exportar formato personalizado", - "ExistingTag": "Tag existente", + "ExistingTag": "Etiqueta existente", "ExistingMovies": "Filme(s) existente(s)", "Existing": "Existente", "ExcludeTitle": "Excluir {0}? Isso impedirá que o {appName} adicione automaticamente por meio de sincronização de lista.", @@ -158,7 +158,7 @@ "EditPerson": "Editar pessoa", "EditMovieFile": "Editar arquivo do filme", "EditMovie": "Editar filme", - "EditImportListExclusion": "Editar exclusão de lista", + "EditImportListExclusion": "Editar exclusão de lista de importação", "Edition": "Edição", "EditGroups": "Editar grupos", "EditDelayProfile": "Editar perfil de atraso", @@ -166,7 +166,7 @@ "Edit": "Editar", "DownloadWarning": "Aviso de download: {warningMessage}", "DownloadPropersAndRepacksHelpTextWarning": "Usar formatos personalizados para atualizações automáticas para propers/repacks", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Use \"Não preferir\" para classificar por pontuação de formato personalizado em vez de propers/repacks", + "DownloadPropersAndRepacksHelpTextCustomFormat": "Use \"Não preferir\" para classificar pela pontuação do formato personalizado em propers/repacks", "DownloadPropersAndRepacksHelpText": "Se deve ou não atualizar automaticamente para propers/repacks", "DownloadPropersAndRepacks": "Propers e repacks", "Downloading": "Baixando", @@ -179,30 +179,30 @@ "DownloadClientsSettingsSummary": "Clientes de download, gerenciamento de download e mapeamentos de caminhos remotos", "DownloadClientSettings": "Configurações do cliente de download", "DownloadClients": "Clientes de download", - "DownloadClientCheckUnableToCommunicateMessage": "Não foi possível comunicar com {downloadClientName}. {errorMessage}", + "DownloadClientCheckUnableToCommunicateMessage": "Não é possível se comunicar com {downloadClientName}. {errorMessage}", "DownloadClientCheckNoneAvailableMessage": "Nenhum cliente de download está disponível", "DownloadClient": "Cliente de download", "DoNotUpgradeAutomatically": "Não atualizar automaticamente", "DoNotPrefer": "Não preferir", "DoneEditingGroups": "Concluir edição de grupos", "Donations": "Doações", - "DockerUpdater": "atualizar o contêiner do Docker para receber a atualização", + "DockerUpdater": "Atualize o contêiner do Docker para receber a atualização", "Docker": "Docker", "DiskSpace": "Espaço em disco", "Discover": "Descobrir", "Discord": "Discord", "Disabled": "Desabilitado", - "DigitalRelease": "Versão Digital", + "DigitalRelease": "Versão digital", "Details": "Detalhes", "DetailedProgressBarHelpText": "Mostrar texto na barra de progresso", "DetailedProgressBar": "Barra de progresso detalhada", "DestinationRelativePath": "Caminho de destino relativo", "DestinationPath": "Caminho de destino", "DeleteMovieFolderConfirmation": "A pasta do filme '{path}' e todo o seu conteúdo serão excluídos.", - "DeleteTagMessageText": "Tem certeza de que deseja excluir a tag '{label}'?", - "DeleteTag": "Excluir Etiqueta", + "DeleteTagMessageText": "Tem certeza de que deseja excluir a etiqueta '{label}'?", + "DeleteTag": "Excluir etiqueta", "DeleteSelectedMovieFiles": "Excluir arquivos do filme selecionado", - "DeleteSelectedMovie": "Excluir Filme Selecionado", + "DeleteSelectedMovie": "Excluir filme selecionado", "DeleteRestrictionHelpText": "Tem certeza de que deseja excluir esta restrição?", "DeleteRestriction": "Excluir restrição", "DeleteQualityProfile": "Excluir perfil de qualidade", @@ -226,7 +226,7 @@ "Deleted": "Excluído", "DeleteCustomFormat": "Excluir formato personalizado", "DeleteBackupMessageText": "Tem certeza de que deseja excluir o backup '{name}'?", - "DeleteBackup": "Excluir Backup", + "DeleteBackup": "Excluir backup", "Delete": "Excluir", "DelayProfiles": "Perfis de atraso", "DelayProfile": "Perfil de atraso", @@ -237,14 +237,14 @@ "Days": "Dias", "Day": "Dia", "Date": "Data", - "CutoffUnmet": "Corte Não Alcançado", + "CutoffUnmet": "Corte não atingido", "UpgradeUntilMovieHelpText": "Quando essa qualidade for atingida, o {appName} não fará mais o download de filmes depois que a pontuação de corte do formato personalizado for atingida ou excedida", "UpgradeUntilCustomFormatScoreMovieHelpText": "Uma vez que o corte de qualidade é atingido ou excedido e esta pontuação de formato personalizado é alcançada, o {appName} não irá mais capturar ou importar atualizações para esses filmes", "Cutoff": "Corte", - "CustomFormatUnknownConditionOption": "Opção desconhecida '{key}' para a condição '{implementation}'", - "CustomFormatUnknownCondition": "Condição de Formato Personalizado desconhecida '{implementation}'", - "CustomFormatsSettingsSummary": "Configurações e Formatos Personalizados", - "CustomFormatsSettings": "Configurações de Formatos Personalizados", + "CustomFormatUnknownConditionOption": "Opção '{key}' desconhecida para a condição '{implementation}'", + "CustomFormatUnknownCondition": "Condição de formato personalizado '{implementation}' desconhecida", + "CustomFormatsSettingsSummary": "Formatos personalizados e configurações", + "CustomFormatsSettings": "Configurações de formatos personalizados", "CustomFormatScore": "Pontuação do formato personalizado", "CustomFormats": "Formatos personalizados", "CustomFormatHelpText": "O {appName} pontua cada lançamento usando a soma das pontuações para formatos personalizados correspondentes. Se um novo lançamento tiver melhor pontuação, com a mesma qualidade ou melhor, o {appName} o obterá.", @@ -259,7 +259,7 @@ "CouldNotFindResults": "Não foi possível encontrar nenhum resultado para '{term}'", "CouldNotConnectSignalR": "Não é possível conectar ao SignalR, a interface não atualizará", "CopyUsingHardlinksHelpTextWarning": "Ocasionalmente, os bloqueios de arquivo podem impedir a renomeação de arquivos que estão sendo semeados. Você pode desabilitar temporariamente a semeadura e usar a função de renomeação do {appName} como uma solução alternativa.", - "CopyUsingHardlinksMovieHelpText": "Os hardlinks permitem que o {appName} importe torrents de propagação para a pasta do filme sem ocupar espaço adicional em disco ou copiar todo o conteúdo do arquivo. Hardlinks só funcionarão se a origem e o destino estiverem no mesmo volume", + "CopyUsingHardlinksMovieHelpText": "Os hardlinks permitem que o {appName} importe torrents que estão sendo semeados para a pasta do filme sem ocupar espaço adicional em disco ou copiar todo o conteúdo do arquivo. Hardlinks só funcionarão se a origem e o destino estiverem no mesmo volume", "CopyToClipboard": "Copiar para a área de transferência", "ConsideredAvailable": "Considerado disponível", "ConnectSettingsSummary": "Notificações, conexões com servidores/players de mídia e scripts personalizados", @@ -272,7 +272,7 @@ "Component": "Componente", "CompletedDownloadHandling": "Gerenciamento de downloads concluídos", "Columns": "Colunas", - "ColonReplacementFormatHelpText": "Alterar como o {appName} lida com a substituição de dois-pontos", + "ColonReplacementFormatHelpText": "Mude como o {appName} lida com a substituição do dois-pontos", "ColonReplacement": "Substituto para dois-pontos", "Collection": "Coleção", "CloseCurrentModal": "Fechar pop-up atual", @@ -285,39 +285,39 @@ "ClickToChangeMovie": "Clique para alterar o filme", "ClickToChangeLanguage": "Clique para alterar o idioma", "Clear": "Limpar", - "CleanLibraryLevel": "Limpar Nível da Biblioteca", - "ChownGroupHelpTextWarning": "Isso só funciona se o usuário que está executando o {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download use o mesmo grupo que o {appName}.", - "ChownGroupHelpText": "Nome ou ID do grupo. Use a ID para sistemas de arquivos remotos.", - "ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que executa {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.", + "CleanLibraryLevel": "Limpar nível da biblioteca", + "ChownGroupHelpTextWarning": "Isso só funciona se o usuário que executa o {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download use o mesmo grupo que o {appName}.", + "ChownGroupHelpText": "Nome do grupo ou gid. Use gid para sistemas de arquivos remotos.", + "ChmodFolderHelpTextWarning": "Isso só funciona se o usuário que executa o {appName} for o proprietário do arquivo. É melhor garantir que o cliente de download defina as permissões corretamente.", "ChmodFolderHelpText": "Octal, aplicado durante a importação/renomeação de pastas e arquivos de mídia (sem bits de execução)", - "ChmodFolder": "Fazer chmod de pasta", - "CheckForFinishedDownloadsInterval": "Verifique o intervalo de downloads concluídos", + "ChmodFolder": "Fazer chmod na pasta", + "CheckForFinishedDownloadsInterval": "Intervalo para verificar a conclusão de downloads", "CheckDownloadClientForDetails": "verifique o cliente de download para saber mais", - "ChangeHasNotBeenSavedYet": "Mudar o que não foi salvo ainda", + "ChangeHasNotBeenSavedYet": "A alteração ainda não foi salva", "ChangeFileDate": "Alterar data do arquivo", "CertValidationNoLocal": "Desabilitado para endereços locais", "CertificationCountryHelpText": "Selecione o país para as certificações de filmes", "CertificationCountry": "País da certificação", "Certification": "Certificação", - "CertificateValidationHelpText": "Altere a rigidez da validação da certificação HTTPS. Não mude a menos que você entenda os riscos.", + "CertificateValidationHelpText": "Alterar a rigidez da validação da certificação HTTPS. Não mude a menos que você entenda os riscos.", "CertificateValidation": "Validação de certificado", "Cast": "Elenco", "CantFindMovie": "Por que não consigo encontrar meu filme?", "CancelProcessing": "Cancelar processamento", - "CancelPendingTask": "Tem certeza de que deseja cancelar essa tarefa pendente?", + "CancelPendingTask": "Tem certeza de que deseja cancelar esta tarefa pendente?", "Cancel": "Cancelar", - "CalendarOptions": "Opções de Calendário", + "CalendarOptions": "Opções do calendário", "Calendar": "Calendário", "BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais", "BuiltIn": "Embutido", "BranchUpdateMechanism": "Ramificação usada pelo mecanismo externo de atualização", - "BranchUpdate": "Ramificação para atualização do {appName}", + "BranchUpdate": "Ramificação para atualizar o {appName}", "Branch": "Ramificação", "BindAddressHelpText": "Endereço IP válido, localhost ou '*' para todas as interfaces", - "BindAddress": "Fixar endereço", + "BindAddress": "Vincular endereço", "BeforeUpdate": "Antes da atualização", "Backups": "Backups", - "BackupRetentionHelpText": "Backups automáticos anteriores ao período de retenção serão limpos automaticamente", + "BackupRetentionHelpText": "Backups automáticos anteriores ao período de retenção serão excluídos automaticamente", "BackupNow": "Fazer backup agora", "BackupIntervalHelpText": "Intervalo entre backups automáticos", "BackupFolderHelpText": "Os caminhos relativos estarão no diretório AppData do {appName}", @@ -325,8 +325,8 @@ "AvailabilityDelayHelpText": "Quantidade de tempo antes ou depois da data de disponibilidade para pesquisar pelo filme", "AvailabilityDelay": "Atraso de disponibilidade", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmes excluídos do disco automaticamente deixam de ser monitorados no {appName}", - "AutoRedownloadFailedHelpText": "Procurar e tentar baixar automaticamente uma versão diferente", - "AutomaticSearch": "Pesquisa Automática", + "AutoRedownloadFailedHelpText": "Procurar e tentar baixar automaticamente um lançamento diferente", + "AutomaticSearch": "Pesquisa automática", "Automatic": "Automático", "AuthForm": "Formulário (página de login)", "AuthenticationMethodHelpText": "Exigir nome de usuário e senha para acessar o {appName}", @@ -334,15 +334,15 @@ "AuthBasic": "Básico (pop-up do navegador)", "AudioInfo": "Informações do áudio", "ICalShowAsAllDayEventsHelpText": "Os eventos aparecerão como eventos de dia inteiro em seu calendário", - "AptUpdater": "Use o apt para instalar a atualização", - "ApplyTagsHelpTextHowToApplyMovies": "Como aplicar tags aos filmes selecionados", - "ApplyTags": "Aplicar Tags", + "AptUpdater": "Usar apt para instalar atualizações", + "ApplyTagsHelpTextHowToApplyMovies": "Como aplicar etiquetas aos filmes selecionados", + "ApplyTags": "Aplicar etiquetas", "Apply": "Aplicar", - "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na atualização", + "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData", "AppDataDirectory": "Diretório AppData", "ApiKey": "Chave da API", "Announced": "Anunciado", - "AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do {appName}. Isso inclui informações sobre seu navegador, quais páginas da interface Web do {appName} você usa, relatórios de erros, e a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.", + "AnalyticsEnabledHelpText": "Envie informações anônimas de uso e erro para os servidores do {appName}. Isso inclui informações sobre seu navegador, quais páginas da interface Web do {appName} você usa, relatórios de erros, a versão do sistema operacional e do tempo de execução. Usaremos essas informações para priorizar recursos e correções de bugs.", "AnalyseVideoFiles": "Analisar arquivos de vídeo", "Always": "Sempre", "AlternativeTitle": "Título alternativo", @@ -365,12 +365,12 @@ "MinimumLimits": "Limites mínimos", "MinimumFreeSpaceHelpText": "Impedir a importação se deixar menos do que esta quantidade de espaço em disco disponível", "MinimumFreeSpace": "Mínimo de espaço livre", - "MinimumCustomFormatScore": "Pontuação mínima de formato personalizado", - "MinimumAgeHelpText": "Somente Usenet: idade mínima, em minutos, dos NZBs antes de serem baixados. Use isso para dar aos novos lançamentos tempo para se propagar para seu provedor de Usenet.", - "MinimumAge": "Idade miníma", + "MinimumCustomFormatScore": "Pontuação mínima do formato personalizado", + "MinimumAgeHelpText": "Somente Usenet: idade mínima, em minutos, dos NZBs antes de serem obtidos. Use esta opção para dar aos novos lançamentos tempo para propagarem para seu provedor de Usenet.", + "MinimumAge": "Idade mínima", "MinimumAvailability": "Disponibilidade mínima", "MinimumCustomFormatScoreHelpText": "Pontuação mínima de formato personalizado permitida para download", - "MinAvailability": "Disponibilidade mínina", + "MinAvailability": "Disponibilidade mínima", "MetadataSettingsMovieSummary": "Criar arquivos de metadados ao importar ou atualizar filmes", "Metadata": "Metadados", "MetadataSettings": "Configurações de metadados", @@ -395,32 +395,32 @@ "ManualImportSelectLanguage": "Importação manual - Selecionar idioma", "ManualImport": "Importação manual", "Manual": "Manual", - "MaintenanceRelease": "Versão de manutenção: correções de bugs e outros aprimoramentos. Consulte o Histórico de Commit do Github para obter mais detalhes", - "Lowercase": "Minúscula", + "MaintenanceRelease": "Versão de manutenção: correções de bugs e outras melhorias. Consulte o Histórico de commit do Github para saber mais", + "Lowercase": "Minúsculas", "LookingForReleaseProfiles2": "em vez disso.", - "LookingForReleaseProfiles1": "Procurando pelos perfis de versões? Tente", - "Logs": "Registros", - "LogOnly": "Só Registro", - "LogLevelTraceHelpTextWarning": "O registro em log deve ser habilitado apenas temporariamente", - "LogLevel": "Nível de registro", - "LogFiles": "Arquivos de registro", + "LookingForReleaseProfiles1": "Procurando pelos perfis de lançamento? Tente", + "Logs": "Logs", + "LogOnly": "Só registro em log", + "LogLevelTraceHelpTextWarning": "O registro em log para rastreamento deve ser habilitado apenas temporariamente", + "LogLevel": "Nível de registro em log", + "LogFiles": "Arquivos de log", "Location": "Localização", "Local": "Local", "LoadingMovieFilesFailed": "Falha ao carregar arquivos do filme", "LoadingMovieExtraFilesFailed": "Falha ao carregar arquivos adicionais do filme", "LoadingMovieCreditsFailed": "Falha ao carregar os créditos do filme", - "ListTagsHelpText": "Os itens na lista de tags serão adicionados com", + "ListTagsHelpText": "Os itens na lista de etiquetas serão adicionados com", "ListSyncLevelHelpTextWarning": "Os arquivos de filme serão excluídos permanentemente, o que pode resultar na limpeza de sua biblioteca se suas listas estiverem vazias", - "ListSyncLevelHelpText": "Os filmes na biblioteca serão tratados com base na sua seleção se eles caírem ou não aparecerem na(s) sua(s) lista(s)", + "ListSyncLevelHelpText": "Os filmes na biblioteca serão tratados com base na sua seleção se saírem de sua(s) lista(s) ou não aparecerem nela(s)", "ImportListsSettingsSummary": "Importe de outra instância do {appName} ou listas do Trakt e gerencie exclusões de listas", - "ImportListSettings": "Configurações de listas", - "ImportLists": "Listas", - "ImportListExclusions": "Exclusões de lista", + "ImportListSettings": "Configurações de Importar listas", + "ImportLists": "Importar listas", + "ImportListExclusions": "Importar exclusões de lista", "Links": "Links", "LinkHere": "aqui", "Level": "Nível", - "LaunchBrowserHelpText": " Abrir o navegador Web e navegar até a página inicial do {appName} ao iniciar o aplicativo.", - "LastWriteTime": "Hora da Última Gravação", + "LaunchBrowserHelpText": " Abrir um navegador e navegar até a página inicial do {appName} ao iniciar o aplicativo.", + "LastWriteTime": "Hora da última gravação", "LastUsed": "Usado por último", "AllResultsHiddenFilter": "Todos os resultados estão ocultos pelo filtro aplicado", "AllowHardcodedSubsHelpText": "Baixaremos as legendas embutidas detectadas automaticamente", @@ -438,14 +438,14 @@ "AddRestriction": "Adicionar restrição", "AddRemotePathMapping": "Adicionar mapeamento de caminho remoto", "AddQualityProfile": "Adicionar perfil de qualidade", - "AddNewTmdbIdMessage": "Você também pode pesquisar usando a ID do TMDb de um filme. Por exemplo, \"tmdb:71663\"", + "AddNewTmdbIdMessage": "Você também pode pesquisar usando a ID do TMDb de um filme. P.ex., \"tmdb:71663\"", "AddNewMovie": "Adicionar novo filme", "AddNewMessage": "É fácil adicionar um novo filme, basta começar a digitar o nome do filme que deseja acrescentar", - "AddNew": "Adicionar Novo", + "AddNew": "Adicionar novo", "AddMovies": "Adicionar filmes", "AddMovie": "Adicionar filme", - "AddImportListExclusion": "Adicionar exclusão à lista", - "AddingTag": "Adicionar tag", + "AddImportListExclusion": "Adicionar exclusão à lista de importação", + "AddingTag": "Adicionar etiqueta", "AddIndexer": "Adicionar indexador", "AddListExclusionMovieHelpText": "Impedir a adição do filme ao {appName} por listas", "AddExclusion": "Adicionar exclusão", @@ -465,17 +465,17 @@ "MovieYear": "Ano do filme", "MovieTitleToExcludeHelpText": "O título do filme a excluir (pode ser qualquer coisa significativa)", "MovieTitle": "Título do filme", - "MoviesSelectedInterp": "{count} Filme(s) selecionado(s)", + "MoviesSelectedInterp": "{count} filme(s) selecionado(s)", "Movies": "Filmes", "MovieNaming": "Nomenclatura de filme", - "MovieIsUnmonitored": "Filme não monitorado", + "MovieIsUnmonitored": "O filme não está monitorado", "MovieIsRecommend": "Filme recomendado com base na adição recente", "MovieIsOnImportExclusionList": "O filme está na lista de exclusão de importação", "MovieIsMonitored": "O filme está monitorado", "MovieIsDownloading": "O filme está baixando", "MovieInvalidFormat": "Filme: formato inválido", "MovieInfoLanguageHelpTextWarning": "É necessário recarregar o navegador", - "MovieInfoLanguageHelpText": "Idioma que o {appName} usará para as informações do filme na interface do usuário", + "MovieInfoLanguageHelpText": "Idioma que o {appName} usará para as informações do filme na interface", "MovieInfoLanguage": "Idioma das informações do filme", "MovieIndexScrollTop": "Índice do filme: rolar para cima", "MovieIndexScrollBottom": "Índice do filme: rolar pra baixo", @@ -486,7 +486,7 @@ "MovieFiles": "Arquivos do filme", "MovieExcludedFromAutomaticAdd": "Filme excluído da adição automática", "MovieEditor": "Editor de filme", - "MovieDetailsPreviousMovie": "Detalhes do filme: Filme anterior", + "MovieDetailsPreviousMovie": "Detalhes do filme: filme anterior", "MovieDetailsNextMovie": "Detalhes do filme: próximo filme", "MovieChat": "Bate-papo sobre o filme", "MovieAlreadyExcluded": "Filme já excluído", @@ -494,7 +494,7 @@ "MoveFolders2": "Deseja mover os arquivos de filmes de \"{0}\" para \"{1}\"?", "MoveFolders1": "Deseja mover as pastas de filmes para \"{0}\"?", "MoveFiles": "Mover arquivos", - "MountMovieHealthCheckMessage": "A montagem que contém um caminho de filme é montada somente para leitura: ", + "MountMovieHealthCheckMessage": "O ponto de montagem que contém um caminho de filme é montado somente para leitura: ", "MoreInfo": "Mais informações", "MoreDetails": "Mais detalhes", "Months": "Meses", @@ -565,7 +565,7 @@ "AddIndexerError": "Não foi possível adicionar um novo indexador. Tente novamente.", "AddDownloadClientError": "Não foi possível adicionar um novo cliente de download. Tente novamente.", "AddCustomFormatError": "Não foi possível adicionar um novo formato personalizado. Tente novamente.", - "AddConditionError": "Não foi possível adicionar uma nova condição. Tente novamente.", + "AddConditionError": "Não foi possível adicionar uma nova condição, tente novamente.", "UiSettings": "Configurações da interface", "BrowserReloadRequired": "É necessário recarregar o navegador", "UiLanguage": "Idioma da interface", @@ -591,7 +591,7 @@ "Test": "Testar", "Tasks": "Tarefas", "TagsSettingsSummary": "Veja todas as etiquetas e como elas são usadas. Etiquetas não utilizadas podem ser removidas", - "ICalTagsMoviesHelpText": "Aplica-se a filmes com pelo menos uma tag correspondente", + "ICalTagsMoviesHelpText": "Aplica-se a filmes com pelo menos uma etiqueta correspondente", "Tags": "Tags", "TagIsNotUsedAndCanBeDeleted": "A tag não é usada e pode ser excluída", "TagDetails": "Detalhes da Tag - {label}", @@ -645,10 +645,10 @@ "ShowMonitored": "Mostrar monitorado(s)", "ShowGenres": "Mostrar gêneros", "ShowDateAdded": "Mostrar data de adição", - "IconForCutoffUnmetHelpText": "Mostrar ícone para arquivos quando o limite não foi atingindo", + "IconForCutoffUnmetHelpText": "Mostrar ícone para arquivos quando o limite não foi atingido", "ShowCertification": "Mostrar certificação", "ShowAdvanced": "Mostrar opções avançadas", - "ListMonitorMovieHelpText": "Os filmes ou coleções adicionados por esta lista devem ser adicionados como monitorados", + "ListMonitorMovieHelpText": "Se os filmes ou coleções adicionados por esta lista devem ser monitorados", "ShowRelativeDatesHelpText": "Mostrar datas absolutas ou relativas (Hoje, Ontem, etc.)", "ShowRelativeDates": "Mostrar datas relativas", "ShortDateFormat": "Formato curto da data", @@ -674,7 +674,7 @@ "Security": "Segurança", "Seconds": "Segundos", "SearchSelected": "Pesquisar selecionado(s)", - "ListSearchOnAddMovieHelpText": "Pesquise filmes nesta lista quando adicionados à biblioteca", + "ListSearchOnAddMovieHelpText": "Pesquisar os filmes desta lista quando adicionados à biblioteca", "SearchOnAdd": "Pesquisar ao adicionar", "SearchMovie": "Pesquisar filme", "SearchMissing": "Pesquisar ausentes", @@ -920,9 +920,9 @@ "MetadataLoadError": "Não foi possível carregar os metadados", "MediaManagementSettingsLoadError": "Não foi possível carregar as configurações de gerenciamento de mídia", "UnableToLoadManualImportItems": "Não foi possível carregar itens de importação manual", - "ImportListsLoadError": "Não foi possível carregar as listas", + "ImportListsLoadError": "Não foi possível carregar Importar listas", "ListOptionsLoadError": "Não foi possível carregar as opções da lista", - "ImportListExclusionsLoadError": "Não foi possível carregar as exclusões de lista", + "ImportListExclusionsLoadError": "Não foi possível carregar as exclusões da lista de importação", "IndexersLoadError": "Não foi possível carregar os indexadores", "IndexerOptionsLoadError": "Não foi possível carregar as opções do indexador", "GeneralSettingsLoadError": "Não foi possível carregar as configurações gerais", @@ -932,17 +932,17 @@ "AddRemotePathMappingError": "Não foi possível adicionar um novo mapeamento de caminho remoto. Tente novamente.", "AddQualityProfileError": "Não foi possível adicionar um novo perfil de qualidade. Tente novamente.", "AddListError": "Não foi possível adicionar uma nova lista. Tente novamente.", - "AddImportListExclusionError": "Não foi possível adicionar uma nova exclusão de lista. Tente novamente.", + "AddImportListExclusionError": "Não foi possível adicionar uma nova exclusão à lista. Tente novamente.", "UiSettingsSummary": "Opções de calendário, data e cores para daltônicos", "Trigger": "Acionador", "Trakt": "Trakt", "Trailer": "Trailer", "TorrentDelayTime": "Atraso do Torrent: {torrentDelay}", - "LastDuration": "Última Duração", + "LastDuration": "Última duração", "Trace": "Traço", - "ImportNotForDownloads": "Não use para importar downloads de seu cliente. Isso se aplica apenas a bibliotecas organizadas existentes, e não a arquivos desorganizados.", + "ImportNotForDownloads": "Não use para importar downloads de seu cliente. Isso aplica-se apenas a bibliotecas organizadas existentes, e não a arquivos desorganizados.", "ImportLibrary": "Importar biblioteca", - "DefaultCase": "Padrão Maiúscula ou Minúscula", + "DefaultCase": "Padrão maiúscula ou minúscula", "ChooseAnotherFolder": "Escolha outra pasta", "MIA": "Ausentes", "SqliteVersionCheckUpgradeRequiredMessage": "A versão {0} do SQLite instalada atualmente não é mais compatível. Atualize o SQLite para pelo menos a versão {1}.", @@ -954,7 +954,7 @@ "OnMovieDelete": "Ao Excluir Filme", "Reddit": "Reddit", "More": "Mais", - "Download": "Download", + "Download": "Baixar", "DownloadClientCheckDownloadingToRoot": "O cliente de download {downloadClientName} coloca os downloads na pasta raiz {path}. Você não deve baixar para uma pasta raiz.", "UpdateAvailableHealthCheckMessage": "Nova atualização está disponível: {version}", "RemotePathMappingCheckFilesGenericPermissions": "O cliente de download {downloadClientName} relatou arquivos em {path}, mas o {appName} não pode ver esse diretório. Pode ser necessário ajustar as permissões da pasta.", @@ -974,14 +974,14 @@ "RemotePathMappingCheckBadDockerPath": "Você está usando o docker; cliente de download {downloadClientName} coloca downloads em {path}, mas este não é um caminho {osName} válido. Revise seus mapeamentos de caminho remoto e baixe as configurações do cliente.", "ImportListMultipleMissingRoots": "Várias pastas raiz estão ausentes para listas de importação: {rootFoldersInfo}", "ImportListMissingRoot": "Pasta raiz ausente para lista(s) de importação: {rootFolderInfo}", - "BypassDelayIfHighestQualityHelpText": "Ignorar atraso quando o lançamento tiver a qualidade mais alta habilitada no perfil de qualidade com o protocolo preferido", + "BypassDelayIfHighestQualityHelpText": "Ignorar o atraso quando o lançamento tiver a qualidade mais alta habilitada no perfil de qualidade com o protocolo preferido", "BypassDelayIfHighestQuality": "Ignorar se a qualidade é mais alta", "From": "de", "Letterboxd": "Letterboxd", "TaskUserAgentTooltip": "User-Agent fornecido pelo aplicativo que chamou a API", "NotificationTriggersHelpText": "Selecione quais eventos devem acionar esta notificação", "Blocklisted": "Bloqueado", - "Blocklist": "Lista de Bloqueio", + "Blocklist": "Lista de bloqueio", "BlocklistRelease": "Lançamento na lista de bloqueio", "RemoveFromBlocklist": "Remover da lista de bloqueio", "BlocklistReleases": "Lançamentos na lista de bloqueio", @@ -992,10 +992,10 @@ "RemoveCompleted": "Remoção Concluída", "RemoveDownloadsAlert": "As configurações de remoção foram movidas para as configurações individuais do cliente de download na tabela acima.", "OnApplicationUpdate": "Na Atualização do Aplicativo", - "DiscordUrlInSlackNotification": "Você tem uma notificação do Discord configurado como uma notificação do Slack. Definir isso como uma notificação do Discord para melhor funcionalidade. Com efeito, notificações são: {0}", + "DiscordUrlInSlackNotification": "Você tem uma notificação do Discord configurada como uma notificação do Slack. Defina-a como uma notificação do Discord para que funcione melhor. As notificações afetadas são: {0}", "AnnouncedMovieDescription": "Filme foi anunciado", "IndexerDownloadClientHelpText": "Especifique qual cliente de download é usado para baixar deste indexador", - "ManualImportSetReleaseGroup": "Importar Manual - Definir Grupo de Lançamento", + "ManualImportSetReleaseGroup": "Importação manual - Definir grupo de lançamento", "SelectLanguages": "Selecione os Idiomas", "SelectReleaseGroup": "Selecionar um Grupo de Lançamento", "SetReleaseGroup": "Definir Grupo do Lançamento", @@ -1006,10 +1006,10 @@ "TmdbRating": "Avaliação no TMDb", "TmdbVotes": "Votos no TMDb", "ImdbVotes": "Votos no IMDb", - "IndexerJackettAll": "Indexadores usando o Jackett 'all' endpoint sem suporte: {indexerNames}", + "IndexerJackettAll": "Indexadores que usam o ponto de extremidade \"all\" incompatível do Jackett: {indexerNames}", "Auto": "Automático", "Duration": "Duração", - "ImportList": "Lista", + "ImportList": "Importar lista", "Never": "Nunca", "Rating": "Avaliação", "Started": "Iniciado", @@ -1021,17 +1021,17 @@ "RssSyncIntervalHelpText": "Intervalo em minutos. Defina como zero para desabilitar (isso interromperá todas as capturas de liberação automática)", "InstanceName": "Nome da instância", "InstanceNameHelpText": "Nome da instância na aba e para o nome do aplicativo Syslog", - "AllCollectionsHiddenDueToFilter": "Todos os filmes estão ocultos devido ao filtro aplicado.", + "AllCollectionsHiddenDueToFilter": "Todas as coleções estão ocultas devido ao filtro aplicado.", "Collections": "Coleções", - "MonitorMovies": "Monitorar Filmes", + "MonitorMovies": "Monitorar filmes", "NoCollections": "Nenhum filme encontrado. Para começar, adicione um novo filme ou importe alguns existentes", - "MovieOnly": "Somente Filme", + "MovieOnly": "Somente filme", "UnableToLoadCollections": "Não foi possível carregar as coleções", "ChooseImportMode": "Escolha o modo de importação", "CountCollectionsSelected": "{count} Coleção(ões) Selecionadas", - "EditCollection": "Editar Coleção", - "MonitorCollection": "Monitorar Coleção", - "MovieAndCollection": "Filme e Coleção", + "EditCollection": "Editar coleção", + "MonitorCollection": "Monitorar coleção", + "MovieAndCollection": "Filme e coleção", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Pasta raiz ausente para a coleção de filmes: {rootFolderInfo}", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Estão faltando várias pastas raízes para coleções de filmes: {rootFoldersInfo}", "ShowCollectionDetails": "Mostrar Estado da Coleção", @@ -1042,7 +1042,7 @@ "ScrollMovies": "Rolar Filmes", "OnMovieAdded": "Ao Adicionar Filme", "ShowPosters": "Mostrar pôsteres", - "CollectionOptions": "Opções de Coleção", + "CollectionOptions": "Opções de coleção", "CollectionShowDetailsHelpText": "Mostrar estado e propriedades da coleção", "CollectionShowOverviewsHelpText": "Mostrar visão geral da coleção", "CollectionShowPostersHelpText": "Mostrar pôsteres de itens da coleção", @@ -1056,15 +1056,15 @@ "ResetQualityDefinitions": "Redefinir definições de qualidade", "ResetTitles": "Redefinir títulos", "Theme": "Tema", - "EnableRssHelpText": "Será usado quando o {appName} procurar periodicamente lançamentos via RSS Sync", - "DownloadClientSortingCheckMessage": "O cliente de download {downloadClientName} tem classificação {sortingMode} habilitada para a categoria do {appName}. Você deve desativar a classificação em seu cliente de download para evitar problemas de importação.", + "EnableRssHelpText": "Será usado quando o {appName} procurar periodicamente por lançamentos via RSS Sync", + "DownloadClientSortingCheckMessage": "O cliente de download {downloadClientName} tem a classificação {sortingMode} habilitada para a categoria do {appName}. Você deve desativar essa classificação em seu cliente de download para evitar problemas de importação.", "File": "Arquivo", "StopSelecting": "Parar Seleção", "UpdateFiltered": "Atualização Filtrada", - "EditMovies": "Editar Filmes", - "EditSelectedMovies": "Editar Filmes Selecionados", + "EditMovies": "Editar filmes", + "EditSelectedMovies": "Editar filmes selecionados", "RecycleBinUnableToWriteHealthCheck": "Não é possível gravar na pasta da lixeira configurada: {path}. Certifique-se de que este caminho exista e seja gravável pelo usuário executando o {appName}", - "MovieMatchType": "Tipo de Filme Correspondente", + "MovieMatchType": "Tipo de filme correspondente", "Loading": "Carregando", "ThereWasAnErrorLoadingThisItem": "Ocorreu um erro ao carregar este item", "ThereWasAnErrorLoadingThisPage": "Ocorreu um erro ao carregar esta página", @@ -1073,7 +1073,7 @@ "OnManualInteractionRequired": "Na Interação Manual Necessária", "OnManualInteractionRequiredHelpText": "Uma Interação Manual é Necessária", "ApiKeyValidationHealthCheckMessage": "Atualize sua chave de API para ter pelo menos {length} caracteres. Você pode fazer isso através das configurações ou do arquivo de configuração", - "ImportScriptPath": "Caminho para importar script", + "ImportScriptPath": "Caminho para script de importação", "ImportUsingScript": "Importar usando script", "RemoveCompletedDownloads": "Remover downloads concluídos", "RemoveFailedDownloads": "Remover downloads com falha", @@ -1084,7 +1084,7 @@ "DeleteImportListExclusionMessageText": "Tem certeza de que deseja excluir esta exclusão da lista de importação?", "DeleteRemotePathMappingMessageText": "Tem certeza de que deseja excluir este mapeamento de caminho remoto?", "DeleteCondition": "Excluir condição", - "CloneCondition": "Clonar Condição", + "CloneCondition": "Clonar condição", "DeleteCustomFormatMessageText": "Tem certeza de que deseja excluir o formato personalizado '{name}'?", "DeleteDelayProfileMessageText": "Tem certeza de que deseja excluir este perfil de atraso?", "DeleteFormatMessageText": "Tem certeza de que deseja excluir a etiqueta de formato {0} ?", @@ -1093,60 +1093,60 @@ "ResetAPIKeyMessageText": "Tem certeza de que deseja redefinir sua chave de API?", "ResetDefinitionTitlesHelpText": "Redefinir títulos de definição e valores", "ResetQualityDefinitionsMessageText": "Tem certeza de que deseja redefinir as definições de qualidade?", - "Complete": "Completo", + "Complete": "Concluído", "ListWillRefreshEveryInterval": "A lista será atualizada a cada {refreshInterval}", "ListRefreshInterval": "Intervalo de atualização da lista", "CountIndexersSelected": "{count} indexador(es) selecionado(s)", "ManageIndexers": "Gerenciar indexadores", - "ApplyChanges": "Aplicar Mudanças", + "ApplyChanges": "Aplicar mudanças", "EditSelectedIndexers": "Editar indexadores selecionados", "Popularity": "Popularidade", "PopularityIndex": "Índice de popularidade atual", "NoIndexersFound": "Nenhum indexador encontrado", "DownloadClientMovieTagHelpText": "Use este cliente de download apenas para filmes com pelo menos uma etiqueta correspondente. Deixe em branco para usar com todos os filmes.", - "AutomaticAdd": "Adição Automática", + "AutomaticAdd": "Adição automática", "CountDownloadClientsSelected": "{count} cliente(s) de download selecionado(s)", "CountImportListsSelected": "{count} lista(s) de importação selecionada(s)", "DeleteSelectedDownloadClients": "Excluir cliente(s) de download", - "DeleteSelectedDownloadClientsMessageText": "Tem certeza de que deseja excluir {count} cliente(s) de download selecionado(s)?", + "DeleteSelectedDownloadClientsMessageText": "Tem certeza de que deseja excluir o(s) {count} cliente(s) de download selecionado(s)?", "DeleteSelectedImportLists": "Excluir lista(s) de importação", - "DeleteSelectedImportListsMessageText": "Tem certeza de que deseja excluir {count} lista(s) de importação selecionada(s)?", + "DeleteSelectedImportListsMessageText": "Tem certeza de que deseja excluir a(s) {count} lista(s) de importação selecionada(s)?", "DeleteSelectedIndexers": "Excluir indexador(es)", - "DeleteSelectedIndexersMessageText": "Tem certeza de que deseja excluir {count} indexadores selecionados?", + "DeleteSelectedIndexersMessageText": "Tem certeza de que deseja excluir o(s) {count} indexador(es) selecionado(s)?", "EditSelectedDownloadClients": "Editar clientes de download selecionados", "EditSelectedImportLists": "Editar listas de importação selecionadas", "Implementation": "Implementação", - "ManageClients": "Gerenciar Clientes", + "ManageClients": "Gerenciar clientes", "ManageDownloadClients": "Gerenciar clientes de download", "ManageImportLists": "Gerenciar listas de importação", "ManageLists": "Gerenciar listas", "NoDownloadClientsFound": "Nenhum cliente de download encontrado", "NoImportListsFound": "Nenhuma lista de importação encontrada", - "ApplyTagsHelpTextAdd": "Adicionar: adicione as tags à lista existente de tags", - "ApplyTagsHelpTextHowToApplyDownloadClients": "Como aplicar tags aos clientes de download selecionados", - "ApplyTagsHelpTextHowToApplyImportLists": "Como aplicar tags às listas de importação selecionadas", - "ApplyTagsHelpTextHowToApplyIndexers": "Como aplicar tags aos indexadores selecionados", - "ApplyTagsHelpTextRemove": "Remover: Remove as tags inseridas", - "ApplyTagsHelpTextReplace": "Substituir: Substitua as tags pelas tags inseridas (não digite nenhuma tag para limpar todas as tags)", + "ApplyTagsHelpTextAdd": "Adicionar: adicione as etiquetas à lista existente de etiquetas", + "ApplyTagsHelpTextHowToApplyDownloadClients": "Como aplicar etiquetas aos clientes de download selecionados", + "ApplyTagsHelpTextHowToApplyImportLists": "Como aplicar etiquetas às listas de importação selecionadas", + "ApplyTagsHelpTextHowToApplyIndexers": "Como aplicar etiquetas aos indexadores selecionados", + "ApplyTagsHelpTextRemove": "Remover: remove as etiquetas inseridas", + "ApplyTagsHelpTextReplace": "Substituir: substitui as etiquetas atuais pelas inseridas (deixe em branco para limpar todas as etiquetas)", "AllTitles": "Todos os títulos", - "MatchedToMovie": "Correspondente ao Filme", + "MatchedToMovie": "Correspondente ao filme", "ReleaseHash": "Hash do Lançamento", "TestParsing": "Análise de teste", "SkipRedownload": "Ignorar o Redownload", "SkipRedownloadHelpText": "Evita que o {appName} tente baixar uma versão alternativa para este item", "MoveAutomatically": "Mover automaticamente", - "AddAutoTag": "Adicionar tag automática", - "AddCondition": "Adicionar Condição", - "AutoTaggingNegateHelpText": "se marcada, a regra de etiqueta automática não será aplicada se esta condição {implementationName} corresponder.", + "AddAutoTag": "Adicionar etiqueta automática", + "AddCondition": "Adicionar condição", + "AutoTaggingNegateHelpText": "Se marcada, a regra de etiquetas automáticas não será aplicada se corresponder à condição {implementationName}.", "RemoveTagsAutomatically": "Remover Tags Automaticamente", - "AutoTagging": "Tagging Automática", - "AutoTaggingRequiredHelpText": "Esta condição {implementationName} deve corresponder para que a regra de etiqueta automática seja aplicada. Caso contrário, uma única correspondência de {implementationName} será suficiente.", - "CloneAutoTag": "Clonar Tag Automática", - "DeleteAutoTag": "Excluir Tag Automática", - "DeleteAutoTagHelpText": "Tem certeza de que deseja excluir a tag automática '{name}'?", - "EditAutoTag": "Editar Tag Automática", + "AutoTagging": "Etiquetas automáticas", + "AutoTaggingRequiredHelpText": "Esta condição, {implementationName}, deve corresponder para que a regra de etiqueta automática seja aplicada. Caso contrário, uma única correspondência de {implementationName} será suficiente.", + "CloneAutoTag": "Clonar etiqueta automática", + "DeleteAutoTag": "Excluir etiqueta automática", + "DeleteAutoTagHelpText": "Tem certeza de que deseja excluir a etiqueta automática '{name}'?", + "EditAutoTag": "Editar etiqueta automática", "RemoveTagsAutomaticallyHelpText": "Remover tags automaticamente se as condições não forem encontradas", - "AutoTaggingLoadError": "Não foi possível carregar a marcação automática", + "AutoTaggingLoadError": "Não foi possível carregar as etiquetas automáticas", "DeleteRootFolder": "Excluir pasta raiz", "DeleteRootFolderMessageText": "Tem certeza de que deseja excluir a pasta raiz '{path}'?", "RootFolderPath": "Caminho da Pasta Raiz", @@ -1176,14 +1176,14 @@ "EditIndexerImplementation": "Editar indexador - {implementationName}", "AuthenticationRequired": "Autenticação exigida", "AuthenticationRequiredHelpText": "Altere para quais solicitações a autenticação é necessária. Não mude a menos que você entenda os riscos.", - "AuthenticationRequiredWarning": "Para evitar o acesso remoto sem autenticação, {appName} agora exige que a autenticação esteja habilitada. Opcionalmente, você pode desabilitar a autenticação de endereços locais.", + "AuthenticationRequiredWarning": "Para evitar o acesso remoto sem autenticação, o {appName} agora exige que a autenticação esteja habilitada. Opcionalmente, você pode desabilitar a autenticação para endereços locais.", "BypassDelayIfAboveCustomFormatScore": "Ignorar se estiver acima da pontuação do formato personalizado", - "BypassDelayIfAboveCustomFormatScoreHelpText": "Ativar ignorar quando a versão tiver uma pontuação maior que a pontuação mínima configurada do formato personalizado", - "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Pontuação mínima de formato personalizado", - "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Pontuação mínima de formato personalizado necessária para ignorar o atraso do protocolo preferido", + "BypassDelayIfAboveCustomFormatScoreHelpText": "Ignorar quando o lançamento tiver uma pontuação mais alta que a pontuação mínima configurada do formato personalizado", + "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Pontuação mínima do formato personalizado", + "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Pontuação mínima do formato personalizado necessária para ignorar o atraso do protocolo preferido", "NotificationStatusAllClientHealthCheckMessage": "Todas as notificações estão indisponíveis devido a falhas", "NotificationStatusSingleClientHealthCheckMessage": "Notificações indisponíveis devido a falhas: {notificationNames}", - "AutomaticUpdatesDisabledDocker": "As atualizações automáticas não têm suporte direto ao usar o mecanismo de atualização do Docker. Você precisará atualizar a imagem do contêiner fora de {appName} ou usar um script", + "AutomaticUpdatesDisabledDocker": "As atualizações automáticas não têm suporte direto ao usar o mecanismo de atualização do Docker. Você precisará atualizar a imagem do contêiner fora do {appName} ou usar um script", "RemotePathMappingsInfo": "Raramente são necessários mapeamentos de caminho remoto, se {appName} e seu cliente de download estiverem no mesmo sistema, é melhor combinar seus caminhos. Para obter mais informações, consulte o [wiki]({wikiLink}).", "DisabledForLocalAddresses": "Desabilitado para endereços locais", "AudioLanguages": "Idiomas do áudio", @@ -1192,8 +1192,8 @@ "VideoDynamicRange": "Faixa Dinâmica de Vídeo", "Default": "Padrão", "DownloadClientsLoadError": "Não foi possível carregar os clientes de download", - "IMDbId": "Id do IMDb", - "ManualGrab": "Baixar Manualmente", + "IMDbId": "ID do IMDb", + "ManualGrab": "Baixar manualmente", "OverrideAndAddToDownloadQueue": "Substituir e adicionar à fila de download", "OverrideGrabModalTitle": "Substituir e Baixar - {title}", "OverrideGrabNoLanguage": "Pelo menos um idioma deve ser selecionado", @@ -1204,11 +1204,11 @@ "DeleteSelectedMovieFilesHelpText": "Tem certeza de que deseja excluir os arquivos de filme selecionados?", "False": "Falso", "InteractiveImportLoadError": "Não foi possível carregar itens de importação manual", - "InteractiveImportNoFilesFound": "Nenhum arquivo de vídeo foi encontrado na pasta selecionada", - "InteractiveImportNoImportMode": "Defina um modo de importação", - "InteractiveImportNoLanguage": "Defina um idioma para cada arquivo selecionado", - "InteractiveImportNoMovie": "O filme deve ser escolhido para cada arquivo selecionado", - "InteractiveImportNoQuality": "Defina a qualidade para cada arquivo selecionado", + "InteractiveImportNoFilesFound": "Nenhum arquivo de vídeo encontrado na pasta selecionada", + "InteractiveImportNoImportMode": "Selecione um modo de importação", + "InteractiveImportNoLanguage": "Selecione um idioma para cada arquivo selecionado", + "InteractiveImportNoMovie": "Selecione o filme para cada arquivo selecionado", + "InteractiveImportNoQuality": "Selecione a qualidade para cada arquivo selecionado", "InteractiveSearchResultsFailedErrorMessage": "A pesquisa falhou porque {message}. Tente atualizar as informações do filme e verifique se as informações necessárias estão presentes antes de pesquisar novamente.", "LanguagesLoadError": "Não foi possível carregar os idiomas", "MovieSearchResultsLoadError": "Não foi possível carregar os resultados desta pesquisa de filmes. Tente mais tarde", @@ -1225,7 +1225,7 @@ "True": "Verdadeiro", "HealthMessagesInfoBox": "Para saber mais sobre a causa dessas mensagens de verificação de integridade, clique no link da wiki (ícone de livro) no final da linha ou verifique os [logs]({link}). Se tiver dificuldade em interpretar essas mensagens, entre em contato com nosso suporte nos links abaixo.", "DefaultNameCopiedProfile": "{name} - Cópia", - "InvalidUILanguage": "Sua UI está definida com um idioma inválido, corrija-a e salve suas configurações", + "InvalidUILanguage": "Sua interface está definida com um idioma inválido, corrija-o e salve suas configurações", "AuthenticationMethod": "Método de autenticação", "AuthenticationMethodHelpTextWarning": "Selecione um método de autenticação válido", "AuthenticationRequiredPasswordHelpTextWarning": "Digite uma nova senha", @@ -1242,17 +1242,17 @@ "NoHistoryFound": "Nenhum histórico encontrado", "QueueLoadError": "Falha ao carregar a fila", "BlocklistLoadError": "Não foi possível carregar a lista de bloqueio", - "BlocklistReleaseHelpText": "Impede que esta versão seja baixada novamente por {appName} via RSS ou Pesquisa Automática", + "BlocklistReleaseHelpText": "Impede que esta versão seja baixada novamente pelo {appName} via RSS ou Pesquisa automática", "CustomFormatJson": "JSON do formato personalizado", "DelayingDownloadUntil": "Atrasando o download até {date} às {time}", "DeletedReasonUpgrade": "O arquivo foi excluído para importar uma atualização", "DownloadIgnored": "Download ignorado", "GrabId": "Obter ID", "HistoryLoadError": "Não foi possível carregar o histórico", - "InfoUrl": "URL da info", - "MovieImported": "Filme Importado", + "InfoUrl": "URL de informações", + "MovieImported": "Filme importado", "MovieGrabbedTooltip": "Filme obtido de {indexer} e enviado para {downloadClient}", - "MovieImportedTooltip": "Filme baixado com sucesso e obtido no cliente de download", + "MovieImportedTooltip": "Filme baixado com sucesso e transferido do cliente de download", "PendingDownloadClientUnavailable": "Pendente - O cliente de download não está disponível", "FormatAgeDays": "dias", "FormatAgeHour": "hora", @@ -1266,9 +1266,9 @@ "FormatShortTimeSpanMinutes": "{minutes} minuto(s)", "FormatShortTimeSpanSeconds": "{seconds} segundo(s)", "FormatTimeSpanDays": "{days}d {time}", - "MovieFileRenamed": "Arquivo do Filme Renomeado", + "MovieFileRenamed": "Arquivo do filme renomeado", "MovieFileRenamedTooltip": "Arquivo do filme renomeado", - "MovieFileDeleted": "Arquivo do Filme Excluído", + "MovieFileDeleted": "Arquivo do filme excluído", "MovieFileDeletedTooltip": "Arquivo do filme excluído", "MovieFolderImportedTooltip": "Filme importado da pasta de filmes", "Or": "ou", @@ -1284,22 +1284,22 @@ "ShowUnknownMovieItemsHelpText": "Mostrar itens sem filme na fila. Isso pode incluir filmes removidos ou qualquer outra coisa na categoria do {appName}", "TablePageSizeMaximum": "O tamanho da página não pode exceder {maximumValue}", "AppUpdated": "{appName} atualizado", - "AppUpdatedVersion": "{appName} foi atualizado para a versão `{version}`. Para obter as alterações mais recentes, você precisará recarregar {appName}", - "ConnectionLostReconnect": "{appName} tentará se conectar automaticamente ou você pode clicar em recarregar abaixo.", - "ConnectionLostToBackend": "{appName} perdeu a conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.", + "AppUpdatedVersion": "O {appName} foi atualizado para a versão `{version}`. Para obter as alterações mais recentes, recarregue o {appName}", + "ConnectionLostReconnect": "O {appName} tentará se conectar automaticamente ou você pode clicar em Recarregar abaixo.", + "ConnectionLostToBackend": "O {appName} perdeu a conexão com o backend e precisará ser recarregado para restaurar a funcionalidade.", "OrganizeLoadError": "Erro ao carregar visualizações", "OrganizeModalHeader": "Organizar & Renomear", "OrganizeNamingPattern": "Padrão de nomenclatura: `{standardMovieFormat}`", "OrganizeNothingToRename": "Sucesso! Meu trabalho está concluído, não há arquivos para renomear.", "OrganizeRelativePaths": "Todos os caminhos são relativos a: `{path}`", "OrganizeRenamingDisabled": "A renomeação está deshabilitada, nada para renomear", - "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "O cliente de download {downloadClientName} está configurado para remover downloads concluídos. Isso pode resultar na remoção dos downloads do seu cliente antes que {appName} possa importá-los.", + "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "O cliente de download {downloadClientName} está configurado para remover os downloads concluídos. Isso pode resultar na remoção dos downloads do seu cliente antes que o {appName} possa importá-los.", "Umask": "Desmascarar", - "AutoRedownloadFailedFromInteractiveSearch": "Falha no Novo Download da Pesquisa Interativa", - "AutoRedownloadFailedFromInteractiveSearchHelpText": "Procure e tente baixar automaticamente uma versão diferente quando a versão com falha for obtida da pesquisa interativa", - "AutoRedownloadFailed": "Falha no Novo Download", + "AutoRedownloadFailedFromInteractiveSearch": "Falha no novo download usando a pesquisa interativa", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "Procurar e tentar baixar automaticamente um lançamento diferente quando for obtido um lançamento com falha na pesquisa interativa", + "AutoRedownloadFailed": "Falha no novo download", "QueueFilterHasNoItems": "O filtro de fila selecionado não possui itens", - "EnableProfile": "Habilitar Perfil", + "EnableProfile": "Habilitar perfil", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Confirme a nova senha", "ClearBlocklist": "Limpar lista de bloqueio", "ClearBlocklistMessageText": "Tem certeza de que deseja limpar todos os itens da lista de bloqueio?", @@ -1310,13 +1310,13 @@ "PackageVersionInfo": "{packageVersion} por {packageAuthor}", "PreviouslyInstalled": "Instalado anteriormente", "UpdaterLogFiles": "Arquivos de log do atualizador", - "InteractiveSearchModalHeader": "Pesquisa Interativa", + "InteractiveSearchModalHeader": "Pesquisa interativa", "WhySearchesCouldBeFailing": "Clique aqui para descobrir por que as pesquisas podem estar falhando", "AddRootFolderError": "Não foi possível adicionar a pasta raiz", - "DownloadClientQbittorrentSettingsContentLayout": "Layout de Conteúdo", - "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Seja para usar o layout de conteúdo configurado do qBittorrent, o layout original do torrent ou sempre criar uma subpasta (qBittorrent 4.3.2+)", + "DownloadClientQbittorrentSettingsContentLayout": "Layout de conteúdo", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Se devemos usar o layout de conteúdo configurado do qBittorrent, o layout original do torrent ou sempre criar uma subpasta (qBittorrent 4.3.2+)", "SearchMoviesConfirmationMessageText": "Tem certeza de que deseja pesquisar {count} filme(s)?", - "ManageFiles": "Gerenciar Arquivos", + "ManageFiles": "Gerenciar arquivos", "NotificationsAppriseSettingsConfigurationKey": "Informar Chave de Configuração", "NotificationsAppriseSettingsNotificationType": "Informar Tipo de Notificação", "NotificationsAppriseSettingsServerUrl": "Informar URL do Servidor", @@ -1355,7 +1355,7 @@ "NotificationsEmbySettingsUpdateLibraryHelpText": "Atualizar Biblioteca ao Importar, Renomear ou Excluir", "NotificationsGotifySettingIncludeMoviePoster": "Incluir Pôster do Filme", "NotificationsGotifySettingIncludeMoviePosterHelpText": "Incluir pôster do filme na mensagem", - "NotificationsGotifySettingsAppToken": "Token do Aplicativo", + "NotificationsGotifySettingsAppToken": "Token do aplicativo", "NotificationsGotifySettingsAppTokenHelpText": "O token do aplicativo gerado pelo Gotify", "NotificationsGotifySettingsPriorityHelpText": "Prioridade da notificação", "NotificationsJoinSettingsNotificationPriority": "Prioridade da Notificação", @@ -1487,11 +1487,11 @@ "NotificationsValidationUnableToConnectToApi": "Não foi possível conectar-se à API {service}. Falha na conexão do servidor: ({responseCode}) {exceptionMessage}", "DownloadClientAriaSettingsDirectoryHelpText": "Local opcional para colocar downloads, deixe em branco para usar o local padrão do Aria2", "MovieFileMissingTooltip": "Arquivo de filme ausente", - "IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeitar Hashes de Torrent Bloqueados Durante a Captura", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se um torrent for bloqueado por hash, ele pode não ser rejeitado corretamente durante o RSS/Pesquisa de alguns indexadores. Ativar isso permitirá que ele seja rejeitado após o torrent ser capturado, mas antes de ser enviado ao cliente.", - "DownloadClientPriorityHelpText": "Prioridade do Cliente de Download de 1 (mais alta) a 50 (mais baixa). Padrão: 1. Round-Robin é usado para clientes com a mesma prioridade.", + "IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeitar hashes de torrent bloqueados durante a captura", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se um torrent for bloqueado por hash, pode não ser rejeitado corretamente durante o RSS/Pesquisa de alguns indexadores. Ativar isso permitirá que ele seja rejeitado após o torrent ser capturado, mas antes de ser enviado ao cliente.", + "DownloadClientPriorityHelpText": "Prioridade do cliente de download de 1 (mais alta) a 50 (mais baixa). Padrão: 1. Usamos uma distribuição equilibrada para clientes com a mesma prioridade.", "ReleaseGroups": "Grupos do Lançamento", - "CutoffNotMet": "Corte Não Alcançado", + "CutoffNotMet": "Corte não atingido", "QualityCutoffNotMet": "Corte da Qualidade ainda não foi alcançado", "BlocklistAndSearch": "Adicionar à lista de bloqueio e pesquisar", "BlocklistAndSearchHint": "Iniciar uma pesquisa por um substituto após adicionar à lista de bloqueio", @@ -1504,10 +1504,10 @@ "CustomFormatsSpecificationRegularExpressionHelpText": "O regex do formato personalizado não diferencia maiúsculas e minúsculas", "DoNotBlocklist": "Não coloque na lista de bloqueio", "DoNotBlocklistHint": "Remover sem colocar na lista de bloqueio", - "IgnoreDownload": "Ignorar Download", - "IgnoreDownloadHint": "Impede que {appName} processe ainda mais este download", - "IgnoreDownloads": "Ignorar Downloads", - "IgnoreDownloadsHint": "Impede que {appName} processe ainda mais esses downloads", + "IgnoreDownload": "Ignorar download", + "IgnoreDownloadHint": "Impede que o {appName} processe ainda mais este download", + "IgnoreDownloads": "Ignorar downloads", + "IgnoreDownloadsHint": "Impede que o {appName} processe ainda mais esses downloads", "RemoveFromDownloadClientHint": "Remove download e arquivo(s) do cliente de download", "RemoveMultipleFromDownloadClientHint": "Remove downloads e arquivos do cliente de download", "RemoveQueueItemRemovalMethod": "Método de Remoção", @@ -1517,109 +1517,109 @@ "BlocklistMultipleOnlyHint": "Adicionar à lista de bloqueio sem procurar por substitutos", "NotificationsEmailSettingsUseEncryptionHelpText": "Se preferir usar criptografia se configurado no servidor, usar sempre criptografia via SSL (somente porta 465) ou StartTLS (qualquer outra porta) ou nunca usar criptografia", "ChangeCategoryMultipleHint": "Altera os downloads para a \"Categoria pós-importação' do cliente de download", - "BlackholeFolderHelpText": "Pasta na qual {appName} armazenará o arquivo {extension}", - "BlackholeWatchFolder": "Pasta de Monitoramento", - "BlackholeWatchFolderHelpText": "Pasta da qual {appName} deve importar downloads concluídos", + "BlackholeFolderHelpText": "Pasta na qual o {appName} armazenará o arquivo {extension}", + "BlackholeWatchFolder": "Pasta de monitoramento", + "BlackholeWatchFolderHelpText": "Pasta da qual o {appName} deve importar os downloads concluídos", "Category": "Categoria", - "Destination": "Destinação", + "Destination": "Destino", "Directory": "Diretório", - "DownloadClientDelugeSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL json do deluge, consulte {url}", + "DownloadClientDelugeSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL do JSON do Deluge, consulte {url}", "DownloadClientDelugeTorrentStateError": "Deluge está relatando um erro", "DownloadClientDelugeValidationLabelPluginFailure": "Falha na configuração do rótulo", - "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} não conseguiu adicionar o rótulo ao {clientName}.", + "DownloadClientDelugeValidationLabelPluginFailureDetail": "O {appName} não conseguiu adicionar o rótulo ao {clientName}.", "DownloadClientDelugeValidationLabelPluginInactive": "Plugin de rótulo não ativado", - "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Você deve ter o plugin rótulo habilitado no {clientName} para usar categorias.", - "DownloadClientDownloadStationProviderMessage": "{appName} não consegue se conectar ao Download Station se a autenticação de dois fatores estiver habilitada em sua conta DSM", + "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Você deve ter o plugin de rótulo habilitado no {clientName} para usar categorias.", + "DownloadClientDownloadStationProviderMessage": "O {appName} não consegue se conectar ao Download Station se a autenticação de dois fatores estiver habilitada em sua conta do DSM", "DownloadClientDownloadStationSettingsDirectoryHelpText": "Pasta compartilhada opcional para colocar downloads, deixe em branco para usar o local padrão do Download Station", - "DownloadClientDownloadStationValidationApiVersion": "A versão da API do Download Station não é suportada; deve ser pelo menos {requiredVersion}. Suporta de {minVersion} a {maxVersion}", - "DownloadClientFloodSettingsAddPaused": "Adicionar Pausado", - "DownloadClientFloodSettingsAdditionalTags": "Etiquetas Adicionais", + "DownloadClientDownloadStationValidationApiVersion": "A versão da API do Download Station não é suportada; deve ser pelo menos {requiredVersion}. Suporte às versões de {minVersion} a {maxVersion}", + "DownloadClientFloodSettingsAddPaused": "Adicionar pausado", + "DownloadClientFloodSettingsAdditionalTags": "Etiquetas adicionais", "DownloadClientFloodSettingsAdditionalTagsHelpText": "Adiciona propriedades de mídia como etiquetas. As dicas são exemplos.", - "DownloadClientFloodSettingsPostImportTags": "Etiquetas Pós-Importação", + "DownloadClientFloodSettingsPostImportTags": "Etiquetas pós-importação", "DownloadClientFloodSettingsPostImportTagsHelpText": "Acrescenta etiquetas após a importação de um download.", - "DownloadClientFloodSettingsRemovalInfo": "{appName} cuidará da remoção automática de torrents com base nos critérios de propagação atuais em Configurações -> Indexadores", - "DownloadClientFloodSettingsStartOnAdd": "Comece ao Adicionar", + "DownloadClientFloodSettingsRemovalInfo": "O {appName} cuidará da remoção automática de torrents com base nos critérios de semeadura atuais em Configurações -> Indexadores", + "DownloadClientFloodSettingsStartOnAdd": "Começar ao adicionar", "DownloadClientFloodSettingsTagsHelpText": "Etiquetas iniciais de um download. Para ser reconhecido, um download deve ter todas as etiquetas iniciais. Isso evita conflitos com downloads não relacionados.", - "DownloadClientFloodSettingsUrlBaseHelpText": "Adiciona um prefixo à API Flood, como {url}", - "DownloadClientFreeboxApiError": "A API Freebox retornou um erro: {errorDescription}", - "DownloadClientFreeboxAuthenticationError": "A autenticação na API Freebox falhou. Motivo: {errorDescription}", - "DownloadClientFreeboxNotLoggedIn": "Não logado", + "DownloadClientFloodSettingsUrlBaseHelpText": "Adiciona um prefixo à API do Flood, como {url}", + "DownloadClientFreeboxApiError": "A API do Freebox retornou um erro: {errorDescription}", + "DownloadClientFreeboxAuthenticationError": "A autenticação na API do Freebox falhou. Motivo: {errorDescription}", + "DownloadClientFreeboxNotLoggedIn": "Não conectado", "DownloadClientFreeboxSettingsApiUrl": "URL da API", - "DownloadClientFreeboxSettingsApiUrlHelpText": "Defina o URL base da API Freebox com a versão da API, por exemplo, '{url}', o padrão é '{defaultApiUrl}'", - "DownloadClientFreeboxSettingsAppId": "ID do App", - "DownloadClientFreeboxSettingsAppIdHelpText": "ID do aplicativo fornecido ao criar acesso à API Freebox (ou seja, 'app_id')", - "DownloadClientFreeboxSettingsAppToken": "Token do App", - "DownloadClientFreeboxSettingsHostHelpText": "Nome do host ou endereço IP do host do Freebox, o padrão é '{url}' (só funcionará se estiver na mesma rede)", - "DownloadClientFreeboxSettingsPortHelpText": "Porta usada para acessar a interface do Freebox, o padrão é '{port}'", - "DownloadClientFreeboxUnableToReachFreeboxApi": "Não foi possível acessar a API Freebox. Verifique a configuração de 'URL da API' para URL base e versão.", + "DownloadClientFreeboxSettingsApiUrlHelpText": "Defina o URL base da API do Freebox com a versão da API, por exemplo, \"{url}\", o padrão é \"{defaultApiUrl}\"", + "DownloadClientFreeboxSettingsAppId": "ID do aplicativo", + "DownloadClientFreeboxSettingsAppIdHelpText": "ID do aplicativo fornecida ao criar acesso à API do Freebox (ou seja, \"app_id\")", + "DownloadClientFreeboxSettingsAppToken": "Token do aplicativo", + "DownloadClientFreeboxSettingsHostHelpText": "Nome ou endereço IP do host do Freebox, o padrão é \"{url}\" (só funcionará se estiver na mesma rede)", + "DownloadClientFreeboxSettingsPortHelpText": "Porta usada para acessar a interface do Freebox, o padrão é \"{port}\"", + "DownloadClientFreeboxUnableToReachFreeboxApi": "Não foi possível acessar a API do Freebox. Verifique o URL base e a versão na configuração \"URL da API\".", "DownloadClientNzbVortexMultipleFilesMessage": "O download contém vários arquivos e não está em uma pasta de trabalho: {outputPath}", - "DownloadClientNzbgetSettingsAddPausedHelpText": "Esta opção requer pelo menos NzbGet versão 16.0", - "DownloadClientNzbgetValidationKeepHistoryOverMax": "A configuração NzbGet KeepHistory deve ser menor que 25.000", + "DownloadClientNzbgetSettingsAddPausedHelpText": "Esta opção requer pelo menos a versão 16.0 do NzbGet", + "DownloadClientNzbgetValidationKeepHistoryOverMax": "A configuração KeepHistory do NzbGet deve ser menor que 25.000", "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "A configuração KeepHistory do NzbGet está muito alta.", "DownloadClientNzbgetValidationKeepHistoryZero": "A configuração KeepHistory do NzbGet deve ser maior que 0", - "DownloadClientNzbgetValidationKeepHistoryZeroDetail": "A configuração KeepHistory do NzbGet está definida como 0. O que impede que {appName} veja os downloads concluídos.", + "DownloadClientNzbgetValidationKeepHistoryZeroDetail": "A configuração KeepHistory do NzbGet está definida como 0, que impede que o {appName} veja os downloads concluídos.", "DownloadClientPneumaticSettingsNzbFolder": "Pasta Nzb", "DownloadClientPneumaticSettingsNzbFolderHelpText": "Esta pasta precisará estar acessível no XBMC", "DownloadClientPneumaticSettingsStrmFolder": "Pasta Strm", "DownloadClientPneumaticSettingsStrmFolderHelpText": "Os arquivos .strm nesta pasta serão importados pelo drone", - "DownloadClientQbittorrentSettingsFirstAndLastFirst": "Primeiro e Último Primeiro", - "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Baixe a primeira e a última peças primeiro (qBittorrent 4.1.0+)", - "DownloadClientQbittorrentSettingsSequentialOrder": "Ordem Sequencial", - "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Baixe em ordem sequencial (qBittorrent 4.1.0+)", - "DownloadClientQbittorrentSettingsUseSslHelpText": "Use uma conexão segura. Consulte Opções - UI da Web - 'Usar HTTPS em vez de HTTP' em qBittorrent.", - "DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent não pode resolver o link magnético com DHT desativado", - "DownloadClientQbittorrentTorrentStateError": "qBittorrent está relatando um erro", - "DownloadClientQbittorrentTorrentStateMetadata": "qBittorrent está baixando metadados", + "DownloadClientQbittorrentSettingsFirstAndLastFirst": "Priorizar o primeiro e o último", + "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Baixe a primeira e a última partes antes (qBittorrent 4.1.0+)", + "DownloadClientQbittorrentSettingsSequentialOrder": "Ordem sequencial", + "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Baixar em ordem sequencial (qBittorrent 4.1.0+)", + "DownloadClientQbittorrentSettingsUseSslHelpText": "Usar uma conexão segura. Consulte Opções -> Interface de Usuário da Web -> \"Usar HTTPS ao invés do HTTP\" no qBittorrent.", + "DownloadClientQbittorrentTorrentStateDhtDisabled": "O qBittorrent não consegue resolver o link magnético com DHT desativado", + "DownloadClientQbittorrentTorrentStateError": "O qBittorrent está relatando um erro", + "DownloadClientQbittorrentTorrentStateMetadata": "O qBittorrent está baixando os metadados", "DownloadClientQbittorrentTorrentStateStalled": "O download está parado sem conexões", "DownloadClientQbittorrentTorrentStateUnknown": "Estado de download desconhecido: {state}", "DownloadClientQbittorrentValidationCategoryAddFailure": "Falha na configuração da categoria", - "DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName} não conseguiu adicionar o rótulo ao qBittorrent.", - "DownloadClientQbittorrentValidationCategoryRecommended": "Categoria é recomendada", - "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} não tentará importar downloads concluídos sem uma categoria.", + "DownloadClientQbittorrentValidationCategoryAddFailureDetail": "O {appName} não conseguiu adicionar o rótulo ao qBittorrent.", + "DownloadClientQbittorrentValidationCategoryRecommended": "Recomenda-se usar uma categoria", + "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "O {appName} não tentará importar downloads concluídos sem uma categoria.", "DownloadClientQbittorrentValidationCategoryUnsupported": "A categoria não é suportada", - "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "As categorias não são suportadas até a versão 3.3.0 do qBittorrent. Atualize ou tente novamente com uma categoria vazia.", - "DownloadClientQbittorrentValidationQueueingNotEnabled": "Fila Não Habilitada", - "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent está configurado para remover torrents quando eles atingem seu limite de proporção de compartilhamento", - "DownloadClientRTorrentSettingsAddStopped": "Adicionar Parado", - "DownloadClientRTorrentSettingsAddStoppedHelpText": "Habilitando, irá adicionar torrents e magnets ao rTorrent em um estado parado. Isso pode quebrar os arquivos magnéticos.", + "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "Não há categorias até a versão 3.3.0 do qBittorrent. Atualize ou tente novamente com uma categoria vazia.", + "DownloadClientQbittorrentValidationQueueingNotEnabled": "Fila não habilitada", + "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "O qBittorrent está configurado para remover torrents quando eles atingem seu limite de proporção de compartilhamento", + "DownloadClientRTorrentSettingsAddStopped": "Adicionar parado", + "DownloadClientRTorrentSettingsAddStoppedHelpText": "Habilitar esta opção adicionará os torrents e links magnéticos ao rTorrent em um estado parado. Isso pode quebrar os arquivos magnéticos.", "DownloadClientRTorrentSettingsDirectoryHelpText": "Local opcional para colocar downloads, deixe em branco para usar o local padrão do rTorrent", - "DownloadClientRTorrentSettingsUrlPath": "Caminho da URL", - "DownloadClientRTorrentSettingsUrlPathHelpText": "Caminho para o endpoint XMLRPC, consulte {url}. Geralmente é RPC2 ou [caminho para ruTorrent]{url2} ao usar o ruTorrent.", - "DownloadClientSabnzbdValidationCheckBeforeDownload": "Desative a opção ‘Verificar antes do download’ no Sabnbzd", + "DownloadClientRTorrentSettingsUrlPath": "Caminho do URL", + "DownloadClientRTorrentSettingsUrlPathHelpText": "Caminho para o ponto de extremidade do XMLRPC, consulte {url}. Geralmente é RPC2 ou [caminho para ruTorrent]{url2} ao usar o ruTorrent.", + "DownloadClientSabnzbdValidationCheckBeforeDownload": "Desative a opção \"Verificar antes do download\" no Sabnbzd", "DownloadClientSabnzbdValidationDevelopVersion": "Versão de desenvolvimento do Sabnzbd, assumindo a versão 3.0.0 ou superior.", - "DownloadClientSabnzbdValidationDevelopVersionDetail": "{appName} pode não ser compatível com novos recursos adicionados ao SABnzbd ao executar versões de desenvolvimento.", - "DownloadClientSabnzbdValidationEnableDisableDateSorting": "Desativar Classificação por Data", - "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Desabilitar Classificação de Filmes", - "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Você deve desativar a classificação de filmes para a categoria usada por {appName} para evitar problemas de importação. Vá para Sabnzbd para consertar.", - "DownloadClientSabnzbdValidationEnableDisableTvSorting": "Desabilitar Classificação de TV", - "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Você deve desativar a classificação de TV para a categoria usada por {appName} para evitar problemas de importação. Vá para Sabnzbd para consertar.", + "DownloadClientSabnzbdValidationDevelopVersionDetail": "O {appName} pode não ser compatível com novos recursos adicionados ao SABnzbd ao executar versões de desenvolvimento.", + "DownloadClientSabnzbdValidationEnableDisableDateSorting": "Desativar classificação por data", + "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Desabilitar classificação de filmes", + "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Você deve desativar a classificação de filmes para a categoria usada pelo {appName} para evitar problemas de importação. Conserte isso no Sabnzbd.", + "DownloadClientSabnzbdValidationEnableDisableTvSorting": "Desabilitar classificação de séries", + "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Você deve desabilitar a classificação de séries para a categoria usada pelo {appName} para evitar problemas de importação. Conserte isso no Sabnzbd.", "DownloadClientSabnzbdValidationEnableJobFolders": "Habilitar pastas de trabalho", - "DownloadClientSabnzbdValidationUnknownVersion": "Versão Desconhecida: {rawVersion}", - "DownloadClientSettingsAddPaused": "Adicionar Pausado", - "DownloadClientSettingsCategoryHelpText": "Adicionar uma categoria específica para {appName} evita conflitos com downloads não relacionados que não sejam de {appName}. Usar uma categoria é opcional, mas altamente recomendado.", - "DownloadClientSettingsCategorySubFolderHelpText": "Adicionar uma categoria específica para {appName} evita conflitos com downloads não relacionados que não sejam de {appName}. Usar uma categoria é opcional, mas altamente recomendado. Cria um subdiretório [categoria] no diretório de saída.", + "DownloadClientSabnzbdValidationUnknownVersion": "Versão desconhecida: {rawVersion}", + "DownloadClientSettingsAddPaused": "Adicionar pausado", + "DownloadClientSettingsCategoryHelpText": "Adicionar uma categoria específica ao {appName} evita conflitos com downloads não relacionados que não sejam do {appName}. Usar uma categoria é opcional, mas altamente recomendado.", + "DownloadClientSettingsCategorySubFolderHelpText": "Adicionar uma categoria específica ao {appName} evita conflitos com downloads não relacionados que não sejam do {appName}. Usar uma categoria é opcional, mas altamente recomendado. Cria um subdiretório \"[categoria]\" no diretório de saída.", "DownloadClientSettingsDestinationHelpText": "Especifica manualmente o destino do download, deixe em branco para usar o padrão", - "DownloadClientSettingsInitialState": "Estado Inicial", - "DownloadClientSettingsInitialStateHelpText": "Estado inicial dos torrents adicionados a {clientName}", - "DownloadClientSettingsOlderPriority": "Priorizar Mais Antigos", - "DownloadClientSettingsOlderPriorityMovieHelpText": "Prioridade de uso ao baixar filmes que foram ao ar há mais de 21 dias", - "DownloadClientSettingsPostImportCategoryHelpText": "Categoria para {appName} definir após importar o download. {appName} não removerá torrents nessa categoria mesmo que a propagação seja concluída. Deixe em branco para manter a mesma categoria.", - "DownloadClientSettingsRecentPriority": "Priorizar Recentes", - "DownloadClientSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL {clientName}, como {url}", - "DownloadClientSettingsUseSslHelpText": "Use conexão segura ao conectar-se a {clientName}", - "DownloadClientTransmissionSettingsDirectoryHelpText": "Local opcional para colocar downloads, deixe em branco para usar o local de transmissão padrão", - "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL rpc {clientName}, por exemplo, {url}, o padrão é '{defaultUrl}'", - "DownloadClientUTorrentTorrentStateError": "uTorrent está relatando um erro", - "DownloadClientValidationApiKeyIncorrect": "Chave de API incorreta", - "DownloadClientValidationApiKeyRequired": "Chave de API necessária", - "DownloadClientValidationAuthenticationFailure": "Falha de Autenticação", + "DownloadClientSettingsInitialState": "Estado inicial", + "DownloadClientSettingsInitialStateHelpText": "Estado inicial dos torrents adicionados ao {clientName}", + "DownloadClientSettingsOlderPriority": "Priorizar mais antigos", + "DownloadClientSettingsOlderPriorityMovieHelpText": "Prioridade ao baixar filmes que foram lançados há mais de 21 dias", + "DownloadClientSettingsPostImportCategoryHelpText": "Categoria para o {appName} definir após importar o download. O {appName} não removerá torrents nessa categoria mesmo que a semeadura esteja concluída. Deixe em branco para manter a mesma categoria.", + "DownloadClientSettingsRecentPriority": "Priorizar recentes", + "DownloadClientSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL do {clientName}, como {url}", + "DownloadClientSettingsUseSslHelpText": "Usar conexão segura ao conectar-se ao {clientName}", + "DownloadClientTransmissionSettingsDirectoryHelpText": "Local opcional para colocar os downloads, deixe em branco para usar o local padrão do Transmission", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL de chamada remota do {clientName}, por exemplo, {url}. O padrão é \"{defaultUrl}\"", + "DownloadClientUTorrentTorrentStateError": "O uTorrent está relatando um erro", + "DownloadClientValidationApiKeyIncorrect": "Chave da API incorreta", + "DownloadClientValidationApiKeyRequired": "Chave da API necessária", + "DownloadClientValidationAuthenticationFailure": "Falha de autenticação", "DownloadClientValidationCategoryMissing": "A categoria não existe", - "DownloadClientValidationCategoryMissingDetail": "A categoria inserida não existe em {clientName}. Crie-o primeiro em {clientName}.", - "DownloadClientValidationErrorVersion": "A versão de {clientName} deve ser pelo menos {requiredVersion}. A versão informada é {reportedVersion}", + "DownloadClientValidationCategoryMissingDetail": "A categoria inserida não existe no {clientName}. Crie-a primeiro no {clientName}.", + "DownloadClientValidationErrorVersion": "A versão do {clientName} deve ser pelo menos {requiredVersion}. A versão informada é {reportedVersion}", "DownloadClientValidationGroupMissing": "O grupo não existe", - "DownloadClientValidationGroupMissingDetail": "O grupo inserido não existe em {clientName}. Crie-o primeiro em {clientName}.", + "DownloadClientValidationGroupMissingDetail": "O grupo inserido não existe no {clientName}. Crie-o primeiro no {clientName}.", "DownloadClientValidationSslConnectFailure": "Não é possível conectar através de SSL", - "DownloadClientValidationSslConnectFailureDetail": "{appName} não consegue se conectar a {clientName} usando SSL. Este problema pode estar relacionado ao computador. Tente configurar {appName} e {clientName} para não usar SSL.", + "DownloadClientValidationSslConnectFailureDetail": "O {appName} não consegue se conectar ao {clientName} usando SSL. Este problema pode estar relacionado ao computador. Tente configurar o {appName} e o {clientName} para não usar SSL.", "DownloadClientValidationTestNzbs": "Falha ao obter a lista de NZBs: {exceptionMessage}", "DownloadClientValidationTestTorrents": "Falha ao obter a lista de torrents: {exceptionMessage}", "DownloadClientValidationUnableToConnect": "Não foi possível conectar-se a {clientName}", @@ -1631,25 +1631,25 @@ "DownloadStationStatusExtracting": "Extraindo: {progress}%", "Menu": "Menu", "MovieIsPopular": "O filme é popular no TMDb", - "DownloadClientFreeboxSettingsAppTokenHelpText": "Token do aplicativo recuperado ao criar acesso à API Freebox (ou seja, 'app_token')", - "DownloadClientFreeboxUnableToReachFreebox": "Não foi possível acessar a API Freebox. Verifique as configurações de 'Host', 'Porta' ou 'Usar SSL'. (Erro: {exceptionMessage})", - "DownloadClientQbittorrentTorrentStatePathError": "Não foi possível importar. O caminho corresponde ao diretório de download da base do cliente, é possível que 'Manter pasta de nível superior' esteja desabilitado para este torrent ou 'Layout de conteúdo de torrent' NÃO esteja definido como 'Original' ou 'Criar subpasta'?", - "DownloadClientQbittorrentSettingsInitialStateHelpText": "Estado inicial para torrents adicionados ao qBittorrent. Observe que os Torrents Forçados não obedecem às restrições de semeação", - "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "O Fila de Torrent não está habilitado nas configurações do qBittorrent. Habilite-o no qBittorrent ou selecione ‘Último’ como prioridade.", - "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} não poderá realizar o tratamento de download concluído conforme configurado. Você pode corrigir isso no qBittorrent ('Ferramentas -> Opções...' no menu) alterando 'Opções -> BitTorrent -> Limitação da proporção de compartilhamento' de 'Removê-los' para 'Pausá-los'", - "DownloadClientRTorrentProviderMessage": "O rTorrent não pausará os torrents quando eles atenderem aos critérios de seed. {appName} lidará com a remoção automática de torrents com base nos critérios de propagação atuais em Configurações->Indexadores somente quando Remover Concluído estiver habilitado. · · Após a importação, ele também definirá {importedView} como uma visualização rTorrent, que pode ser usada em scripts rTorrent para personalizar o comportamento.", - "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Usar 'Verificar antes do download' afeta a capacidade do {appName} de rastrear novos downloads. Além disso, o Sabnzbd recomenda 'Abortar trabalhos que não podem ser concluídos', pois é mais eficaz.", - "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Você deve desativar a classificação por data para a categoria usada por {appName} para evitar problemas de importação. Vá para Sabnzbd para consertar.", - "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} prefere que cada download tenha uma pasta separada. Com * anexado à pasta/caminho, o Sabnzbd não criará essas pastas de trabalho. Vá para Sabnzbd para consertar.", - "DownloadClientSettingsRecentPriorityMovieHelpText": "Prioridade de uso ao baixar filmes que foram ao ar nos últimos 21 dias", - "DownloadClientValidationAuthenticationFailureDetail": "Por favor verifique seu nome de usuário e senha. Verifique também se o host que executa {appName} não está impedido de acessar {clientName} pelas limitações da WhiteList na configuração de {clientName}.", + "DownloadClientFreeboxSettingsAppTokenHelpText": "Token do aplicativo recuperado ao criar acesso à API do Freebox (ou seja, \"app_token\")", + "DownloadClientFreeboxUnableToReachFreebox": "Não foi possível acessar a API do Freebox. Verifique as configurações \"Host\", \"Porta\" ou \"Usar SSL\". (Erro: {exceptionMessage})", + "DownloadClientQbittorrentTorrentStatePathError": "Não foi possível importar. O caminho corresponde ao diretório de download base do cliente, é possível que \"Manter pasta de nível superior\" esteja desabilitado para este torrent ou \"Layout de conteúdo de torrent\" NÃO esteja definido como 'Original' ou 'Criar subpasta'?", + "DownloadClientQbittorrentSettingsInitialStateHelpText": "Estado inicial para torrents adicionados ao qBittorrent. Observe que torrents forçados não obedecem às restrições de semeadura", + "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "A fila de torrents não está habilitada nas configurações do qBittorrent. Habilite-a no qBittorrent ou selecione \"Último\" como prioridade.", + "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "O {appName} não poderá realizar o tratamento de download concluído conforme configurado. Para corrigir isso, no qBittorrent, acesse \"Ferramentas -> Opções... -> BitTorrent -> Limites de Semeadura\", e altere a opção de \"Remover\" para \"Parar\"", + "DownloadClientRTorrentProviderMessage": "O rTorrent não pausará os torrents quando eles atenderem aos critérios de semeadura. O {appName} lidará com a remoção automática de torrents com base nos critérios de semeadura atuais em Configurações -> Indexadores somente quando Remover concluído estiver habilitado. · · Após a importação, ele também definirá {importedView} como uma visualização do rTorrent, que pode ser usada em scripts do rTorrent para personalizar o comportamento.", + "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Usar \"Verificar antes do download\" afeta a capacidade do {appName} de rastrear novos downloads. Além disso, o Sabnzbd recomenda \"Abortar trabalhos que não podem ser concluídos\", pois é mais eficaz.", + "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Você deve desativar a classificação por data para a categoria usada pelo {appName} para evitar problemas de importação. Conserte isso no Sabnzbd.", + "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "O {appName} prefere que cada download tenha uma pasta separada. Com * anexado à pasta/caminho, o Sabnzbd não criará essas pastas de trabalho. Conserte isso no Sabnzbd.", + "DownloadClientSettingsRecentPriorityMovieHelpText": "Prioridade ao baixar filmes que foram lançados nos últimos 21 dias", + "DownloadClientValidationAuthenticationFailureDetail": "Verifique o nome de usuário e a senha. Verifique também se o host que executa o {appName} não está impedido o acesso ao {clientName} pelas limitações da Lista de permissões na configuração do {clientName}.", "Donate": "Doar", "DownloadClientDownloadStationValidationFolderMissing": "A pasta não existe", - "DownloadClientDownloadStationValidationFolderMissingDetail": "A pasta '{downloadDir}' não existe, ela deve ser criada manualmente dentro da Pasta Compartilhada '{sharedFolder}'.", + "DownloadClientDownloadStationValidationFolderMissingDetail": "A pasta \"{downloadDir}\" não existe. Você deve criá-la manualmente dentro da Pasta compartilhada \"{sharedFolder}\".", "DownloadClientDownloadStationValidationNoDefaultDestination": "Nenhum destino padrão", - "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Você deve fazer login em seu Diskstation como {username} e configurá-lo manualmente nas configurações do DownloadStation em BT/HTTP/FTP/NZB -> Localização.", + "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Você deve fazer login em seu Diskstation como {username} e configurá-lo manualmente nas configurações do Download Station em BT/HTTP/FTP/NZB -> Localização.", "DownloadClientDownloadStationValidationSharedFolderMissing": "A pasta compartilhada não existe", - "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "O Diskstation não possui uma pasta compartilhada com o nome '{sharedFolder}', tem certeza de que a especificou corretamente?", + "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "O Diskstation não possui uma Pasta compartilhada com o nome \"{sharedFolder}\", tem certeza de que a especificou corretamente?", "NzbgetHistoryItemMessage": "Status PAR: {parStatus} - Status de descompactação: {unpackStatus} - Status de movimentação: {moveStatus} - Status do script: {scriptStatus} - Status de exclusão: {deleteStatus} - Status de marcação: {markStatus}", "PostImportCategory": "Categoria Pós-Importação", "SecretToken": "Token Secreto", @@ -1670,9 +1670,9 @@ "TorrentBlackholeTorrentFolder": "Pasta do Torrent", "NoExtraFilesToManage": "Não há arquivos extras para gerenciar.", "Space": "Espaço", - "DeleteSpecification": "Excluir Especificação", + "DeleteSpecification": "Excluir especificação", "EditMetadata": "Editar {metadataType} Metadados", - "AddReleaseProfile": "Adicionar um Perfil de Lançamento", + "AddReleaseProfile": "Adicionar perfil de lançamento", "Clone": "Clonar", "NotificationsTagsMovieHelpText": "Envie notificações apenas para filmes com pelo menos uma etiqueta correspondente", "OneMinute": "1 Minuto", @@ -1682,41 +1682,41 @@ "Yes": "Sim", "AddDelayProfileError": "Não foi possível adicionar um novo perfil de atraso. Tente novamente.", "Dash": "Traço", - "DelayMinutes": "{delay} Minutos", + "DelayMinutes": "{delay} minutos", "ChownGroup": "Fazer chown em grupo", - "EditReleaseProfile": "Editar Perfil de Lançamento", + "EditReleaseProfile": "Editar perfil de lançamento", "EnableProfileHelpText": "Marque para habilitar o perfil de lançamento", "Example": "Exemplo", "HourShorthand": "h", - "ListRootFolderHelpText": "Os itens da lista da pasta raiz que serão adicionados", + "ListRootFolderHelpText": "Os itens da lista da pasta raiz serão adicionados a", "MovieFolderFormatHelpText": "Usado ao adicionar um novo filme ou mover filmes através do editor de filmes", "MustContainHelpText": "O lançamento deve conter pelo menos um destes termos (não diferenciar maiúsculas e minúsculas)", - "MustNotContainHelpText": "O lançamento será rejeitado se contiver um ou mais termos (não diferenciar maiúsculas e minúsculas)", + "MustNotContainHelpText": "O lançamento será rejeitado se contiver um ou mais destes termos (não diferencia maiúsculas e minúsculas)", "No": "Não", "NoDelay": "Sem Atraso", "Release": "Lançamento", "ReleaseProfileIndexerHelpText": "Especifique a qual indexador o perfil se aplica", "ReleaseProfileTagMovieHelpText": "Os perfis de lançamento serão aplicados a filmes com pelo menos uma etiqueta correspondente. Deixe em branco para aplicar a todos os filmes", "Repack": "Repack", - "RestartLater": "Vou reiniciar mais tarde", + "RestartLater": "Reiniciarei mais tarde", "RestartRequiredWindowsService": "Dependendo de qual usuário está executando o serviço {appName}, pode ser necessário reiniciar {appName} como administrador uma vez antes que o serviço seja iniciado automaticamente.", "TypeOfList": "{typeOfList} Lista", "Underscore": "Sublinhar", - "ListQualityProfileHelpText": "Os itens da lista de Perfil de Qualidade que serão adicionados com", + "ListQualityProfileHelpText": "Os itens da lista de Perfil de qualidade serão adicionados com", "AddAutoTagError": "Não foi possível adicionar uma nova etiqueta automática, tente novamente.", "DeleteReleaseProfileMessageText": "Tem certeza de que deseja excluir o perfil de lançamento '{name}'?", "DeleteSpecificationHelpText": "Tem certeza de que deseja excluir a especificação '{name}'?", - "ConditionUsingRegularExpressions": "Esta condição corresponde ao uso de Expressões Regulares. Observe que os caracteres `\\^$.|?*+()[{` têm significados especiais e precisam escape com um `\\`", + "ConditionUsingRegularExpressions": "Esta condição corresponde ao uso de Expressões Regulares. Observe que os caracteres `\\^$.|?*+()[{` têm significados especiais e precisam de escape com um `\\`", "DelayProfileMovieTagsHelpText": "Aplica-se a filmes com pelo menos uma etiqueta correspondente", "DelayProfileProtocol": "Protocolo: {preferredProtocol}", - "DeleteReleaseProfile": "Excluir Perfil de Lançamento", + "DeleteReleaseProfile": "Excluir perfil de lançamento", "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages suporta um sufixo `:EN+DE` permitindo filtrar os idiomas incluídos no nome do arquivo. Use `-DE` para excluir idiomas específicos. Anexar `+` (por exemplo, `:EN+`) resultará em `[EN]`/`[EN+--]`/`[--]` dependendo dos idiomas excluídos. Por exemplo, `{MediaInfo Full:EN+DE}`.", "RegularExpressionsTutorialLink": "Mais detalhes sobre expressões regulares podem ser encontrados [aqui](https://www.regular-expressions.info/tutorial.html).", "RestartRequiredToApplyChanges": "{appName} requer reinicialização para aplicar as alterações. Deseja reiniciar agora?", "SupportedAutoTaggingProperties": "{appName} oferece suporte às propriedades a seguir para regras de codificação automática", "WantMoreControlAddACustomFormat": "Quer mais controle sobre quais downloads são preferidos? Adicione um [Formato Personalizado](/settings/customformats)", "SearchMoviesOnAdd": "Pesquisar Filmes ao Adicionar", - "AddListExclusion": "Adicionar Exclusão de Lista", + "AddListExclusion": "Adicionar exclusão à lista", "ExistsInLibrary": "Existe na Biblioteca", "Lists": "Listas", "Popular": "Popular", @@ -1739,7 +1739,7 @@ "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Local opcional para mover os downloads concluídos, deixe em branco para usar o local padrão do Deluge", "ConnectionSettingsUrlBaseHelpText": "Adiciona um prefixo ao URL {connectionName}, como {url}", "ReleaseProfileIndexerHelpTextWarning": "Definir um indexador específico em um perfil de lançamento fará com que esse perfil seja aplicado apenas a lançamentos desse indexador.", - "IncludeHealthWarnings": "Incluir Alertas de Saúde", + "IncludeHealthWarnings": "Incluir avisos de integridade", "CustomFormatsSettingsTriggerInfo": "Um formato personalizado será aplicado a um lançamento ou arquivo quando corresponder a pelo menos um dos diferentes tipos de condição escolhidos.", "AutoTaggingSpecificationTag": "Etiqueta", "NotificationsTelegramSettingsIncludeAppName": "Incluir {appName} no Título", @@ -1855,5 +1855,13 @@ "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Grave metadados em movie.nfo em vez do nome de arquivo de filme padrão .nfo", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluir URLs de filmes TMDb e IMDb no .nfo", "FileBrowser": "Navegador de Arquivos", - "ManageFormats": "Gerenciar Formatos" + "ManageFormats": "Gerenciar Formatos", + "Completed": "Concluída", + "Delay": "Atraso", + "Fallback": "Reserva", + "FavoriteFolderAdd": "Adicionar Pasta Favorita", + "FavoriteFolderRemove": "Remover Pasta Favorita", + "FavoriteFolders": "Pastas Favoritas", + "Warning": "Cuidado", + "DownloadClientUnavailable": "Cliente de download indisponível" } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 2214381d26..14823cd417 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -267,7 +267,7 @@ "AlreadyInYourLibrary": "Deja în biblioteca dvs.", "BackupFolderHelpText": "Căile relative vor fi în directorul AppData al lui {appName}", "ClickToChangeMovie": "Faceți clic pentru a schimba filmul", - "CloneCustomFormat": "Clonați format personalizat", + "CloneCustomFormat": "Clonează format personalizat", "CopyUsingHardlinksHelpTextWarning": "Ocazional, blocarea fișierelor poate împiedica redenumirea fișierelor care sunt însămânțate. Puteți dezactiva temporar însămânțarea și puteți utiliza funcția de redenumire a lui {appName} ca soluție.", "CustomFormatHelpText": "{appName} marchează fiecare versiune folosind suma scorurilor pentru potrivirea formatelor personalizate. Dacă o nouă versiune ar îmbunătăți scorul, la aceeași calitate sau mai bună, atunci {appName} îl va lua.", "UpgradeUntilMovieHelpText": "Odată atinsă această calitate, {appName} nu va mai descărca filme", @@ -588,8 +588,8 @@ "Real": "Real", "ClickToChangeLanguage": "Faceți clic pentru a schimba limba", "ClickToChangeQuality": "Faceți clic pentru a schimba calitatea", - "CloneIndexer": "Clonă Indexer", - "CloneProfile": "Clonați profil", + "CloneIndexer": "Clonează Indexer", + "CloneProfile": "Clonează Profil", "CloseCurrentModal": "Închideți modul curent", "ColonReplacement": "Înlocuirea colonului", "ColonReplacementFormatHelpText": "Schimbați modul în care {appName} gestionează înlocuirea colonului", @@ -992,7 +992,7 @@ "ApplyChanges": "Aplicați modificări", "AnnouncedMovieDescription": "Filmul este anunțat", "AutomaticAdd": "Adăugare automată", - "CloneCondition": "Clonați condiție", + "CloneCondition": "Clonează condiție", "AllTitles": "Toate titlurile", "ApplicationURL": "URL aplicație", "ApplyTagsHelpTextHowToApplyImportLists": "Cum se aplică etichete listelor de import selectate", @@ -1148,5 +1148,8 @@ "OnFileImport": "La import fișier", "OnFileUpgrade": "La actualizare fișier", "EditReleaseProfile": "Editați profilul de întârziere", - "Clone": "Închide" + "Clone": "Clonează", + "AddReleaseProfile": "Editați profilul de întârziere", + "Delay": "Întârziere", + "DownloadClientUnavailable": "Client de descărcare indisponibil" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index bfc8c1160f..189c2fa4ad 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1787,5 +1787,8 @@ "AnnouncedMovieAvailabilityDescription": "Фильмы считаются доступными, как только они добавляются в {appName}.", "CountCustomFormatsSelected": "{count} пользовательских форматов выбрано", "CustomFormatsSpecificationExceptLanguage": "Исключить язык", - "FileBrowser": "Файловый браузер" + "FileBrowser": "Файловый браузер", + "Completed": "Завершенный", + "Delay": "Задержка", + "DownloadClientUnavailable": "Программа для скачивания недоступна" } diff --git a/src/NzbDrone.Core/Localization/Core/sk.json b/src/NzbDrone.Core/Localization/Core/sk.json index 2b89b291f0..ad150833f8 100644 --- a/src/NzbDrone.Core/Localization/Core/sk.json +++ b/src/NzbDrone.Core/Localization/Core/sk.json @@ -298,5 +298,6 @@ "TMDb": "TMDb", "Reason": "Séria", "Clone": "Zatvoriť", - "AllTitles": "Všetky súbory" + "AllTitles": "Všetky súbory", + "Delay": "Oneskorenie" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 3eeebbeed9..1c67fcbea5 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1097,5 +1097,8 @@ "FolderNameTokens": "Filnamn tokens", "Clone": "Avsluta", "AllTitles": "Samtliga filer", - "EditReleaseProfile": "Redigera fördröjningsprofil" + "EditReleaseProfile": "Redigera fördröjningsprofil", + "AddReleaseProfile": "Redigera fördröjningsprofil", + "Delay": "Fördröj", + "DownloadClientUnavailable": "Nedladdningsklient är otillgänglig" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 4774dd7362..120a49104f 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1069,5 +1069,7 @@ "FolderNameTokens": "โทเค็นชื่อไฟล์", "Clone": "ปิด", "AllTitles": "เอกสารทั้งหมด", - "EditReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า" + "EditReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า", + "AddReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า", + "DownloadClientUnavailable": "ไม่สามารถดาวน์โหลดไคลเอนต์ได้" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index d3ac8b301a..23c78d53a1 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1854,5 +1854,7 @@ "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Meta verileri varsayılan .nfo yerine movie.nfo'ya yaz", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "TMDb ve IMDb film URL'lerini .nfo'ya ekleyin", "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın", - "FileBrowser": "Dosya Yöneticisi" + "FileBrowser": "Dosya Yöneticisi", + "Completed": "Tamamla", + "DownloadClientUnavailable": "İndirme istemcisi kullanılamıyor" } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 5240f21343..ed26e9c589 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1286,5 +1286,8 @@ "ShowPhysicalRelease": "Дата фізичного випуску", "ShowPhysicalReleaseHelpText": "Показати дату випуску під плакатом", "FolderNameTokens": "Маркери імен файлів", - "DefaultNotFoundMessage": "Ви, мабуть, заблукали, тут нічого не видно." + "DefaultNotFoundMessage": "Ви, мабуть, заблукали, тут нічого не видно.", + "Completed": "Завершено", + "Delay": "Затримка", + "DownloadClientUnavailable": "Клієнт завантажувача недоступний" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 9d7726d819..a43a92e367 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1108,5 +1108,8 @@ "UnknownEventTooltip": "Sự kiện không rõ", "EditReleaseProfile": "Chỉnh sửa hồ sơ độ trễ", "Clone": "Đóng", - "AllTitles": "Tất cả các tệp" + "AllTitles": "Tất cả các tệp", + "DownloadClientUnavailable": "Ứng dụng khách tải xuống không khả dụng", + "AddReleaseProfile": "Chỉnh sửa hồ sơ độ trễ", + "EditConditionImplementation": "Thêm điều kiện - {implementationName}" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 9e87faf114..d5cf5c42bc 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -906,7 +906,7 @@ "MovieExcludedFromAutomaticAdd": "电影已被排除在自动添加之外", "MovieDetailsPreviousMovie": "电影详情:前作", "MovieDetailsNextMovie": "电影详情:续作", - "MovieChat": "电影聊天", + "MovieChat": "Movie Chat", "MovieAlreadyExcluded": "电影已排除", "Mode": "模式", "MinimumLimits": "最小限制", @@ -1851,5 +1851,9 @@ "MetadataSettingsMovieImages": "电影图片", "MetadataXmbcSettingsMovieMetadataNfoHelpText": "将元数据写入 movie.nfo 而非默认的 .nfo", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "在 .nfo 文件中包含电影的 TMDb 和 IMDb URLs", - "FileBrowser": "文件浏览器" + "FileBrowser": "文件浏览器", + "Completed": "完成", + "Delay": "延迟", + "DownloadClientUnavailable": "下载客户端不可用", + "Fallback": "备选" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index e614c01d5a..a1296f1229 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -251,5 +251,7 @@ "Discord": "Discord", "TMDb": "TMDb", "EditReleaseProfile": "新增延時配置", - "Reason": "季" + "Reason": "季", + "Delay": "延遲", + "AddReleaseProfile": "新增延時配置" } From 50ce480abf043140e209d2d2959fbea8dd5dd2ab Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 15 Nov 2024 21:48:26 +0200 Subject: [PATCH 081/579] Pin ReportGenerator in Azure Pipelines for .NET 6 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 547e17be7d..d2955f0302 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1226,7 +1226,7 @@ stages: - task: SonarCloudAnalyze@2 condition: eq(variables['System.PullRequest.IsFork'], 'False') displayName: Publish SonarCloud Results - - task: reportgenerator@5 + - task: reportgenerator@5.3.11 displayName: Generate Coverage Report inputs: reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml' From a752476cdb9435615d563496480ecbe54dbd9bb9 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 14 Nov 2024 19:01:38 -0800 Subject: [PATCH 082/579] Fixed: Allow files to be moved from Torrent Blackhole even when remove is disabled (cherry picked from commit f739fd0900695e2ff312d13985c87d84ae00ea75) --- .../Blackhole/TorrentBlackholeFixture.cs | 2 +- .../Download/Clients/Blackhole/TorrentBlackhole.cs | 5 ++--- .../Download/Clients/Blackhole/UsenetBlackhole.cs | 10 ++++++---- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs index 50f2f03770..2154b8163b 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/TorrentBlackholeFixture.cs @@ -119,7 +119,7 @@ public void completed_download_should_have_required_properties() VerifyCompleted(result); - result.CanBeRemoved.Should().BeFalse(); + result.CanBeRemoved.Should().BeTrue(); result.CanMoveFiles.Should().BeFalse(); } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs index b6fe511fb2..d51c0bf877 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/TorrentBlackhole.cs @@ -104,9 +104,8 @@ public override IEnumerable GetItems() Status = item.Status }; - queueItem.CanMoveFiles = queueItem.CanBeRemoved = - queueItem.DownloadClientInfo.RemoveCompletedDownloads && - !Settings.ReadOnly; + queueItem.CanMoveFiles = !Settings.ReadOnly; + queueItem.CanBeRemoved = queueItem.DownloadClientInfo.RemoveCompletedDownloads; yield return queueItem; } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs index 0216be0407..241aa047f5 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/UsenetBlackhole.cs @@ -59,7 +59,7 @@ public override IEnumerable GetItems() { foreach (var item in _scanWatchFolder.GetItems(Settings.WatchFolder, ScanGracePeriod)) { - yield return new DownloadClientItem + var queueItem = new DownloadClientItem { DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, false), DownloadId = Definition.Name + "_" + item.DownloadId, @@ -72,10 +72,12 @@ public override IEnumerable GetItems() OutputPath = item.OutputPath, Status = item.Status, - - CanBeRemoved = true, - CanMoveFiles = true }; + + queueItem.CanMoveFiles = true; + queueItem.CanBeRemoved = queueItem.DownloadClientInfo.RemoveCompletedDownloads; + + yield return queueItem; } } From 2429dd91c6d08eb2b70b14db2b3c673d320e6a5c Mon Sep 17 00:00:00 2001 From: Elias Benbourenane Date: Thu, 14 Nov 2024 22:27:56 -0500 Subject: [PATCH 083/579] Allow `GetFileSize` to follow symlinks (cherry picked from commit ca0bb14027f3409014e7cf9ffa8e04e577001d77) --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 20a6607ac0..8983b92989 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -189,6 +189,18 @@ public long GetFileSize(string path) } var fi = new FileInfo(path); + + // If the file is a symlink, resolve the target path and get the size of the target file. + if (fi.Attributes.HasFlag(FileAttributes.ReparsePoint)) + { + var targetPath = fi.ResolveLinkTarget(true)?.FullName; + + if (targetPath != null) + { + fi = new FileInfo(targetPath); + } + } + return fi.Length; } From ea86d14ca7d2ca896f2487c22bce5d026ad63602 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 3 Nov 2024 16:22:32 -0800 Subject: [PATCH 084/579] Fixed: Normalize unicode characters when comparing paths for equality (cherry picked from commit ceeec091f85d0094e07537b7f62f18292655a710) --- src/NzbDrone.Common.Test/PathExtensionFixture.cs | 10 ++++++++++ src/NzbDrone.Common/Extensions/PathExtensions.cs | 4 ++++ src/NzbDrone.Common/PathEqualityComparer.cs | 4 ++-- 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Common.Test/PathExtensionFixture.cs b/src/NzbDrone.Common.Test/PathExtensionFixture.cs index 2c9d8f7a5a..5a54eb7559 100644 --- a/src/NzbDrone.Common.Test/PathExtensionFixture.cs +++ b/src/NzbDrone.Common.Test/PathExtensionFixture.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Text; using FluentAssertions; using Moq; using NUnit.Framework; @@ -433,5 +434,14 @@ public void unix_path_should_return_relative_path(string parentPath, string chil { parentPath.GetRelativePath(childPath).Should().Be(relativePath); } + + [Test] + public void should_be_equal_with_different_unicode_representations() + { + var path1 = @"C:\Test\file.mkv".AsOsAgnostic().Normalize(NormalizationForm.FormC); + var path2 = @"C:\Test\file.mkv".AsOsAgnostic().Normalize(NormalizationForm.FormD); + + path1.PathEquals(path2); + } } } diff --git a/src/NzbDrone.Common/Extensions/PathExtensions.cs b/src/NzbDrone.Common/Extensions/PathExtensions.cs index cbf82e41cb..93e9746381 100644 --- a/src/NzbDrone.Common/Extensions/PathExtensions.cs +++ b/src/NzbDrone.Common/Extensions/PathExtensions.cs @@ -55,6 +55,10 @@ public static bool PathNotEquals(this string firstPath, string secondPath, Strin public static bool PathEquals(this string firstPath, string secondPath, StringComparison? comparison = null) { + // Normalize paths to ensure unicode characters are represented the same way + firstPath = firstPath.Normalize(); + secondPath = secondPath?.Normalize(); + if (!comparison.HasValue) { comparison = DiskProviderBase.PathStringComparison; diff --git a/src/NzbDrone.Common/PathEqualityComparer.cs b/src/NzbDrone.Common/PathEqualityComparer.cs index 5b9c3aa1c3..bd6fa430d9 100644 --- a/src/NzbDrone.Common/PathEqualityComparer.cs +++ b/src/NzbDrone.Common/PathEqualityComparer.cs @@ -21,10 +21,10 @@ public int GetHashCode(string obj) { if (OsInfo.IsWindows) { - return obj.CleanFilePath().ToLower().GetHashCode(); + return obj.CleanFilePath().Normalize().ToLower().GetHashCode(); } - return obj.CleanFilePath().GetHashCode(); + return obj.CleanFilePath().Normalize().GetHashCode(); } } } From 09b4bf15cf668c81f8bbd43478b8d24c81972b74 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 17 Nov 2024 09:27:40 +0000 Subject: [PATCH 085/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/pt_BR.json | 6 +++--- src/NzbDrone.Core/Localization/Core/tr.json | 15 +++++++++++---- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 3d77bd57d0..e127824417 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1856,7 +1856,7 @@ "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Escribe los metadatos en película.nfo en lugar de al archivo .nfo predeterminado", "FileBrowser": "Explorador de archivos", "ManageFormats": "Gestionar formatos", - "Completed": "Completados", + "Completed": "Completado", "Delay": "Retardo", "FavoriteFolderAdd": "Añadir carpeta favorita", "FavoriteFolders": "Carpetas favoritas", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 806cf80cec..0bbace0f8f 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -338,7 +338,7 @@ "ApplyTagsHelpTextHowToApplyMovies": "Como aplicar etiquetas aos filmes selecionados", "ApplyTags": "Aplicar etiquetas", "Apply": "Aplicar", - "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData", + "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na Atualização", "AppDataDirectory": "Diretório AppData", "ApiKey": "Chave da API", "Announced": "Anunciado", @@ -1491,7 +1491,7 @@ "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se um torrent for bloqueado por hash, pode não ser rejeitado corretamente durante o RSS/Pesquisa de alguns indexadores. Ativar isso permitirá que ele seja rejeitado após o torrent ser capturado, mas antes de ser enviado ao cliente.", "DownloadClientPriorityHelpText": "Prioridade do cliente de download de 1 (mais alta) a 50 (mais baixa). Padrão: 1. Usamos uma distribuição equilibrada para clientes com a mesma prioridade.", "ReleaseGroups": "Grupos do Lançamento", - "CutoffNotMet": "Corte não atingido", + "CutoffNotMet": "Corte Não Alcançado", "QualityCutoffNotMet": "Corte da Qualidade ainda não foi alcançado", "BlocklistAndSearch": "Adicionar à lista de bloqueio e pesquisar", "BlocklistAndSearchHint": "Iniciar uma pesquisa por um substituto após adicionar à lista de bloqueio", @@ -1856,7 +1856,7 @@ "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Incluir URLs de filmes TMDb e IMDb no .nfo", "FileBrowser": "Navegador de Arquivos", "ManageFormats": "Gerenciar Formatos", - "Completed": "Concluída", + "Completed": "Completado", "Delay": "Atraso", "Fallback": "Reserva", "FavoriteFolderAdd": "Adicionar Pasta Favorita", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 23c78d53a1..b34f813703 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -381,7 +381,7 @@ "AllMoviesInPathHaveBeenImported": "{path} içindeki tüm filmler içe aktarıldı", "AlternativeTitle": "Alternatif Başlık", "Always": "Her zaman", - "AptUpdater": "Güncellemeyi yüklemek için apt kullanın", + "AptUpdater": "Güncellemeyi yüklemek için apt'ı kullanın", "CancelProcessing": "İşlemeyi İptal Et", "CantFindMovie": "Filmimi neden bulamıyorum?", "CertValidationNoLocal": "Yerel Adresler için Devre Dışı Bırak", @@ -592,7 +592,7 @@ "AllMoviesHiddenDueToFilter": "Uygulanan filtre nedeniyle tüm filmler gizlendi.", "AllowHardcodedSubs": "Sabit Kodlu Aboneliklere İzin Ver", "AddRemotePathMapping": "Uzak Yol Eşleme Ekleme", - "AudioInfo": "Ses Bilgileri", + "AudioInfo": "Ses Bilgisi", "Cancel": "Vazgeç", "PhysicalRelease": "Fiziksel Salınım", "Port": "Liman", @@ -716,7 +716,7 @@ "EnableInteractiveSearchHelpText": "Etkileşimli arama kullanıldığında kullanılacak", "SearchIsNotSupportedWithThisIndexer": "Bu indeksleyici ile arama desteklenmiyor", "EnableRss": "RSS'yi etkinleştir", - "AnalyseVideoFilesHelpText": "Dosyalardan çözünürlük, çalışma zamanı ve kodek bilgileri gibi video bilgilerini çıkarın. Bu, {appName}'ın dosyanın taramalar sırasında yüksek disk veya ağ etkinliğine neden olabilecek bölümlerini okumasını gerektirir.", + "AnalyseVideoFilesHelpText": "Çözünürlük, çalışma zamanı ve kodek bilgileri gibi video bilgilerini dosyalardan çıkarın. Bu, {appName} uygulamasının taramalar sırasında yüksek disk veya ağ etkinliğine neden olabilecek dosyanın bölümlerini okumasını gerektirir.", "EnableSslHelpText": " Etkili olması için yönetici olarak yeniden çalıştırmayı gerektirir", "Error": "Hata", "ErrorLoadingContents": "İçerik yüklenirken hata oluştu", @@ -1856,5 +1856,12 @@ "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın", "FileBrowser": "Dosya Yöneticisi", "Completed": "Tamamla", - "DownloadClientUnavailable": "İndirme istemcisi kullanılamıyor" + "DownloadClientUnavailable": "İndirme istemcisi kullanılamıyor", + "Delay": "Gecikme", + "Fallback": "Geri Çek", + "FavoriteFolderAdd": "Favori Klasör Ekle", + "FavoriteFolderRemove": "Favori Klasörü Kaldır", + "FavoriteFolders": "Favori Klasörler", + "Warning": "Uyarı", + "ManageFormats": "Biçimleri Yönet" } From 179637fe8ba20c219849e085d395bfccd7e3f300 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 18 Nov 2024 22:50:02 +0200 Subject: [PATCH 086/579] Fixed: Release dates for Discover Movie posters --- .../Posters/DiscoverMoviePosterInfo.js | 36 ++++++++----------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js index 4feb8d89b2..a86824d15e 100644 --- a/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js +++ b/frontend/src/DiscoverMovie/Posters/DiscoverMoviePosterInfo.js @@ -50,15 +50,13 @@ function DiscoverMoviePosterInfo(props) { } if (sortKey === 'inCinemas' && inCinemas) { - const inCinemasDate = getRelativeDate( - inCinemas, + const inCinemasDate = getRelativeDate({ + date: inCinemas, shortDateFormat, showRelativeDates, - { - timeFormat, - timeForToday: false - } - ); + timeFormat, + timeForToday: false + }); return (
@@ -68,15 +66,13 @@ function DiscoverMoviePosterInfo(props) { } if (sortKey === 'digitalRelease' && digitalRelease) { - const digitalReleaseDate = getRelativeDate( - digitalRelease, + const digitalReleaseDate = getRelativeDate({ + date: digitalRelease, shortDateFormat, showRelativeDates, - { - timeFormat, - timeForToday: false - } - ); + timeFormat, + timeForToday: false + }); return (
@@ -86,15 +82,13 @@ function DiscoverMoviePosterInfo(props) { } if (sortKey === 'physicalRelease' && physicalRelease) { - const physicalReleaseDate = getRelativeDate( - physicalRelease, + const physicalReleaseDate = getRelativeDate({ + date: physicalRelease, shortDateFormat, showRelativeDates, - { - timeFormat, - timeForToday: false - } - ); + timeFormat, + timeForToday: false + }); return (
From 0411d6652066d268afc50ccd02f0e2c40de1c1fb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 19 Nov 2024 03:10:17 +0200 Subject: [PATCH 087/579] Bump version to 5.16.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index d2955f0302..c1713abaac 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.15.1' + majorVersion: '5.16.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From c3fa440cf8fcfa23f97fddf1ebbd5aab6d6f37fa Mon Sep 17 00:00:00 2001 From: Servarr <32001786+ServarrAdmin@users.noreply.github.com> Date: Tue, 19 Nov 2024 21:37:07 -0500 Subject: [PATCH 088/579] Multiple Translations updated by Weblate (#10688) ignore-downstream Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translation: Servarr/Radarr Co-authored-by: Weblate Co-authored-by: GkhnGRBZ --- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index b34f813703..68c38e8b68 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -105,7 +105,7 @@ "ReleaseBranchCheckOfficialBranchMessage": "{0} şubesi geçerli bir {appName} sürüm dalı değil; güncelleme almayacaksınız", "RefreshAndScan": "Yenile ve Tara", "Refresh": "Yenile", - "Queue": "Sırada", + "Queue": "Kuyruk", "QualitySettingsSummary": "Kalite boyutları ve adlandırma", "QualityProfiles": "Kalite Profileri", "QualityProfile": "Kalite Profili", From af06a9f70d3c4e6724eff64104b71fa12d56f141 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 23 Nov 2024 16:48:05 -0800 Subject: [PATCH 089/579] Webpack web target (cherry picked from commit a90866a73e6cff9a286c23e60c74672f4c0d317a) --- frontend/build/webpack.config.js | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/build/webpack.config.js b/frontend/build/webpack.config.js index b4b423674f..da97f73313 100644 --- a/frontend/build/webpack.config.js +++ b/frontend/build/webpack.config.js @@ -26,6 +26,7 @@ module.exports = (env) => { const config = { mode: isProduction ? 'production' : 'development', devtool: isProduction ? 'source-map' : 'eval-source-map', + target: 'web', stats: { children: false From 15b6f7212d70174ec3747468f9d28d42379d62dd Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 24 Nov 2024 16:25:24 +0000 Subject: [PATCH 090/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Havok Dan Co-authored-by: Mizuyoru_TW Co-authored-by: Weblate Co-authored-by: hebian Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/zh_CN.json | 2 +- src/NzbDrone.Core/Localization/Core/zh_TW.json | 8 +++++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 0bbace0f8f..fea5af8688 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -432,7 +432,7 @@ "AgeWhenGrabbed": "Tempo de vida (quando obtido)", "Agenda": "Programação", "Age": "Tempo de vida", - "AfterManualRefresh": "Após a atualização manual", + "AfterManualRefresh": "Após a Atualização Manual", "AddToDownloadQueue": "Adicionar à fila de download", "AddRootFolder": "Adicionar pasta raiz", "AddRestriction": "Adicionar restrição", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index d5cf5c42bc..8e64c6c95e 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1814,7 +1814,7 @@ "NotificationsDiscordSettingsOnManualInteractionFields": "手动操作时字段", "NotificationsPushoverSettingsSoundHelpText": "通知声音,留空使用默认声音", "ReleaseGroupFootNote": "可选参数,控制使用省略号(`...`)的最大截断字数。支持从末尾截断(例如:`{Movie Title:30}`)或从开头截断(例如:`{Movie Title:-30}`)。", - "Disposition": "Disposition", + "Disposition": "配置", "NotificationsGotifySettingsMetadataLinks": "元数据链接", "NotificationsGotifySettingsPreferredMetadataLink": "首选元数据链接", "NotificationsGotifySettingsMetadataLinksMovieHelpText": "添加一个在发送通知时指向电影元数据的链接", diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index a1296f1229..470d9fd0a5 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -253,5 +253,11 @@ "EditReleaseProfile": "新增延時配置", "Reason": "季", "Delay": "延遲", - "AddReleaseProfile": "新增延時配置" + "AddReleaseProfile": "新增延時配置", + "Version": "版本", + "Uptime": "上線時間", + "UpdateAvailableHealthCheckMessage": "可用的新版本: {version}", + "UpdateAppDirectlyLoadError": "無法直接更新 {appName},", + "UnselectAll": "取消全選", + "Any": "任何" } From ff609848d811e3b47d40a103a10ca06826d3642a Mon Sep 17 00:00:00 2001 From: bakerboy448 <55419169+bakerboy448@users.noreply.github.com> Date: Wed, 27 Nov 2024 15:15:35 -0600 Subject: [PATCH 091/579] New: Replace 'Ben the Man' release group parsing with 'Ben the Men' Closes #10676 (cherry picked from commit 202190d032257b3cd19e42606385db7052b2aae4) --- src/NzbDrone.Core.Test/ParserTests/ReleaseGroupParserFixture.cs | 2 +- src/NzbDrone.Core/Parser/Parser.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/ReleaseGroupParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/ReleaseGroupParserFixture.cs index b0fc6f6f12..970973bca9 100644 --- a/src/NzbDrone.Core.Test/ParserTests/ReleaseGroupParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/ReleaseGroupParserFixture.cs @@ -125,7 +125,7 @@ public void should_parse_release_group(string title, string expected) [TestCase("Movie Title(2023) 1080p SkySHO WEB-DL ESP DD+ 5.1 H.264-EML HDTeam", "EML HDTeam")] [TestCase("Movie Title (2022) BDFull 1080p DTS-HD MA 5.1 AVC LMain", "LMain")] [TestCase("Movie Title (2024) (1080p BluRay x265 SDR DDP 5.1 English - DarQ)", "DarQ")] - [TestCase("Movie Title (2024) (1080p BluRay x265 SDR DDP 5.1 English -BEN THE MAN", "BEN THE MAN")] + [TestCase("Movie Title (2024) (1080p BluRay x265 SDR DDP 5.1 English -BEN THE MEN", "BEN THE MEN")] public void should_parse_exception_release_group(string title, string expected) { Parser.Parser.ParseReleaseGroup(title).Should().Be(expected); diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 260a186d92..76011eab71 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -159,7 +159,7 @@ public static class Parser // Handle Exception Release Groups that don't follow -RlsGrp; Manual List // name only...BE VERY CAREFUL WITH THIS, HIGH CHANCE OF FALSE POSITIVES - private static readonly Regex ExceptionReleaseGroupRegexExact = new Regex(@"\b(?KRaLiMaRKo|E\.N\.D|D\-Z0N3|Koten_Gars|BluDragon|ZØNEHD|Tigole|HQMUX|VARYG|YIFY|YTS(.(MX|LT|AG))?|TMd|Eml HDTeam|LMain|DarQ|BEN THE MAN)\b", RegexOptions.IgnoreCase | RegexOptions.Compiled); + private static readonly Regex ExceptionReleaseGroupRegexExact = new Regex(@"\b(?KRaLiMaRKo|E\.N\.D|D\-Z0N3|Koten_Gars|BluDragon|ZØNEHD|Tigole|HQMUX|VARYG|YIFY|YTS(.(MX|LT|AG))?|TMd|Eml HDTeam|LMain|DarQ|BEN THE MEN)\b", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex WordDelimiterRegex = new Regex(@"(\s|\.|,|_|-|=|'|\|)+", RegexOptions.Compiled); private static readonly Regex SpecialCharRegex = new Regex(@"(\&|\:|\\|\/)+", RegexOptions.Compiled); From cd490d63349449cfe7aab164a9539d8e10dc4d8f Mon Sep 17 00:00:00 2001 From: Gauthier Date: Fri, 15 Nov 2024 04:01:05 +0100 Subject: [PATCH 092/579] New: Add headers setting in webhook connection (cherry picked from commit 78fb20282de73c0ea47375895a807235385d90e3) --- .../src/Components/Form/KeyValueListInput.js | 156 ------------------ .../src/Components/Form/KeyValueListInput.tsx | 104 ++++++++++++ .../Components/Form/KeyValueListInputItem.css | 14 +- .../Form/KeyValueListInputItem.css.d.ts | 3 +- .../Components/Form/KeyValueListInputItem.js | 124 -------------- .../Components/Form/KeyValueListInputItem.tsx | 89 ++++++++++ .../Components/Form/ProviderFieldFormGroup.js | 2 + frontend/src/typings/inputs.ts | 2 + .../Reflection/ReflectionExtensions.cs | 3 +- .../Annotations/FieldDefinitionAttribute.cs | 3 +- src/NzbDrone.Core/Localization/Core/en.json | 1 + .../Notifications/Webhook/WebhookProxy.cs | 5 + .../Notifications/Webhook/WebhookSettings.cs | 7 +- 13 files changed, 228 insertions(+), 285 deletions(-) delete mode 100644 frontend/src/Components/Form/KeyValueListInput.js create mode 100644 frontend/src/Components/Form/KeyValueListInput.tsx delete mode 100644 frontend/src/Components/Form/KeyValueListInputItem.js create mode 100644 frontend/src/Components/Form/KeyValueListInputItem.tsx diff --git a/frontend/src/Components/Form/KeyValueListInput.js b/frontend/src/Components/Form/KeyValueListInput.js deleted file mode 100644 index 3e73d74f3d..0000000000 --- a/frontend/src/Components/Form/KeyValueListInput.js +++ /dev/null @@ -1,156 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import KeyValueListInputItem from './KeyValueListInputItem'; -import styles from './KeyValueListInput.css'; - -class KeyValueListInput extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isFocused: false - }; - } - - // - // Listeners - - onItemChange = (index, itemValue) => { - const { - name, - value, - onChange - } = this.props; - - const newValue = [...value]; - - if (index == null) { - newValue.push(itemValue); - } else { - newValue.splice(index, 1, itemValue); - } - - onChange({ - name, - value: newValue - }); - }; - - onRemoveItem = (index) => { - const { - name, - value, - onChange - } = this.props; - - const newValue = [...value]; - newValue.splice(index, 1); - - onChange({ - name, - value: newValue - }); - }; - - onFocus = () => { - this.setState({ - isFocused: true - }); - }; - - onBlur = () => { - this.setState({ - isFocused: false - }); - - const { - name, - value, - onChange - } = this.props; - - const newValue = value.reduce((acc, v) => { - if (v.key || v.value) { - acc.push(v); - } - - return acc; - }, []); - - if (newValue.length !== value.length) { - onChange({ - name, - value: newValue - }); - } - }; - - // - // Render - - render() { - const { - className, - value, - keyPlaceholder, - valuePlaceholder, - hasError, - hasWarning - } = this.props; - - const { isFocused } = this.state; - - return ( -
- { - [...value, { key: '', value: '' }].map((v, index) => { - return ( - - ); - }) - } -
- ); - } -} - -KeyValueListInput.propTypes = { - className: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - value: PropTypes.arrayOf(PropTypes.object).isRequired, - hasError: PropTypes.bool, - hasWarning: PropTypes.bool, - keyPlaceholder: PropTypes.string, - valuePlaceholder: PropTypes.string, - onChange: PropTypes.func.isRequired -}; - -KeyValueListInput.defaultProps = { - className: styles.inputContainer, - value: [] -}; - -export default KeyValueListInput; diff --git a/frontend/src/Components/Form/KeyValueListInput.tsx b/frontend/src/Components/Form/KeyValueListInput.tsx new file mode 100644 index 0000000000..f5c6ac19be --- /dev/null +++ b/frontend/src/Components/Form/KeyValueListInput.tsx @@ -0,0 +1,104 @@ +import classNames from 'classnames'; +import React, { useCallback, useState } from 'react'; +import { InputOnChange } from 'typings/inputs'; +import KeyValueListInputItem from './KeyValueListInputItem'; +import styles from './KeyValueListInput.css'; + +interface KeyValue { + key: string; + value: string; +} + +export interface KeyValueListInputProps { + className?: string; + name: string; + value: KeyValue[]; + hasError?: boolean; + hasWarning?: boolean; + keyPlaceholder?: string; + valuePlaceholder?: string; + onChange: InputOnChange; +} + +function KeyValueListInput({ + className = styles.inputContainer, + name, + value = [], + hasError = false, + hasWarning = false, + keyPlaceholder, + valuePlaceholder, + onChange, +}: KeyValueListInputProps): JSX.Element { + const [isFocused, setIsFocused] = useState(false); + + const handleItemChange = useCallback( + (index: number | null, itemValue: KeyValue) => { + const newValue = [...value]; + + if (index === null) { + newValue.push(itemValue); + } else { + newValue.splice(index, 1, itemValue); + } + + onChange({ name, value: newValue }); + }, + [value, name, onChange] + ); + + const handleRemoveItem = useCallback( + (index: number) => { + const newValue = [...value]; + newValue.splice(index, 1); + onChange({ name, value: newValue }); + }, + [value, name, onChange] + ); + + const onFocus = useCallback(() => setIsFocused(true), []); + + const onBlur = useCallback(() => { + setIsFocused(false); + + const newValue = value.reduce((acc: KeyValue[], v) => { + if (v.key || v.value) { + acc.push(v); + } + return acc; + }, []); + + if (newValue.length !== value.length) { + onChange({ name, value: newValue }); + } + }, [value, name, onChange]); + + return ( +
+ {[...value, { key: '', value: '' }].map((v, index) => ( + + ))} +
+ ); +} + +export default KeyValueListInput; diff --git a/frontend/src/Components/Form/KeyValueListInputItem.css b/frontend/src/Components/Form/KeyValueListInputItem.css index 88c5847ee2..ed82db4592 100644 --- a/frontend/src/Components/Form/KeyValueListInputItem.css +++ b/frontend/src/Components/Form/KeyValueListInputItem.css @@ -5,13 +5,19 @@ &:last-child { margin-bottom: 0; + border-bottom: 0; } } -.inputWrapper { +.keyInputWrapper { flex: 1 0 0; } +.valueInputWrapper { + flex: 1 0 0; + min-width: 40px; +} + .buttonWrapper { flex: 0 0 22px; } @@ -20,4 +26,10 @@ .valueInput { width: 100%; border: none; + background-color: transparent; + color: var(--textColor); + + &::placeholder { + color: var(--helpTextColor); + } } diff --git a/frontend/src/Components/Form/KeyValueListInputItem.css.d.ts b/frontend/src/Components/Form/KeyValueListInputItem.css.d.ts index 35baf55cd3..aa0c1be134 100644 --- a/frontend/src/Components/Form/KeyValueListInputItem.css.d.ts +++ b/frontend/src/Components/Form/KeyValueListInputItem.css.d.ts @@ -2,10 +2,11 @@ // Please do not change this file! interface CssExports { 'buttonWrapper': string; - 'inputWrapper': string; 'itemContainer': string; 'keyInput': string; + 'keyInputWrapper': string; 'valueInput': string; + 'valueInputWrapper': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/Components/Form/KeyValueListInputItem.js b/frontend/src/Components/Form/KeyValueListInputItem.js deleted file mode 100644 index 5379c21290..0000000000 --- a/frontend/src/Components/Form/KeyValueListInputItem.js +++ /dev/null @@ -1,124 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import IconButton from 'Components/Link/IconButton'; -import { icons } from 'Helpers/Props'; -import TextInput from './TextInput'; -import styles from './KeyValueListInputItem.css'; - -class KeyValueListInputItem extends Component { - - // - // Listeners - - onKeyChange = ({ value: keyValue }) => { - const { - index, - value, - onChange - } = this.props; - - onChange(index, { key: keyValue, value }); - }; - - onValueChange = ({ value }) => { - // TODO: Validate here or validate at a lower level component - - const { - index, - keyValue, - onChange - } = this.props; - - onChange(index, { key: keyValue, value }); - }; - - onRemovePress = () => { - const { - index, - onRemove - } = this.props; - - onRemove(index); - }; - - onFocus = () => { - this.props.onFocus(); - }; - - onBlur = () => { - this.props.onBlur(); - }; - - // - // Render - - render() { - const { - keyValue, - value, - keyPlaceholder, - valuePlaceholder, - isNew - } = this.props; - - return ( -
-
- -
- -
- -
- -
- { - isNew ? - null : - - } -
-
- ); - } -} - -KeyValueListInputItem.propTypes = { - index: PropTypes.number, - keyValue: PropTypes.string.isRequired, - value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, - keyPlaceholder: PropTypes.string.isRequired, - valuePlaceholder: PropTypes.string.isRequired, - isNew: PropTypes.bool.isRequired, - onChange: PropTypes.func.isRequired, - onRemove: PropTypes.func.isRequired, - onFocus: PropTypes.func.isRequired, - onBlur: PropTypes.func.isRequired -}; - -KeyValueListInputItem.defaultProps = { - keyPlaceholder: 'Key', - valuePlaceholder: 'Value' -}; - -export default KeyValueListInputItem; diff --git a/frontend/src/Components/Form/KeyValueListInputItem.tsx b/frontend/src/Components/Form/KeyValueListInputItem.tsx new file mode 100644 index 0000000000..c63ad50a92 --- /dev/null +++ b/frontend/src/Components/Form/KeyValueListInputItem.tsx @@ -0,0 +1,89 @@ +import React, { useCallback } from 'react'; +import IconButton from 'Components/Link/IconButton'; +import { icons } from 'Helpers/Props'; +import TextInput from './TextInput'; +import styles from './KeyValueListInputItem.css'; + +interface KeyValueListInputItemProps { + index: number; + keyValue: string; + value: string; + keyPlaceholder?: string; + valuePlaceholder?: string; + isNew: boolean; + onChange: (index: number, itemValue: { key: string; value: string }) => void; + onRemove: (index: number) => void; + onFocus: () => void; + onBlur: () => void; +} + +function KeyValueListInputItem({ + index, + keyValue, + value, + keyPlaceholder = 'Key', + valuePlaceholder = 'Value', + isNew, + onChange, + onRemove, + onFocus, + onBlur, +}: KeyValueListInputItemProps): JSX.Element { + const handleKeyChange = useCallback( + ({ value: keyValue }: { value: string }) => { + onChange(index, { key: keyValue, value }); + }, + [index, value, onChange] + ); + + const handleValueChange = useCallback( + ({ value }: { value: string }) => { + onChange(index, { key: keyValue, value }); + }, + [index, keyValue, onChange] + ); + + const handleRemovePress = useCallback(() => { + onRemove(index); + }, [index, onRemove]); + + return ( +
+
+ +
+ +
+ +
+ +
+ {isNew ? null : ( + + )} +
+
+ ); +} + +export default KeyValueListInputItem; diff --git a/frontend/src/Components/Form/ProviderFieldFormGroup.js b/frontend/src/Components/Form/ProviderFieldFormGroup.js index 3f33490261..0cd23298e5 100644 --- a/frontend/src/Components/Form/ProviderFieldFormGroup.js +++ b/frontend/src/Components/Form/ProviderFieldFormGroup.js @@ -14,6 +14,8 @@ function getType({ type, selectOptionsProviderAction }) { return inputTypes.CHECK; case 'device': return inputTypes.DEVICE; + case 'keyValueList': + return inputTypes.KEY_VALUE_LIST; case 'password': return inputTypes.PASSWORD; case 'number': diff --git a/frontend/src/typings/inputs.ts b/frontend/src/typings/inputs.ts index cf91149b67..eb42e316d6 100644 --- a/frontend/src/typings/inputs.ts +++ b/frontend/src/typings/inputs.ts @@ -3,4 +3,6 @@ export type InputChanged = { value: T; }; +export type InputOnChange = (change: InputChanged) => void; + export type CheckInputChanged = InputChanged; diff --git a/src/NzbDrone.Common/Reflection/ReflectionExtensions.cs b/src/NzbDrone.Common/Reflection/ReflectionExtensions.cs index 12749df9ef..44c7d8cc52 100644 --- a/src/NzbDrone.Common/Reflection/ReflectionExtensions.cs +++ b/src/NzbDrone.Common/Reflection/ReflectionExtensions.cs @@ -34,7 +34,8 @@ public static bool IsSimpleType(this Type type) || type == typeof(string) || type == typeof(DateTime) || type == typeof(Version) - || type == typeof(decimal); + || type == typeof(decimal) + || (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(KeyValuePair<,>)); } public static bool IsReadable(this PropertyInfo propertyInfo) diff --git a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs index 413bbdb259..77cc677937 100644 --- a/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs +++ b/src/NzbDrone.Core/Annotations/FieldDefinitionAttribute.cs @@ -100,7 +100,8 @@ public enum FieldType TagSelect, RootFolder, QualityProfile, - MovieTag + MovieTag, + KeyValueList, } public enum HiddenType diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 5160649fe2..bc9a859f10 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1206,6 +1206,7 @@ "NotificationsSettingsWebhookMethod": "Method", "NotificationsSettingsWebhookMethodHelpText": "Which HTTP method to use submit to the Webservice", "NotificationsSettingsWebhookUrl": "Webhook URL", + "NotificationsSettingsWebhookHeaders": "Headers", "NotificationsSignalSettingsGroupIdPhoneNumber": "Group ID / Phone Number", "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "Group ID / Phone Number of the receiver", "NotificationsSignalSettingsPasswordHelpText": "Password used to authenticate requests toward signal-api", diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs index 23a7fbdc8c..a7a7025e73 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookProxy.cs @@ -43,6 +43,11 @@ public void SendWebhook(WebhookPayload body, WebhookSettings settings) request.Credentials = new BasicNetworkCredential(settings.Username, settings.Password); } + foreach (var header in settings.Headers) + { + request.Headers.Add(header.Key, header.Value); + } + _httpClient.Execute(request); } catch (HttpException ex) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs index 565f454e2c..51d91f7dbd 100644 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookSettings.cs @@ -1,4 +1,5 @@ -using System; +using System; +using System.Collections.Generic; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Validation; @@ -20,6 +21,7 @@ public class WebhookSettings : NotificationSettingsBase public WebhookSettings() { Method = Convert.ToInt32(WebhookMethod.POST); + Headers = new List>(); } [FieldDefinition(0, Label = "NotificationsSettingsWebhookUrl", Type = FieldType.Url)] @@ -34,6 +36,9 @@ public WebhookSettings() [FieldDefinition(3, Label = "Password", Type = FieldType.Password, Privacy = PrivacyLevel.Password)] public string Password { get; set; } + [FieldDefinition(4, Label = "NotificationsSettingsWebhookHeaders", Type = FieldType.KeyValueList, Advanced = true)] + public IEnumerable> Headers { get; set; } + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From 219477273675b23a426554896a145d553fc9a319 Mon Sep 17 00:00:00 2001 From: bpoxy Date: Wed, 27 Nov 2024 16:00:33 -0700 Subject: [PATCH 093/579] New: Add Albanian language (#10663) --- src/NzbDrone.Core.Test/Languages/LanguageFixture.cs | 6 ++++-- .../ParserTests/LanguageParserFixture.cs | 8 ++++++++ src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs | 4 +++- src/NzbDrone.Core/Languages/Language.cs | 2 ++ src/NzbDrone.Core/Parser/IsoLanguages.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 5 +++++ 6 files changed, 23 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs index 11d381383b..e160ac24dc 100644 --- a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs +++ b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs @@ -61,7 +61,8 @@ public class LanguageFixture : CoreTest new object[] { 46, Language.Macedonian }, new object[] { 47, Language.Slovenian }, new object[] { 48, Language.Malayalam }, - new object[] { 49, Language.Kannada } + new object[] { 49, Language.Kannada }, + new object[] { 50, Language.Albanian } }; public static object[] ToIntCases = @@ -117,7 +118,8 @@ public class LanguageFixture : CoreTest new object[] { Language.Macedonian, 46 }, new object[] { Language.Slovenian, 47 }, new object[] { Language.Malayalam, 48 }, - new object[] { Language.Kannada, 49 } + new object[] { Language.Kannada, 49 }, + new object[] { Language.Albanian, 50 } }; [Test] diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index e1f3dae236..79647690db 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -444,6 +444,14 @@ public void should_parse_language_kannada(string postTitle) result.Should().Contain(Language.Kannada); } + [TestCase("Movie Title (2024) Albanian 1080p HD AVC MP4 x264 .9.8GB TEAMTR")] + [TestCase("Movie.Title.2024.Albanian.1080p.AMZN.WEB-DL.DD+2.0.x264-Telly")] + public void should_parse_language_albanian(string postTitle) + { + var result = LanguageParser.ParseLanguages(postTitle); + result.Should().Contain(Language.Albanian); + } + [TestCase("Movie.Title.en.sub")] [TestCase("Movie Title.eng.sub")] [TestCase("Movie.Title.eng.forced.sub")] diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs index 596d1cf579..0072d2db6a 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs @@ -61,6 +61,8 @@ public enum TMDbLanguageCodes [FieldOption(Hint = "Malayalam")] ml, [FieldOption(Hint = "Kannada")] - kn + kn, + [FieldOption(Hint = "Albanian")] + sq } } diff --git a/src/NzbDrone.Core/Languages/Language.cs b/src/NzbDrone.Core/Languages/Language.cs index 9aa5d034df..3dc0592b0c 100644 --- a/src/NzbDrone.Core/Languages/Language.cs +++ b/src/NzbDrone.Core/Languages/Language.cs @@ -120,6 +120,7 @@ public override bool Equals(object obj) public static Language Slovenian => new Language(47, "Slovenian"); public static Language Malayalam => new Language(48, "Malayalam"); public static Language Kannada => new Language(49, "Kannada"); + public static Language Albanian => new Language(50, "Albanian"); public static Language Any => new Language(-1, "Any"); public static Language Original => new Language(-2, "Original"); @@ -179,6 +180,7 @@ public static List All Slovenian, Malayalam, Kannada, + Albanian, Any, Original }; diff --git a/src/NzbDrone.Core/Parser/IsoLanguages.cs b/src/NzbDrone.Core/Parser/IsoLanguages.cs index b16c3cb399..c9aa6b2806 100644 --- a/src/NzbDrone.Core/Parser/IsoLanguages.cs +++ b/src/NzbDrone.Core/Parser/IsoLanguages.cs @@ -59,6 +59,7 @@ public static class IsoLanguages new IsoLanguage("sl", "", "slv", "Slovenian", Language.Slovenian), new IsoLanguage("ml", "", "mal", "Malayalam", Language.Malayalam), new IsoLanguage("kn", "", "kan", "Kannada", Language.Kannada), + new IsoLanguage("sq", "", "sqi", "Albanian", Language.Albanian), }; private static readonly Dictionary AlternateIsoCodeMappings = new () diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 5fcf8acda8..a9de0dce10 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -229,6 +229,11 @@ public static List ParseLanguages(string title) languages.Add(Language.Kannada); } + if (lowerTitle.Contains("albanian")) + { + languages.Add(Language.Albanian); + } + // Case sensitive var caseSensitiveMatches = CaseSensitiveLanguageRegex.Matches(title); From 1526bf29f485859daf5fcde1872677f2cecc77da Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 30 Nov 2024 01:59:16 +0200 Subject: [PATCH 094/579] Fixed path in downloading to root folder check message --- .../HealthCheck/Checks/DownloadClientRootFolderCheck.cs | 2 +- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 4 ++-- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- src/NzbDrone.Core/Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- src/NzbDrone.Core/Localization/Core/zh_CN.json | 2 +- 31 files changed, 32 insertions(+), 32 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs index e06d28ec5d..15b727fdb4 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs @@ -54,7 +54,7 @@ public override HealthCheck Check() { return new HealthCheck(GetType(), HealthCheckResult.Warning, - _localizationService.GetLocalizedString("DownloadClientCheckDownloadingToRoot", new Dictionary + _localizationService.GetLocalizedString("DownloadClientRootFolderHealthCheckMessage", new Dictionary { { "downloadClientName", client.Definition.Name }, { "rootFolderPath", folder.FullPath } diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 472d980c34..3c399397b7 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -955,7 +955,7 @@ "Reddit": "رديت", "More": "أكثر", "Download": "تحميل", - "DownloadClientCheckDownloadingToRoot": "يقوم برنامج التنزيل {downloadClientName} بوضع التنزيلات في المجلد الجذر {path}. يجب ألا تقوم بالتنزيل إلى مجلد جذر.", + "DownloadClientRootFolderHealthCheckMessage": "يقوم برنامج التنزيل {downloadClientName} بوضع التنزيلات في المجلد الجذر {rootFolderPath}. يجب ألا تقوم بالتنزيل إلى مجلد جذر.", "Blocklist": "القائمة السوداء", "BlocklistRelease": "إصدار القائمة السوداء", "RemoveFromBlocklist": "إزالة من القائمة السوداء", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 96b3df42c3..16fbbe8087 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "| Повече ▼", "Download": "Изтегли", - "DownloadClientCheckDownloadingToRoot": "Клиентът за изтегляне {downloadClientName} поставя изтеглянията в основната папка {path}. Не трябва да изтегляте в основна папка.", + "DownloadClientRootFolderHealthCheckMessage": "Клиентът за изтегляне {downloadClientName} поставя изтеглянията в основната папка {rootFolderPath}. Не трябва да изтегляте в основна папка.", "Blocklist": "Черен списък", "BlocklistRelease": "Освобождаване на черния списък", "RemoveFromBlocklist": "Премахване от черния списък", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 48063bd17d..bcef7ab095 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -446,7 +446,7 @@ "DoneEditingGroups": "Acabada l'edició de grups", "DoNotPrefer": "No ho prefereixo", "DoNotUpgradeAutomatically": "No actualitzeu automàticament", - "DownloadClientCheckDownloadingToRoot": "El client de baixada {downloadClientName} col·loca les baixades a la carpeta arrel {path}. No s'hauria de baixar a una carpeta arrel.", + "DownloadClientRootFolderHealthCheckMessage": "El client de baixada {downloadClientName} col·loca les baixades a la carpeta arrel {rootFolderPath}. No s'hauria de baixar a una carpeta arrel.", "DownloadClientCheckUnableToCommunicateMessage": "No es pot comunicar amb {downloadClientName}. {errorMessage}", "DownloadClientsSettingsSummary": "Descàrrega de clients, gestió de descàrregues i mapes de camins remots", "Downloaded": "S'ha baixat", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 801aaed2d4..015859e299 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Více", "Download": "Stažení", - "DownloadClientCheckDownloadingToRoot": "Stahovací klient {downloadClientName} umístí stažené soubory do kořenové složky {path}. Neměli byste stahovat do kořenové složky.", + "DownloadClientRootFolderHealthCheckMessage": "Stahovací klient {downloadClientName} umístí stažené soubory do kořenové složky {rootFolderPath}. Neměli byste stahovat do kořenové složky.", "Blocklist": "Blocklist", "BlocklistRelease": "Blocklist pro vydání", "RemoveFromBlocklist": "Odebrat z černé listiny", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index d41b69f2d0..58d225e76a 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Mere", "Download": "Hent", - "DownloadClientCheckDownloadingToRoot": "Download klient {downloadClientName} placerer downloads i rodmappen {path}. Du skal ikke downloade til en rodmappe.", + "DownloadClientRootFolderHealthCheckMessage": "Download klient {downloadClientName} placerer downloads i rodmappen {rootFolderPath}. Du skal ikke downloade til en rodmappe.", "Blocklist": "Blacklist", "BlocklistRelease": "Udgivelse af sortliste", "RemoveFromBlocklist": "Fjern fra sortlisten", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 603e2893c5..ab0b451604 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -944,7 +944,7 @@ "Reddit": "Reddit", "More": "Mehr", "Download": "Herunterladen", - "DownloadClientCheckDownloadingToRoot": "Download-Client {downloadClientName} legt Downloads im Stammordner {path} ab. Sie sollten nicht in einen Stammordner herunterladen.", + "DownloadClientRootFolderHealthCheckMessage": "Download-Client {downloadClientName} legt Downloads im Stammordner {rootFolderPath} ab. Sie sollten nicht in einen Stammordner herunterladen.", "UpdateAvailableHealthCheckMessage": "Neue Version verfügbar", "RemotePathMappingCheckFilesLocalWrongOSPath": "Downloader {downloadClientName} meldet Dateien in {path}, aber dies ist kein valider {osName} Pfad. Überprüfe die Downloader Einstellungen.", "RemotePathMappingCheckFilesBadDockerPath": "Docker erkannt; Downloader {downloadClientName} meldet Dateien in {path}, aber dies ist kein valider {osName} Pfad. Überprüfe deine Remote-Pfadzuordnungen und die Downloader Einstellungen.", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index f511e83139..3b0b6fecc3 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Περισσότερο", "Download": "Κατεβάστε", - "DownloadClientCheckDownloadingToRoot": "Λήψη προγράμματος-πελάτη {downloadClientName} τοποθετεί λήψεις στον ριζικό φάκελο {path}. Δεν πρέπει να κάνετε λήψη σε έναν ριζικό φάκελο.", + "DownloadClientRootFolderHealthCheckMessage": "Λήψη προγράμματος-πελάτη {downloadClientName} τοποθετεί λήψεις στον ριζικό φάκελο {rootFolderPath}. Δεν πρέπει να κάνετε λήψη σε έναν ριζικό φάκελο.", "Blocklist": "Αποριφθέντα", "BlocklistRelease": "Έκδοση μαύρης λίστας", "RemoveFromBlocklist": "Κατάργηση από μαύρη λίστα", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index bc9a859f10..1702ec0e92 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -397,7 +397,6 @@ "Download": "Download", "DownloadClient": "Download Client", "DownloadClientAriaSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Aria2 location", - "DownloadClientCheckDownloadingToRoot": "Download client {downloadClientName} places downloads in the root folder {path}. You should not download to a root folder.", "DownloadClientCheckNoneAvailableMessage": "No download client is available", "DownloadClientCheckUnableToCommunicateMessage": "Unable to communicate with {downloadClientName}. {errorMessage}", "DownloadClientDelugeSettingsDirectory": "Download Directory", @@ -486,6 +485,7 @@ "DownloadClientRTorrentSettingsUrlPath": "Url Path", "DownloadClientRTorrentSettingsUrlPathHelpText": "Path to the XMLRPC endpoint, see {url}. This is usually RPC2 or [path to ruTorrent]{url2} when using ruTorrent.", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Download client {downloadClientName} is set to remove completed downloads. This can result in downloads being removed from your client before {appName} can import them.", + "DownloadClientRootFolderHealthCheckMessage": "Download client {downloadClientName} places downloads in the root folder {rootFolderPath}. You should not download to a root folder.", "DownloadClientSabnzbdValidationCheckBeforeDownload": "Disable 'Check before download' option in Sabnbzd", "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Using 'Check before download' affects {appName} ability to track new downloads. Also Sabnzbd recommends 'Abort jobs that cannot be completed' instead since it's more effective.", "DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd develop version, assuming version 3.0.0 or higher.", @@ -1203,10 +1203,10 @@ "NotificationsSettingsUpdateMapPathsTo": "Map Paths To", "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName} path, used to modify movie paths when {serviceName} sees library path location differently from {appName} (Requires 'Update Library')", "NotificationsSettingsUseSslHelpText": "Connect to {serviceName} over HTTPS instead of HTTP", + "NotificationsSettingsWebhookHeaders": "Headers", "NotificationsSettingsWebhookMethod": "Method", "NotificationsSettingsWebhookMethodHelpText": "Which HTTP method to use submit to the Webservice", "NotificationsSettingsWebhookUrl": "Webhook URL", - "NotificationsSettingsWebhookHeaders": "Headers", "NotificationsSignalSettingsGroupIdPhoneNumber": "Group ID / Phone Number", "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "Group ID / Phone Number of the receiver", "NotificationsSignalSettingsPasswordHelpText": "Password used to authenticate requests toward signal-api", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index e127824417..221e6750d0 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -947,7 +947,7 @@ "Reddit": "Reddit", "More": "Más", "Download": "Descargar", - "DownloadClientCheckDownloadingToRoot": "El cliente de descarga {downloadClientName} coloca las descargas en la carpeta raíz {path}. No deberías descargar a una carpeta raíz.", + "DownloadClientRootFolderHealthCheckMessage": "El cliente de descarga {downloadClientName} coloca las descargas en la carpeta raíz {rootFolderPath}. No deberías descargar a una carpeta raíz.", "ImportListMultipleMissingRoots": "Faltan varias carpetas raíz de las listas de importación: {rootFoldersInfo}", "ImportListMissingRoot": "Falta la capeta raíz de la(s) lista(s) de importación: {rootFolderInfo}", "From": "de", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 017924ae48..1c7a220970 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -953,7 +953,7 @@ "Reddit": "Reddit", "More": "Lisää", "Download": "Lataa", - "DownloadClientCheckDownloadingToRoot": "Lataustyökalu \"{downloadClientName}\" tallentaa lataukset juurikansioon \"{path}\", mutta ne tulisi tallentaa muualle.", + "DownloadClientRootFolderHealthCheckMessage": "Lataustyökalu \"{downloadClientName}\" tallentaa lataukset juurikansioon \"{rootFolderPath}\", mutta ne tulisi tallentaa muualle.", "Blocklist": "Estolista", "BlocklistRelease": "Lisää julkaisu estolistalle", "RemoveFromBlocklist": "Poista estolistalta", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index f64685b827..0be9cd5c42 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -955,7 +955,7 @@ "Reddit": "Reddit", "More": "Plus", "Download": "Téléchargement", - "DownloadClientCheckDownloadingToRoot": "Le client de téléchargement {downloadClientName} place les téléchargements dans le dossier racine {path}. Vous ne devez pas télécharger dans un dossier racine.", + "DownloadClientRootFolderHealthCheckMessage": "Le client de téléchargement {downloadClientName} place les téléchargements dans le dossier racine {rootFolderPath}. Vous ne devez pas télécharger dans un dossier racine.", "NotificationTriggersHelpText": "Sélectionnez les événements qui doivent déclencher cette notification", "From": "de", "UpdateAvailableHealthCheckMessage": "Une nouvelle mise à jour est disponible : {version}", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 62dfe3bfe3..6213550bd2 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -954,7 +954,7 @@ "Reddit": "רדיט", "More": "יותר", "Download": "הורד", - "DownloadClientCheckDownloadingToRoot": "הורד לקוח {downloadClientName} ממקם הורדות בתיקיית הבסיס {path}. אתה לא צריך להוריד לתיקיית שורש.", + "DownloadClientRootFolderHealthCheckMessage": "הורד לקוח {downloadClientName} ממקם הורדות בתיקיית הבסיס {rootFolderPath}. אתה לא צריך להוריד לתיקיית שורש.", "Blocklist": "רשימה שחורה", "BlocklistRelease": "שחרור הרשימה השחורה", "RemoveFromBlocklist": "הסר מהרשימה השחורה", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 0630a4b99d..e6390f39be 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -954,7 +954,7 @@ "Reddit": "reddit", "More": "अधिक", "Download": "डाउनलोड", - "DownloadClientCheckDownloadingToRoot": "डाउनलोड क्लाइंट {downloadClientName} रूट फ़ोल्डर में डाउनलोड करता है {path}। आपको रूट फ़ोल्डर में डाउनलोड नहीं करना चाहिए।", + "DownloadClientRootFolderHealthCheckMessage": "डाउनलोड क्लाइंट {downloadClientName} रूट फ़ोल्डर में डाउनलोड करता है {rootFolderPath}। आपको रूट फ़ोल्डर में डाउनलोड नहीं करना चाहिए।", "Blocklist": "काला सूची में डालना", "BlocklistRelease": "ब्लैकलिस्ट रिलीज़", "RemoveFromBlocklist": "ब्लैकलिस्ट से निकालें", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 77eca052be..8a154c57ea 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Több", "Download": "Letöltés", - "DownloadClientCheckDownloadingToRoot": "A Letöltőkliens {downloadClientName} a letöltéseket a gyökérmappába helyezi {path}. Nem szabad letölteni egy gyökérmappába.", + "DownloadClientRootFolderHealthCheckMessage": "A Letöltőkliens {downloadClientName} a letöltéseket a gyökérmappába helyezi {rootFolderPath}. Nem szabad letölteni egy gyökérmappába.", "UpdateAvailableHealthCheckMessage": "Új frissítés elérhető", "RemotePathMappingCheckFilesGenericPermissions": "A letöltőkliens {downloadClientName} jelentett fájljait a(z) {path} fájlba, de a {appName} nem látja ezt a könyvtárat. Lehet, hogy módosítania kell a mappa engedélyeit.", "RemotePathMappingCheckRemoteDownloadClient": "A távoli letöltőkliens {downloadClientName} fájlokat jelentett a(z) {path} fájlban, de úgy tűnik, hogy ez a könyvtár nem létezik. Valószínűleg hiányzik a távoli útvonal-hozzárendelés.", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index e91be34650..e9e7dbf8ba 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Meira", "Download": "Sækja", - "DownloadClientCheckDownloadingToRoot": "Sæktu viðskiptavinur {downloadClientName} setur niðurhal í rótarmöppuna {path}. Þú ættir ekki að hlaða niður í rótarmöppu.", + "DownloadClientRootFolderHealthCheckMessage": "Sæktu viðskiptavinur {downloadClientName} setur niðurhal í rótarmöppuna {rootFolderPath}. Þú ættir ekki að hlaða niður í rótarmöppu.", "Blocklist": "Svartur listi", "BlocklistRelease": "Útgáfa svartalista", "RemoveFromBlocklist": "Fjarlægja af svörtum lista", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index afd9005429..b3862372c4 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -952,7 +952,7 @@ "Reddit": "Reddit", "More": "Altro", "Download": "Scarica", - "DownloadClientCheckDownloadingToRoot": "Il client di download {downloadClientName} colloca i download nella cartella radice {path}. Non dovresti scaricare in una cartella radice.", + "DownloadClientRootFolderHealthCheckMessage": "Il client di download {downloadClientName} colloca i download nella cartella radice {rootFolderPath}. Non dovresti scaricare in una cartella radice.", "Blocklist": "Lista dei Blocchi", "BlocklistRelease": "Release in Lista dei Blocchi", "RemoveFromBlocklist": "Rimuovi della blacklist", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index ffaef99690..6350e2c8bb 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "もっと", "Download": "ダウンロード", - "DownloadClientCheckDownloadingToRoot": "ダウンロードクライアント{downloadClientName}は、ダウンロードをルートフォルダ{path}に配置します。ルートフォルダにダウンロードしないでください。", + "DownloadClientRootFolderHealthCheckMessage": "ダウンロードクライアント{downloadClientName}は、ダウンロードをルートフォルダ{rootFolderPath}に配置します。ルートフォルダにダウンロードしないでください。", "Blocklist": "ブラックリスト", "BlocklistRelease": "ブラックリストリリース", "RemoveFromBlocklist": "ブラックリストから削除する", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 5c0809ab34..b4047391e6 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -954,7 +954,7 @@ "Reddit": "레딧", "More": "더보기", "Download": "다운로드", - "DownloadClientCheckDownloadingToRoot": "다운로드 클라이언트 {downloadClientName} 은(는) 루트 폴더 {path}에 다운로드를 저장합니다. 루트 폴더에 다운로드해서는 안됩니다.", + "DownloadClientRootFolderHealthCheckMessage": "다운로드 클라이언트 {downloadClientName} 은(는) 루트 폴더 {rootFolderPath}에 다운로드를 저장합니다. 루트 폴더에 다운로드해서는 안됩니다.", "Blocklist": "블랙리스트", "BlocklistRelease": "블랙리스트 릴리스", "RemoveFromBlocklist": "블랙리스트에서 제거", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 69220fb649..d3756026dd 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -955,7 +955,7 @@ "Reddit": "Reddit", "More": "Meer", "Download": "Downloaden", - "DownloadClientCheckDownloadingToRoot": "Downloadclient {downloadClientName} plaatst downloads in de hoofdmap {path}. U mag niet naar een hoofdmap downloaden.", + "DownloadClientRootFolderHealthCheckMessage": "Downloadclient {downloadClientName} plaatst downloads in de hoofdmap {rootFolderPath}. U mag niet naar een hoofdmap downloaden.", "UpdateAvailableHealthCheckMessage": "Nieuwe update is beschikbaar", "From": "van", "RemotePathMappingCheckDownloadPermissions": "{appName} kan gedownloade film {path} zien, maar niet openen. Waarschijnlijk fout met machtigingen.", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index a004690d37..7aa5c26dd2 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -953,7 +953,7 @@ "Reddit": "Reddit", "More": "Jeszcze", "Download": "Ściągnij", - "DownloadClientCheckDownloadingToRoot": "Klient pobierania {downloadClientName} umieszcza pliki do pobrania w folderze głównym {path}. Nie należy pobierać do folderu głównego.", + "DownloadClientRootFolderHealthCheckMessage": "Klient pobierania {downloadClientName} umieszcza pliki do pobrania w folderze głównym {rootFolderPath}. Nie należy pobierać do folderu głównego.", "Blocklist": "Czarna lista", "BlocklistRelease": "Dodaj wersję do czarnej listy", "RemoveFromBlocklist": "Usuń z czarnej listy", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 487496da1a..dd4119738e 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -955,7 +955,7 @@ "Reddit": "Reddit", "More": "Mais", "Download": "Transferência", - "DownloadClientCheckDownloadingToRoot": "O cliente {downloadClientName} coloca as transferências na pasta raiz {path}. Não transfira para a pasta raiz.", + "DownloadClientRootFolderHealthCheckMessage": "O cliente {downloadClientName} coloca as transferências na pasta raiz {rootFolderPath}. Não transfira para a pasta raiz.", "UpdateAvailableHealthCheckMessage": "Nova atualização disponível", "TaskUserAgentTooltip": "Par Utilizador-Agente fornecido pela aplicação que chamou a API", "RemotePathMappingCheckWrongOSPath": "O cliente remoto {downloadClientName} coloca as transferências em {path}, mas esse não é um caminho {osName} válido. Revise os mapeamentos de caminho remoto e as definições do cliente de transferências.", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index fea5af8688..d6da3b787d 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -955,7 +955,7 @@ "Reddit": "Reddit", "More": "Mais", "Download": "Baixar", - "DownloadClientCheckDownloadingToRoot": "O cliente de download {downloadClientName} coloca os downloads na pasta raiz {path}. Você não deve baixar para uma pasta raiz.", + "DownloadClientRootFolderHealthCheckMessage": "O cliente de download {downloadClientName} coloca os downloads na pasta raiz {rootFolderPath}. Você não deve baixar para uma pasta raiz.", "UpdateAvailableHealthCheckMessage": "Nova atualização está disponível: {version}", "RemotePathMappingCheckFilesGenericPermissions": "O cliente de download {downloadClientName} relatou arquivos em {path}, mas o {appName} não pode ver esse diretório. Pode ser necessário ajustar as permissões da pasta.", "RemotePathMappingCheckRemoteDownloadClient": "O cliente de download remoto {downloadClientName} relatou arquivos em {path}, mas este diretório parece não existir. Provavelmente faltando mapeamento de caminho remoto.", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 14823cd417..135b50b55f 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -955,7 +955,7 @@ "Reddit": "Reddit", "More": "Mai mult", "Download": "Descarca", - "DownloadClientCheckDownloadingToRoot": "Clientul de descărcare {downloadClientName} plasează descărcările în folderul rădăcină {path}. Nu trebuie să descărcați într-un folder rădăcină.", + "DownloadClientRootFolderHealthCheckMessage": "Clientul de descărcare {downloadClientName} plasează descărcările în folderul rădăcină {rootFolderPath}. Nu trebuie să descărcați într-un folder rădăcină.", "Blocklist": "Listă Neagră", "BlocklistRelease": "Lansare pe lista neagră", "RemoveFromBlocklist": "Eliminați de pe lista neagră", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 189c2fa4ad..636d2b0e9a 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Ещё", "Download": "Загрузить", - "DownloadClientCheckDownloadingToRoot": "Клиент загрузки {downloadClientName} помещает загрузки в корневую папку {path}. Вы не должны загружать в корневую папку.", + "DownloadClientRootFolderHealthCheckMessage": "Клиент загрузки {downloadClientName} помещает загрузки в корневую папку {rootFolderPath}. Вы не должны загружать в корневую папку.", "RemotePathMappingCheckWrongOSPath": "Удалённый клиент загрузки {downloadClientName} загружает файлы в {path}, но это не действительный путь {osName}. Проверьте соответствие удаленных путей и настройки клиента загрузки.", "RemotePathMappingCheckRemoteDownloadClient": "Удалённый клиент загрузки {downloadClientName} сообщил о файлах в {path}, но эта директория, похоже, не существует. Вероятно, отсутствует сопоставление удаленных путей.", "RemotePathMappingCheckLocalWrongOSPath": "Локальный клиент загрузки {downloadClientName} загружает файлы в {path}, но это не правильный путь {osName}. Проверьте настройки клиента загрузки.", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 1c67fcbea5..b8910cb3c1 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Mer", "Download": "Ladda ner", - "DownloadClientCheckDownloadingToRoot": "Ladda ner klient {downloadClientName} placerar nedladdningar i rotmappen {path}. Du bör inte ladda ner till en rotmapp.", + "DownloadClientRootFolderHealthCheckMessage": "Ladda ner klient {downloadClientName} placerar nedladdningar i rotmappen {rootFolderPath}. Du bör inte ladda ner till en rotmapp.", "Blocklist": "Svartlista", "BlocklistRelease": "Svartlista utgåva", "RemoveFromBlocklist": "Ta bort från svartlistan", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 120a49104f..3e3fece121 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "มากกว่า", "Download": "ดาวน์โหลด", - "DownloadClientCheckDownloadingToRoot": "ดาวน์โหลดไคลเอนต์ {downloadClientName} จะทำการดาวน์โหลดในโฟลเดอร์รูท {path} คุณไม่ควรดาวน์โหลดไปยังโฟลเดอร์รูท", + "DownloadClientRootFolderHealthCheckMessage": "ดาวน์โหลดไคลเอนต์ {downloadClientName} จะทำการดาวน์โหลดในโฟลเดอร์รูท {rootFolderPath} คุณไม่ควรดาวน์โหลดไปยังโฟลเดอร์รูท", "Blocklist": "บัญชีดำ", "BlocklistRelease": "Blacklist Release", "RemoveFromBlocklist": "ลบออกจากบัญชีดำ", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 68c38e8b68..f885857dc0 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Daha", "Download": "İndir", - "DownloadClientCheckDownloadingToRoot": "İndirme istemcisi {downloadClientName}, indirmeleri kök klasöre yerleştirir {path}. Bir kök klasöre indirmemelisiniz.", + "DownloadClientRootFolderHealthCheckMessage": "İndirme istemcisi {downloadClientName}, indirmeleri kök klasöre yerleştirir {rootFolderPath}. Bir kök klasöre indirmemelisiniz.", "Blocklist": "Kara liste", "BlocklistRelease": "Kara Liste Sürümü", "RemoveFromBlocklist": "Kara listeden kaldır", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index ed26e9c589..4b607976f8 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -955,7 +955,7 @@ "Test": "Тест", "TorrentsDisabled": "Торренти вимкнено", "TotalFileSize": "Загальний розмір файлу", - "DownloadClientCheckDownloadingToRoot": "Клієнт завантаження {downloadClientName} розміщує завантаження в кореневій папці {path}. Ви не повинні завантажувати в кореневу папку.", + "DownloadClientRootFolderHealthCheckMessage": "Клієнт завантаження {downloadClientName} розміщує завантаження в кореневій папці {rootFolderPath}. Ви не повинні завантажувати в кореневу папку.", "DigitalRelease": "Цифровий випуск", "Disabled": "Вимкнено", "DeleteEmptyFoldersHelpText": "Видаляти порожні папки фільмів під час сканування диска та під час видалення файлів фільмів", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index a43a92e367..d2dccc574c 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -954,7 +954,7 @@ "Reddit": "Reddit", "More": "Hơn", "Download": "Tải xuống", - "DownloadClientCheckDownloadingToRoot": "Tải xuống ứng dụng khách {downloadClientName} đặt các bản tải xuống trong thư mục gốc {path}. Bạn không nên tải xuống thư mục gốc.", + "DownloadClientRootFolderHealthCheckMessage": "Tải xuống ứng dụng khách {downloadClientName} đặt các bản tải xuống trong thư mục gốc {rootFolderPath}. Bạn không nên tải xuống thư mục gốc.", "Blocklist": "Danh sách chặn", "BlocklistRelease": "Chặn bản phát hành", "RemoveFromBlocklist": "Xóa khỏi danh sách đen", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 8e64c6c95e..18851d0a5e 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -953,7 +953,7 @@ "Reddit": "Reddit", "More": "更多", "Download": "下载", - "DownloadClientCheckDownloadingToRoot": "下载客户端{downloadClientName}将下载内容放在根文件夹{path}中。您不应该下载到根文件夹。", + "DownloadClientRootFolderHealthCheckMessage": "下载客户端{downloadClientName}将下载内容放在根文件夹{rootFolderPath}中。您不应该下载到根文件夹。", "ImportListMultipleMissingRoots": "导入列表中缺失多个根目录:{rootFoldersInfo}", "ImportListMissingRoot": "导入列表中缺失根目录: {rootFolderInfo}", "BypassDelayIfHighestQuality": "如果达到最高质量,则跳过", From a626b4f3c426770c1cf361a92d7b576b04e081d9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 30 Nov 2024 02:01:14 +0200 Subject: [PATCH 095/579] Fixed: Custom Format upgrading not respecting 'Upgrades Allowed' (cherry picked from commit 91c5e6f12292e522ceb9094825525fb3684b97c6) Closes #10691 --- .../UpgradeDiskSpecificationFixture.cs | 34 +++++++++++++++++++ .../Specifications/UpgradableSpecification.cs | 4 ++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index c261575769..458299be73 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -11,6 +11,7 @@ using NzbDrone.Core.Movies; using NzbDrone.Core.Parser; using NzbDrone.Core.Parser.Model; +using NzbDrone.Core.Profiles; using NzbDrone.Core.Profiles.Qualities; using NzbDrone.Core.Qualities; using NzbDrone.Core.Test.CustomFormats; @@ -303,5 +304,38 @@ public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_c Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } + + [Test] + public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_format_cutoff_is_above_current_score() + { + var customFormat = new CustomFormat("My Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 1 }; + + GivenProfile(new QualityProfile + { + Cutoff = Quality.SDTV.Id, + MinFormatScore = 0, + CutoffFormatScore = 10000, + Items = Qualities.QualityFixture.GetDefaultQualities(), + FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("My Format"), + UpgradeAllowed = false + }); + + _parseResultSingle.Series.QualityProfile.Value.FormatItems = new List + { + new ProfileFormatItem + { + Format = customFormat, + Score = 50 + } + }; + + GivenFileQuality(new QualityModel(Quality.WEBDL1080p)); + GivenNewQuality(new QualityModel(Quality.WEBDL1080p)); + + GivenOldCustomFormats(new List()); + GivenNewCustomFormats(new List { customFormat }); + + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index 79769b4ceb..157848517a 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -135,7 +135,9 @@ public bool QualityCutoffNotMet(QualityProfile profile, QualityModel currentQual private bool CustomFormatCutoffNotMet(QualityProfile profile, List currentFormats) { var score = profile.CalculateCustomFormatScore(currentFormats); - return score < profile.CutoffFormatScore; + var cutoff = profile.UpgradeAllowed ? profile.CutoffFormatScore : profile.MinFormatScore; + + return score < cutoff; } public bool CutoffNotMet(QualityProfile profile, QualityModel currentQuality, List currentFormats, QualityModel newQuality = null) From 2607c679123f4105f592d4a2232b6007d9b3f507 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 18 Nov 2024 16:51:28 -0800 Subject: [PATCH 096/579] Fixed: Prevent lack of internet from stopping all health checks from running (cherry picked from commit dba3a8243988d3e9870b841696303191e1703a0d) Closes #10694 --- .../HealthCheck/Checks/SystemTimeCheck.cs | 33 +++++++++++-------- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 2 +- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 2 +- 31 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/SystemTimeCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/SystemTimeCheck.cs index 6bdc96142e..b31a4adc70 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/SystemTimeCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/SystemTimeCheck.cs @@ -13,7 +13,7 @@ public class SystemTimeCheck : HealthCheckBase private readonly IHttpRequestBuilderFactory _cloudRequestBuilder; private readonly Logger _logger; - public SystemTimeCheck(IHttpClient client, IRadarrCloudRequestBuilder cloudRequestBuilder, ILocalizationService localizationService, Logger logger) + public SystemTimeCheck(IHttpClient client, IRadarrCloudRequestBuilder cloudRequestBuilder, Logger logger, ILocalizationService localizationService) : base(localizationService) { _client = client; @@ -23,19 +23,26 @@ public SystemTimeCheck(IHttpClient client, IRadarrCloudRequestBuilder cloudReque public override HealthCheck Check() { - var request = _cloudRequestBuilder.Create() - .Resource("/time") - .Build(); - - var response = _client.Execute(request); - var result = Json.Deserialize(response.Content); - var systemTime = DateTime.UtcNow; - - // +/- more than 1 day - if (Math.Abs(result.DateTimeUtc.Subtract(systemTime).TotalDays) >= 1) + try { - _logger.Error("System time mismatch. SystemTime: {0} Expected Time: {1}. Update system time", systemTime, result.DateTimeUtc); - return new HealthCheck(GetType(), HealthCheckResult.Error, _localizationService.GetLocalizedString("SystemTimeCheckMessage"), "#system-time-off"); + var request = _cloudRequestBuilder.Create() + .Resource("/time") + .Build(); + + var response = _client.Execute(request); + var result = Json.Deserialize(response.Content); + var systemTime = DateTime.UtcNow; + + // +/- more than 1 day + if (Math.Abs(result.DateTimeUtc.Subtract(systemTime).TotalDays) >= 1) + { + _logger.Error("System time mismatch. SystemTime: {0} Expected Time: {1}. Update system time", systemTime, result.DateTimeUtc); + return new HealthCheck(GetType(), HealthCheckResult.Error, _localizationService.GetLocalizedString("SystemTimeHealthCheckMessage"), "#system-time-off"); + } + } + catch (Exception e) + { + _logger.Warn(e, "Unable to verify system time"); } return new HealthCheck(GetType()); diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 3c399397b7..66253916e4 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -491,7 +491,7 @@ "TableOptionsColumnsMessage": "اختر الأعمدة المرئية والترتيب الذي تظهر به", "TableOptions": "خيارات الجدول", "Table": "الطاولة", - "SystemTimeCheckMessage": "توقف وقت النظام بأكثر من يوم واحد. قد لا تعمل المهام المجدولة بشكل صحيح حتى يتم تصحيح الوقت", + "SystemTimeHealthCheckMessage": "توقف وقت النظام بأكثر من يوم واحد. قد لا تعمل المهام المجدولة بشكل صحيح حتى يتم تصحيح الوقت", "System": "النظام", "Sunday": "الأحد", "SuggestTranslationChange": "اقترح تغيير الترجمة", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 16fbbe8087..eaac7645dd 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -923,7 +923,7 @@ "FileBrowserPlaceholderText": "Започнете да пишете или изберете път отдолу", "StartupDirectory": "Стартова директория", "System": "Система", - "SystemTimeCheckMessage": "Системното време е изключено с повече от 1 ден. Планираните задачи може да не се изпълняват правилно, докато времето не бъде коригирано", + "SystemTimeHealthCheckMessage": "Системното време е изключено с повече от 1 ден. Планираните задачи може да не се изпълняват правилно, докато времето не бъде коригирано", "TagCannotBeDeletedWhileInUse": "Не може да се изтрие, докато се използва", "TotalFileSize": "Общ размер на файла", "Backup": "Архивиране", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index bcef7ab095..1cce9a1a15 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -221,7 +221,7 @@ "RssSync": "Sincronització RSS", "ListEnabledHelpText": "Habiliteu aquesta llista per a utilitzar-la a {appName}", "Error": "Error", - "SystemTimeCheckMessage": "L'hora del sistema està apagada durant més d'1 dia. És possible que les tasques programades no s'executin correctament fins que no es corregeixi l'hora", + "SystemTimeHealthCheckMessage": "L'hora del sistema està apagada durant més d'1 dia. És possible que les tasques programades no s'executin correctament fins que no es corregeixi l'hora", "SupportedIndexersMoreInfo": "Per a obtenir més informació sobre els indexadors individuals, feu clic als botons d'informació.", "GeneralSettingsSummary": "Port, SSL, nom d'usuari/contrasenya, servidor intermediari, analítiques i actualitzacions", "Genres": "Gèneres", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 015859e299..50fb0b2ce5 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -442,7 +442,7 @@ "FileBrowserPlaceholderText": "Začněte psát nebo vyberte cestu níže", "StartupDirectory": "Spouštěcí adresář", "System": "Systém", - "SystemTimeCheckMessage": "Systémový čas je vypnutý o více než 1 den. Naplánované úlohy nemusí fungovat správně, dokud nebude čas opraven", + "SystemTimeHealthCheckMessage": "Systémový čas je vypnutý o více než 1 den. Naplánované úlohy nemusí fungovat správně, dokud nebude čas opraven", "Posters": "Plakáty", "PosterSize": "Velikost plakátu", "TagCannotBeDeletedWhileInUse": "Během používání nelze smazat", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 58d225e76a..e5269bd7bc 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -436,7 +436,7 @@ "MustNotContain": "Må ikke indeholde", "NamingSettings": "Navngivningsindstillinger", "NegateHelpText": "Hvis dette er markeret, gælder det tilpassede format ikke, hvis denne {0} betingelse stemmer overens.", - "SystemTimeCheckMessage": "Systemtiden er slukket mere end 1 dag. Planlagte opgaver kører muligvis ikke korrekt, før tiden er rettet", + "SystemTimeHealthCheckMessage": "Systemtiden er slukket mere end 1 dag. Planlagte opgaver kører muligvis ikke korrekt, før tiden er rettet", "Posters": "Plakater", "PosterSize": "Plakatstørrelse", "TimeFormat": "Tidsformat", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index ab0b451604..9af5e9beb2 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -246,7 +246,7 @@ "AllMoviesHiddenDueToFilter": "Alle Filme sind wegen dem Filter ausgeblendet.", "Age": "Alter", "AddNewMovie": "Neuen Film hinzufügen", - "SystemTimeCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", + "SystemTimeHealthCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", "UnsavedChanges": "Nicht gespeicherte Änderungen", "Table": "Tabelle", "ShowTitle": "Titel anzeigen", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 3b0b6fecc3..d51eaa8937 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -431,7 +431,7 @@ "FileBrowserPlaceholderText": "Ξεκινήστε να πληκτρολογείτε ή επιλέξτε μια διαδρομή παρακάτω", "StartupDirectory": "Κατάλογος εκκίνησης", "System": "Σύστημα", - "SystemTimeCheckMessage": "Ο χρόνος συστήματος είναι απενεργοποιημένος για περισσότερο από 1 ημέρα. Οι προγραμματισμένες εργασίες ενδέχεται να μην εκτελούνται σωστά έως ότου διορθωθεί η ώρα", + "SystemTimeHealthCheckMessage": "Ο χρόνος συστήματος είναι απενεργοποιημένος για περισσότερο από 1 ημέρα. Οι προγραμματισμένες εργασίες ενδέχεται να μην εκτελούνται σωστά έως ότου διορθωθεί η ώρα", "Posters": "Αφίσες", "PosterSize": "Μέγεθος αφίσας", "TagCannotBeDeletedWhileInUse": "Δεν είναι δυνατή η διαγραφή κατά τη χρήση", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 1702ec0e92..6732f48284 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1702,7 +1702,7 @@ "SupportedListsMoreInfo": "For more information on the individual import lists, click on the info buttons.", "SupportedListsMovie": "{appName} supports any RSS movie lists as well as the one stated below.", "System": "System", - "SystemTimeCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected", + "SystemTimeHealthCheckMessage": "System time is off by more than 1 day. Scheduled tasks may not run correctly until the time is corrected", "TMDBId": "TMDb Id", "TMDb": "TMDb", "Table": "Table", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 221e6750d0..9ba527fbf7 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -247,7 +247,7 @@ "AllMoviesHiddenDueToFilter": "Todas las películas están ocultas debido al filtro aplicado.", "Age": "Antigüedad", "AddNewMovie": "Añadir película nueva", - "SystemTimeCheckMessage": "El reloj del sistema está retrasado más de un día. Las tareas de mantenimiento no se ejecutarán correctamente hasta que se haya corregido", + "SystemTimeHealthCheckMessage": "El reloj del sistema está retrasado más de un día. Las tareas de mantenimiento no se ejecutarán correctamente hasta que se haya corregido", "MonitorMovie": "Monitorizar Película", "ExistingMovies": "Película(s) Existente(s)", "EditRemotePathMapping": "Editar mapeo de ruta remota", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 1c7a220970..6d3897c77b 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -393,7 +393,7 @@ "FileBrowserPlaceholderText": "Aloita kirjoitus tai valitse sijainti alta", "StartupDirectory": "Käynnistyskansio", "System": "Järjestelmä", - "SystemTimeCheckMessage": "Järjestelmän ajassa on ainakin vuorokauden heitto eivätkä ajoitetut tehtävät tämän vuoksi toimi oikein ennen kuin se on korjattu.", + "SystemTimeHealthCheckMessage": "Järjestelmän ajassa on ainakin vuorokauden heitto eivätkä ajoitetut tehtävät tämän vuoksi toimi oikein ennen kuin se on korjattu.", "Posters": "Julisteet", "PosterSize": "Julisteiden koko", "TagCannotBeDeletedWhileInUse": "Tunnistetta ei voi poistaa, koska se on käytössä", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 0be9cd5c42..195acebd0a 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -249,7 +249,7 @@ "HardlinkCopyFiles": "Lien physique/Copie de fichiers", "Extension": "Extension", "CustomFormatScore": "Score du format personnalisé", - "SystemTimeCheckMessage": "L'heure du système est décalée de plus d'un jour. Les tâches planifiées peuvent ne pas s'exécuter correctement tant que l'heure ne sera pas corrigée", + "SystemTimeHealthCheckMessage": "L'heure du système est décalée de plus d'un jour. Les tâches planifiées peuvent ne pas s'exécuter correctement tant que l'heure ne sera pas corrigée", "ShowMonitored": "Afficher le chemin", "WeekColumnHeaderHelpText": "Affiché au dessus de chaque colonne quand \"Semaine\" est l'affichage actif", "ShowRelativeDates": "Afficher les dates relatives", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 6213550bd2..5748e0a368 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -392,7 +392,7 @@ "Warn": "לְהַזהִיר", "StartupDirectory": "ספריית ההפעלה", "System": "מערכת", - "SystemTimeCheckMessage": "זמן המערכת אינו פעיל יותר מיום אחד. משימות מתוזמנות עשויות שלא לפעול כראוי עד לתיקון הזמן", + "SystemTimeHealthCheckMessage": "זמן המערכת אינו פעיל יותר מיום אחד. משימות מתוזמנות עשויות שלא לפעול כראוי עד לתיקון הזמן", "Posters": "כרזות", "PosterSize": "גודל פוסטר", "TagCannotBeDeletedWhileInUse": "לא ניתן למחוק בזמן השימוש", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index e6390f39be..e9cec94338 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -567,7 +567,7 @@ "FileBrowserPlaceholderText": "टाइप करना शुरू करें या नीचे एक पथ चुनें", "StartupDirectory": "स्टार्टअप निर्देशिका", "System": "प्रणाली", - "SystemTimeCheckMessage": "सिस्टम का समय 1 दिन से अधिक बंद है। जब तक समय सही नहीं होगा तब तक शेड्यूल किए गए कार्य सही तरीके से नहीं चल सकते हैं", + "SystemTimeHealthCheckMessage": "सिस्टम का समय 1 दिन से अधिक बंद है। जब तक समय सही नहीं होगा तब तक शेड्यूल किए गए कार्य सही तरीके से नहीं चल सकते हैं", "New": "नया", "Posters": "पोस्टर", "PosterSize": "पोस्टर का आकार", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 8a154c57ea..14e4d13646 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -635,7 +635,7 @@ "TagIsNotUsedAndCanBeDeleted": "A címke nincs használatban, törölhető", "TagCannotBeDeletedWhileInUse": "Használat közben nem törölhető", "TableOptionsColumnsMessage": "Válasszd ki, mely oszlopok legyenek láthatóak, és milyen sorrendben jelenjenek meg", - "SystemTimeCheckMessage": "A rendszeridő több mint 1 napja nem frissült. Előfordulhat, hogy az ütemezett feladatok az idő kijavításáig nem futnak megfelelően", + "SystemTimeHealthCheckMessage": "A rendszeridő több mint 1 napja nem frissült. Előfordulhat, hogy az ütemezett feladatok az idő kijavításáig nem futnak megfelelően", "ColonReplacementFormatHelpText": "Változtassa meg, hogy a {appName} hogyan helyettesíti a kettőspontokat", "ColonReplacement": "Kettőspont Helyettesítés", "IndexerStatusCheckAllClientMessage": "Az összes indexer elérhetetlen hiba miatt", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index e9e7dbf8ba..3db126c46b 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -427,7 +427,7 @@ "FileBrowserPlaceholderText": "Byrjaðu að slá eða veldu leið hér að neðan", "StartupDirectory": "Ræsiskrá", "System": "Kerfi", - "SystemTimeCheckMessage": "Slökkt er á tíma kerfisins meira en 1 dag. Skipulögð verkefni ganga kannski ekki rétt fyrr en tíminn er leiðréttur", + "SystemTimeHealthCheckMessage": "Slökkt er á tíma kerfisins meira en 1 dag. Skipulögð verkefni ganga kannski ekki rétt fyrr en tíminn er leiðréttur", "Posters": "Veggspjöld", "TimeFormat": "Tímasnið", "Timeleft": "Tími eftir", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index b3862372c4..70326e45ec 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -259,7 +259,7 @@ "Test": "Prova", "TableOptionsColumnsMessage": "Scegli quali colonne rendere visibili ed il loro ordine", "TableOptions": "Opzioni Tabella", - "SystemTimeCheckMessage": "L'orario di sistema è sbagliato di più di un giorno. Le attività pianificate potrebbero non essere eseguite correttamente fino alla correzione", + "SystemTimeHealthCheckMessage": "L'orario di sistema è sbagliato di più di un giorno. Le attività pianificate potrebbero non essere eseguite correttamente fino alla correzione", "Source": "Fonte", "Shutdown": "Spegnimento", "Seeders": "Seeders", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 6350e2c8bb..cfb9cfe943 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -18,7 +18,7 @@ "QualityProfiles": "品質プロファイル", "RequiredHelpText": "カスタム形式を適用するには、この{0}条件が一致する必要があります。それ以外の場合は、単一の{1}一致で十分です。", "SendAnonymousUsageData": "匿名の使用状況データを送信する", - "SystemTimeCheckMessage": "システム時刻が1日以上ずれています。スケジュールされたタスクは、時間が修正されるまで正しく実行されない場合があります", + "SystemTimeHealthCheckMessage": "システム時刻が1日以上ずれています。スケジュールされたタスクは、時間が修正されるまで正しく実行されない場合があります", "NotAvailable": "利用不可", "ClickToChangeMovie": "クリックしてムービーを変更", "CloneCustomFormat": "カスタムフォーマットのクローン", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index b4047391e6..4830357263 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -393,7 +393,7 @@ "FileBrowserPlaceholderText": "입력을 시작하거나 아래 경로를 선택하세요.", "StartupDirectory": "시작 디렉토리", "System": "시스템", - "SystemTimeCheckMessage": "시스템 시간이 1 일 이상 꺼져 있습니다. 예약 된 작업은 시간이 수정 될 때까지 올바르게 실행되지 않을 수 있습니다.", + "SystemTimeHealthCheckMessage": "시스템 시간이 1 일 이상 꺼져 있습니다. 예약 된 작업은 시간이 수정 될 때까지 올바르게 실행되지 않을 수 있습니다.", "Posters": "포스터", "PosterSize": "포스터 크기", "TagCannotBeDeletedWhileInUse": "사용 중에는 삭제할 수 없습니다.", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index d3756026dd..0963f311a3 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -213,7 +213,7 @@ "Test": "Test", "TableOptionsColumnsMessage": "Kies welke kolommen zichtbaar zijn en in welke volgorde", "TableOptions": "Tabel Opties", - "SystemTimeCheckMessage": "De systeemtijd loopt verkeerd met meer dan 1 dag. Geplande taken worden mogelijk niet goed uitgevoerd tot dit is opgelost", + "SystemTimeHealthCheckMessage": "De systeemtijd loopt verkeerd met meer dan 1 dag. Geplande taken worden mogelijk niet goed uitgevoerd tot dit is opgelost", "Source": "Bron", "Shutdown": "Afsluiten", "Save": "Opslaan", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 7aa5c26dd2..46e7fbf6c8 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -396,7 +396,7 @@ "AllowHardcodedSubs": "Zezwalaj na wbudowane napisy", "AllowHardcodedSubsHelpText": "Wykryte wbudowane napisy zostaną automatycznie pobrane", "AlreadyInYourLibrary": "Już w Twojej bibliotece", - "SystemTimeCheckMessage": "Czas systemowy jest wyłączony o więcej niż 1 dzień. Zaplanowane zadania mogą nie działać poprawnie, dopóki czas nie zostanie skorygowany", + "SystemTimeHealthCheckMessage": "Czas systemowy jest wyłączony o więcej niż 1 dzień. Zaplanowane zadania mogą nie działać poprawnie, dopóki czas nie zostanie skorygowany", "AnalyticsEnabledHelpText": "Wysyłaj anonimowe informacje o użytkowaniu i błędach do serwerów {appName}. Obejmuje to informacje o Twojej przeglądarce, z których stron {appName} WebUI korzystasz, raportowanie błędów, a także wersję systemu operacyjnego i środowiska wykonawczego. Wykorzystamy te informacje, aby nadać priorytet funkcjom i poprawkom błędów.", "MinimumFreeSpace": "Minimalna wolna przestrzeń", "MinimumLimits": "Minimalne limity", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index dd4119738e..c6236c1967 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -34,7 +34,7 @@ "TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em qual ordem aparecem", "TableOptions": "Opções da tabela", "Table": "Tabela", - "SystemTimeCheckMessage": "A hora do sistema está atrasada em mais de 1 dia. As tarefas agendadas podem não ocorrer corretamente até a hora ser corrigida", + "SystemTimeHealthCheckMessage": "A hora do sistema está atrasada em mais de 1 dia. As tarefas agendadas podem não ocorrer corretamente até a hora ser corrigida", "System": "Sistema", "Style": "Estilo", "Studio": "Estúdio", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index d6da3b787d..6d8bfb71d8 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -599,7 +599,7 @@ "TableOptionsColumnsMessage": "Escolha quais colunas são visíveis e em que ordem aparecem", "TableOptions": "Opções de Tabela", "Table": "Tabela", - "SystemTimeCheckMessage": "A hora do sistema está desligada por mais de 1 dia. Tarefas agendadas podem não ser executadas corretamente até que o horário seja corrigido", + "SystemTimeHealthCheckMessage": "A hora do sistema está desligada por mais de 1 dia. Tarefas agendadas podem não ser executadas corretamente até que o horário seja corrigido", "System": "Sistema", "Sunday": "Domingo", "SuggestTranslationChange": "Sugerir mudança de tradução", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 135b50b55f..0b95a75c4f 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -199,7 +199,7 @@ "Tags": "Etichete", "TableOptionsColumnsMessage": "Alege ce coloane sunt vizibile și în ce ordine apar", "TableOptions": "Opțiuni tabel", - "SystemTimeCheckMessage": "Ora sistemului este diferită cu mai mult de 1 zi. Operațiunile programate s-ar putea să nu funcționeze corect până când ora nu este corectată", + "SystemTimeHealthCheckMessage": "Ora sistemului este diferită cu mai mult de 1 zi. Operațiunile programate s-ar putea să nu funcționeze corect până când ora nu este corectată", "System": "Sistem", "Style": "Stil", "Studio": "Studio", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 636d2b0e9a..0491ca6ded 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -850,7 +850,7 @@ "TableOptionsColumnsMessage": "Выберите видимые столбцы и порядок их отображения", "TableOptions": "Параметры таблицы", "Table": "Таблица", - "SystemTimeCheckMessage": "Системное время отклонилось более чем на 1 день. Запланированные задания могут не работать правильно, пока время не будет исправлено", + "SystemTimeHealthCheckMessage": "Системное время отклонилось более чем на 1 день. Запланированные задания могут не работать правильно, пока время не будет исправлено", "System": "Система", "Sunday": "Воскресенье", "SuggestTranslationChange": "Предложить изменение перевода", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index b8910cb3c1..8af571c739 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -249,7 +249,7 @@ "AllMoviesHiddenDueToFilter": "Samtliga filmer är dolda på grund av tillämpade filter.", "Age": "Ålder", "AddNewMovie": "Lägg till ny film", - "SystemTimeCheckMessage": "Systemklockan går fel med mer än en dag. Schemalagda uppgifter kan få problem att köras innan tiden är korrigerad", + "SystemTimeHealthCheckMessage": "Systemklockan går fel med mer än en dag. Schemalagda uppgifter kan få problem att köras innan tiden är korrigerad", "NoHistory": "Ingen historik", "MovieYear": "Filmår", "NoBackupsAreAvailable": "Inga säkerhetskopior tillgängliga", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 3e3fece121..9e13b83748 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -494,7 +494,7 @@ "FileBrowserPlaceholderText": "เริ่มพิมพ์หรือเลือกเส้นทางด้านล่าง", "StartupDirectory": "ไดเร็กทอรีเริ่มต้น", "System": "ระบบ", - "SystemTimeCheckMessage": "เวลาของระบบปิดมากกว่า 1 วัน งานที่ตั้งเวลาไว้อาจทำงานไม่ถูกต้องจนกว่าจะมีการแก้ไขเวลา", + "SystemTimeHealthCheckMessage": "เวลาของระบบปิดมากกว่า 1 วัน งานที่ตั้งเวลาไว้อาจทำงานไม่ถูกต้องจนกว่าจะมีการแก้ไขเวลา", "Posters": "โปสเตอร์", "PosterSize": "ขนาดโปสเตอร์", "TagCannotBeDeletedWhileInUse": "ไม่สามารถลบได้ขณะใช้งาน", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index f885857dc0..b999c29303 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -615,7 +615,7 @@ "SendAnonymousUsageData": "Anonim Kullanım Verilerini Gönderin", "FileBrowserPlaceholderText": "Yazmaya başlayın veya aşağıdan bir yol seçin", "StartupDirectory": "Başlangıç Dizini", - "SystemTimeCheckMessage": "Sistem saati 1 günden fazla kapalı. Zamanlanan görevler, saat düzeltilene kadar doğru çalışmayabilir", + "SystemTimeHealthCheckMessage": "Sistem saati 1 günden fazla kapalı. Zamanlanan görevler, saat düzeltilene kadar doğru çalışmayabilir", "Posters": "Posterler", "PosterSize": "Poster Boyutu", "TagCannotBeDeletedWhileInUse": "Kullanımdayken silinemez", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 4b607976f8..89ace04326 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -851,7 +851,7 @@ "Style": "Стиль", "SubfolderWillBeCreatedAutomaticallyInterp": "Вкладена папка \"{0}\" буде створена автоматично", "SuggestTranslationChange": "Запропонуйте зміну перекладу", - "SystemTimeCheckMessage": "Системний час вимкнено більш ніж на 1 день. Заплановані завдання можуть не працювати належним чином, доки час не буде виправлено", + "SystemTimeHealthCheckMessage": "Системний час вимкнено більш ніж на 1 день. Заплановані завдання можуть не працювати належним чином, доки час не буде виправлено", "Table": "Таблиця", "TableOptions": "Параметри таблиці", "TableOptionsColumnsMessage": "Виберіть, які стовпці відображаються та в якому порядку вони відображаються", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index d2dccc574c..51c6ae9fd5 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -608,7 +608,7 @@ "FileBrowserPlaceholderText": "Bắt đầu nhập hoặc chọn một đường dẫn bên dưới", "StartupDirectory": "Thư mục khởi động", "System": "Hệ thống", - "SystemTimeCheckMessage": "Thời gian hệ thống tắt hơn 1 ngày. Các tác vụ đã lên lịch có thể không chạy chính xác cho đến khi thời gian được sửa", + "SystemTimeHealthCheckMessage": "Thời gian hệ thống tắt hơn 1 ngày. Các tác vụ đã lên lịch có thể không chạy chính xác cho đến khi thời gian được sửa", "Posters": "Áp phích", "PosterSize": "Kích thước áp phích", "TotalFileSize": "Tổng kích thước tệp", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 18851d0a5e..42a57e5f40 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -698,7 +698,7 @@ "LastUsed": "上次使用", "YesMoveFiles": "是,移动文件", "UpdateMechanismHelpText": "使用 {appName} 内置的更新程序或脚本", - "SystemTimeCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", + "SystemTimeHealthCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", "Table": "表格", "WaitingToImport": "等待导入", "QualityProfiles": "质量配置", From 71ccebd0f5dd4454296bbc6919741be65032452b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 30 Nov 2024 02:12:26 +0200 Subject: [PATCH 097/579] Fix cutoff fixture --- .../DecisionEngineTests/UpgradeDiskSpecificationFixture.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index 458299be73..6a56e98516 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -320,7 +320,7 @@ public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_f UpgradeAllowed = false }); - _parseResultSingle.Series.QualityProfile.Value.FormatItems = new List + _parseResultSingle.Movie.QualityProfile.FormatItems = new List { new ProfileFormatItem { From 4b4e598b67fd1a3a2fa358d2d1bf27104a1f554d Mon Sep 17 00:00:00 2001 From: Barry Mieny Date: Thu, 28 Nov 2024 17:08:55 +0100 Subject: [PATCH 098/579] New: Add Afrikaans language --- src/NzbDrone.Core.Test/Languages/LanguageFixture.cs | 6 ++++-- .../ParserTests/IsoLanguagesFixture.cs | 9 +++++++++ .../ParserTests/LanguageParserFixture.cs | 8 ++++++++ src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs | 4 +++- src/NzbDrone.Core/Languages/Language.cs | 2 ++ src/NzbDrone.Core/Parser/IsoLanguages.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs index e160ac24dc..fae2caa6d6 100644 --- a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs +++ b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs @@ -62,7 +62,8 @@ public class LanguageFixture : CoreTest new object[] { 47, Language.Slovenian }, new object[] { 48, Language.Malayalam }, new object[] { 49, Language.Kannada }, - new object[] { 50, Language.Albanian } + new object[] { 50, Language.Albanian }, + new object[] { 51, Language.Afrikaans } }; public static object[] ToIntCases = @@ -119,7 +120,8 @@ public class LanguageFixture : CoreTest new object[] { Language.Slovenian, 47 }, new object[] { Language.Malayalam, 48 }, new object[] { Language.Kannada, 49 }, - new object[] { Language.Albanian, 50 } + new object[] { Language.Albanian, 50 }, + new object[] { Language.Afrikaans, 51 } }; [Test] diff --git a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs index 0cef2a3904..63d8fa4234 100644 --- a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs @@ -53,5 +53,14 @@ public void should_return_telugu(string isoCode) var result = IsoLanguages.Find(isoCode); result.Language.Should().Be(Language.Telugu); } + + [TestCase("af")] + [TestCase("afr")] + [TestCase("af-ZA")] + public void should_return_afrikaans(string isoCode) + { + var result = IsoLanguages.Find(isoCode); + result.Language.Should().Be(Language.Afrikaans); + } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 79647690db..145099911b 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -452,6 +452,14 @@ public void should_parse_language_albanian(string postTitle) result.Should().Contain(Language.Albanian); } + [TestCase("Movie Title (2024) Afrikaans 1080p HD AVC MP4 x264 .9.8GB TEAMTR")] + [TestCase("Movie.Title.2024.Afrikaans.1080p.AMZN.WEB-DL.DD+2.0.x264-Telly")] + public void should_parse_language_afrikaans(string postTitle) + { + var result = LanguageParser.ParseLanguages(postTitle); + result.Should().Contain(Language.Afrikaans); + } + [TestCase("Movie.Title.en.sub")] [TestCase("Movie Title.eng.sub")] [TestCase("Movie.Title.eng.forced.sub")] diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs index 0072d2db6a..f562feb02d 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs @@ -63,6 +63,8 @@ public enum TMDbLanguageCodes [FieldOption(Hint = "Kannada")] kn, [FieldOption(Hint = "Albanian")] - sq + sq, + [FieldOption(Hint = "Afrikaans")] + af } } diff --git a/src/NzbDrone.Core/Languages/Language.cs b/src/NzbDrone.Core/Languages/Language.cs index 3dc0592b0c..94b9e4e681 100644 --- a/src/NzbDrone.Core/Languages/Language.cs +++ b/src/NzbDrone.Core/Languages/Language.cs @@ -121,6 +121,7 @@ public override bool Equals(object obj) public static Language Malayalam => new Language(48, "Malayalam"); public static Language Kannada => new Language(49, "Kannada"); public static Language Albanian => new Language(50, "Albanian"); + public static Language Afrikaans => new Language(51, "Afrikaans"); public static Language Any => new Language(-1, "Any"); public static Language Original => new Language(-2, "Original"); @@ -181,6 +182,7 @@ public static List All Malayalam, Kannada, Albanian, + Afrikaans, Any, Original }; diff --git a/src/NzbDrone.Core/Parser/IsoLanguages.cs b/src/NzbDrone.Core/Parser/IsoLanguages.cs index c9aa6b2806..af59c3b951 100644 --- a/src/NzbDrone.Core/Parser/IsoLanguages.cs +++ b/src/NzbDrone.Core/Parser/IsoLanguages.cs @@ -60,6 +60,7 @@ public static class IsoLanguages new IsoLanguage("ml", "", "mal", "Malayalam", Language.Malayalam), new IsoLanguage("kn", "", "kan", "Kannada", Language.Kannada), new IsoLanguage("sq", "", "sqi", "Albanian", Language.Albanian), + new IsoLanguage("af", "", "afr", "Afrikaans", Language.Afrikaans), }; private static readonly Dictionary AlternateIsoCodeMappings = new () diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index a9de0dce10..dea8b80dce 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -234,6 +234,11 @@ public static List ParseLanguages(string title) languages.Add(Language.Albanian); } + if (lowerTitle.Contains("afrikaans")) + { + languages.Add(Language.Afrikaans); + } + // Case sensitive var caseSensitiveMatches = CaseSensitiveLanguageRegex.Matches(title); From 7952fd325b71ff94f289e68309971607f03cb632 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 29 Nov 2024 03:32:10 +0000 Subject: [PATCH 099/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Albrt9527 <2563009889@qq.com> Co-authored-by: Havok Dan Co-authored-by: Languages add-on Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_HANS/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/es.json | 3 ++- src/NzbDrone.Core/Localization/Core/pt_BR.json | 7 ++++--- src/NzbDrone.Core/Localization/Core/vi.json | 3 ++- src/NzbDrone.Core/Localization/Core/zh_CN.json | 11 ++++++++++- src/NzbDrone.Core/Localization/Core/zh_HANS.json | 7 +++++++ src/NzbDrone.Core/Localization/Core/zh_TW.json | 9 ++++++++- 6 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 src/NzbDrone.Core/Localization/Core/zh_HANS.json diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 9ba527fbf7..ad47985eb1 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1862,5 +1862,6 @@ "FavoriteFolders": "Carpetas favoritas", "Warning": "Aviso", "FavoriteFolderRemove": "Eliminar carpeta favorita", - "DownloadClientUnavailable": "Cliente de descarga no disponible" + "DownloadClientUnavailable": "Cliente de descarga no disponible", + "NotificationsSettingsWebhookHeaders": "Cabeceras" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 6d8bfb71d8..d5e1611a49 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -389,7 +389,7 @@ "MassMovieSearch": "Pesquisar filmes em massa", "MarkAsFailed": "Marcar como falha", "MarkAsFailedMessageText": "Tem certeza que deseja marcar \"{0}\" como falhado?", - "MappedNetworkDrivesWindowsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as Perguntas frequentes para saber mais", + "MappedNetworkDrivesWindowsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as [FAQ]({url}) para obter mais informações.", "ManualImportSelectQuality": " Importação manual - Selecionar qualidade", "ManualImportSelectMovie": "Importação manual - Selecionar filme", "ManualImportSelectLanguage": "Importação manual - Selecionar idioma", @@ -399,7 +399,7 @@ "Lowercase": "Minúsculas", "LookingForReleaseProfiles2": "em vez disso.", "LookingForReleaseProfiles1": "Procurando pelos perfis de lançamento? Tente", - "Logs": "Logs", + "Logs": "Registros", "LogOnly": "Só registro em log", "LogLevelTraceHelpTextWarning": "O registro em log para rastreamento deve ser habilitado apenas temporariamente", "LogLevel": "Nível de registro em log", @@ -1863,5 +1863,6 @@ "FavoriteFolderRemove": "Remover Pasta Favorita", "FavoriteFolders": "Pastas Favoritas", "Warning": "Cuidado", - "DownloadClientUnavailable": "Cliente de download indisponível" + "DownloadClientUnavailable": "Cliente de download indisponível", + "NotificationsSettingsWebhookHeaders": "Cabeçalhos" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 51c6ae9fd5..8dd0a23297 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1111,5 +1111,6 @@ "AllTitles": "Tất cả các tệp", "DownloadClientUnavailable": "Ứng dụng khách tải xuống không khả dụng", "AddReleaseProfile": "Chỉnh sửa hồ sơ độ trễ", - "EditConditionImplementation": "Thêm điều kiện - {implementationName}" + "EditConditionImplementation": "Thêm điều kiện - {implementationName}", + "EditIndexerImplementation": "Thêm điều kiện - {implementationName}" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 42a57e5f40..dee5788dd9 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1855,5 +1855,14 @@ "Completed": "完成", "Delay": "延迟", "DownloadClientUnavailable": "下载客户端不可用", - "Fallback": "备选" + "Fallback": "备选", + "FavoriteFolderAdd": "添加收藏文件夹", + "FavoriteFolderRemove": "删除收藏夹", + "FavoriteFolders": "收藏夹", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "如果 .nfo 中可用,请包含所选语言", + "OnFileUpgrade": "文件升级时", + "OnFileImport": "关于文件导入", + "ManageFormats": "管理格式", + "NotificationsSettingsWebhookHeaders": "标头", + "Warning": "警告" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_HANS.json b/src/NzbDrone.Core/Localization/Core/zh_HANS.json new file mode 100644 index 0000000000..8b9f6d1631 --- /dev/null +++ b/src/NzbDrone.Core/Localization/Core/zh_HANS.json @@ -0,0 +1,7 @@ +{ + "About": "关于", + "Add": "添加", + "Always": "总是", + "Analytics": "分析", + "Username": "用户名" +} diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index 470d9fd0a5..9aca50298b 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -259,5 +259,12 @@ "UpdateAvailableHealthCheckMessage": "可用的新版本: {version}", "UpdateAppDirectlyLoadError": "無法直接更新 {appName},", "UnselectAll": "取消全選", - "Any": "任何" + "Any": "任何", + "UiLanguage": "使用者介面語言", + "IndexersLoadError": "無法載入索引器", + "TagsLoadError": "無法載入標籤", + "UiSettings": "使用者介面設定", + "UiSettingsLoadError": "無法載入 UI 設定", + "HistoryLoadError": "無法載入歷史記錄", + "UiLanguageHelpText": "{appName} 介面所使用的語言" } From 828b994ef4fa457055983e9db67b42e584712206 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 24 Nov 2024 20:51:33 -0800 Subject: [PATCH 100/579] Support Postgres with non-standard version string (cherry picked from commit 40f4ef27b22113c1dae0d0cbdee8205132bed68a) --- .../Datastore/DatabaseVersionParserFixture.cs | 38 +++++++++++++++++++ src/NzbDrone.Core/Datastore/Database.cs | 4 +- .../Datastore/DatabaseVersionParser.cs | 16 ++++++++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 src/NzbDrone.Core.Test/Datastore/DatabaseVersionParserFixture.cs create mode 100644 src/NzbDrone.Core/Datastore/DatabaseVersionParser.cs diff --git a/src/NzbDrone.Core.Test/Datastore/DatabaseVersionParserFixture.cs b/src/NzbDrone.Core.Test/Datastore/DatabaseVersionParserFixture.cs new file mode 100644 index 0000000000..05bf04fead --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/DatabaseVersionParserFixture.cs @@ -0,0 +1,38 @@ +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Test.Datastore; + +[TestFixture] +public class DatabaseVersionParserFixture +{ + [TestCase("3.44.2", 3, 44, 2)] + public void should_parse_sqlite_database_version(string serverVersion, int majorVersion, int minorVersion, int buildVersion) + { + var version = DatabaseVersionParser.ParseServerVersion(serverVersion); + + version.Should().NotBeNull(); + version.Major.Should().Be(majorVersion); + version.Minor.Should().Be(minorVersion); + version.Build.Should().Be(buildVersion); + } + + [TestCase("14.8 (Debian 14.8-1.pgdg110+1)", 14, 8, null)] + [TestCase("16.3 (Debian 16.3-1.pgdg110+1)", 16, 3, null)] + [TestCase("16.3 - Percona Distribution", 16, 3, null)] + [TestCase("17.0 - Percona Server", 17, 0, null)] + public void should_parse_postgres_database_version(string serverVersion, int majorVersion, int minorVersion, int? buildVersion) + { + var version = DatabaseVersionParser.ParseServerVersion(serverVersion); + + version.Should().NotBeNull(); + version.Major.Should().Be(majorVersion); + version.Minor.Should().Be(minorVersion); + + if (buildVersion.HasValue) + { + version.Build.Should().Be(buildVersion.Value); + } + } +} diff --git a/src/NzbDrone.Core/Datastore/Database.cs b/src/NzbDrone.Core/Datastore/Database.cs index d4252ed258..d31dab26b4 100644 --- a/src/NzbDrone.Core/Datastore/Database.cs +++ b/src/NzbDrone.Core/Datastore/Database.cs @@ -2,7 +2,6 @@ using System.Data; using System.Data.Common; using System.Data.SQLite; -using System.Text.RegularExpressions; using Dapper; using NLog; using NzbDrone.Common.Instrumentation; @@ -52,9 +51,8 @@ public Version Version { using var db = _datamapperFactory(); var dbConnection = db as DbConnection; - var version = Regex.Replace(dbConnection.ServerVersion, @"\(.*?\)", ""); - return new Version(version); + return DatabaseVersionParser.ParseServerVersion(dbConnection.ServerVersion); } } diff --git a/src/NzbDrone.Core/Datastore/DatabaseVersionParser.cs b/src/NzbDrone.Core/Datastore/DatabaseVersionParser.cs new file mode 100644 index 0000000000..ffc77cf182 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/DatabaseVersionParser.cs @@ -0,0 +1,16 @@ +using System; +using System.Text.RegularExpressions; + +namespace NzbDrone.Core.Datastore; + +public static class DatabaseVersionParser +{ + private static readonly Regex VersionRegex = new (@"^[^ ]+", RegexOptions.Compiled); + + public static Version ParseServerVersion(string serverVersion) + { + var match = VersionRegex.Match(serverVersion); + + return match.Success ? new Version(match.Value) : null; + } +} From 0fee5520742aa2dbbbe8d1727407847ed2be0671 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 1 Dec 2024 14:00:15 +0200 Subject: [PATCH 101/579] Bump version to 5.16.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c1713abaac..8e988be842 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.16.0' + majorVersion: '5.16.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From b845268b3d67bcc1f8075ff508dff5f57fc41bc4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 22 Nov 2024 18:39:35 -0800 Subject: [PATCH 102/579] New: Support for new SABnzbd history retention values Closes #10699 (cherry picked from commit e361f18837d98c089f7dc9c0190221ca8e2cf225) --- .../SabnzbdTests/SabnzbdFixture.cs | 31 +++++++++++ .../Download/Clients/Sabnzbd/Sabnzbd.cs | 53 ++++++++++++++----- .../Clients/Sabnzbd/SabnzbdCategory.cs | 2 + 3 files changed, 72 insertions(+), 14 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs index fe782f0c95..00d904a0a8 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/SabnzbdTests/SabnzbdFixture.cs @@ -478,6 +478,37 @@ public void should_set_history_removes_completed_downloads_true(string historyRe downloadClientInfo.RemovesCompletedDownloads.Should().BeTrue(); } + [TestCase("all", 0)] + [TestCase("days-archive", 15)] + [TestCase("days-delete", 15)] + public void should_set_history_removes_completed_downloads_false_for_separate_properties(string option, int number) + { + _config.Misc.history_retention_option = option; + _config.Misc.history_retention_number = number; + + var downloadClientInfo = Subject.GetStatus(); + + downloadClientInfo.RemovesCompletedDownloads.Should().BeFalse(); + } + + [TestCase("number-archive", 10)] + [TestCase("number-delete", 10)] + [TestCase("number-archive", 0)] + [TestCase("number-delete", 0)] + [TestCase("days-archive", 3)] + [TestCase("days-delete", 3)] + [TestCase("all-archive", 0)] + [TestCase("all-delete", 0)] + public void should_set_history_removes_completed_downloads_true_for_separate_properties(string option, int number) + { + _config.Misc.history_retention_option = option; + _config.Misc.history_retention_number = number; + + var downloadClientInfo = Subject.GetStatus(); + + downloadClientInfo.RemovesCompletedDownloads.Should().BeTrue(); + } + [TestCase(@"Y:\sabnzbd\root", @"completed\downloads", @"vv", @"Y:\sabnzbd\root\completed\downloads", @"Y:\sabnzbd\root\completed\downloads\vv")] [TestCase(@"Y:\sabnzbd\root", @"completed", @"vv", @"Y:\sabnzbd\root\completed", @"Y:\sabnzbd\root\completed\vv")] [TestCase(@"/sabnzbd/root", @"completed/downloads", @"vv", @"/sabnzbd/root/completed/downloads", @"/sabnzbd/root/completed/downloads/vv")] diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs index 7237640add..02e8a17ef1 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/Sabnzbd.cs @@ -278,20 +278,7 @@ public override DownloadClientInfo GetStatus() status.OutputRootFolders = new List { _remotePathMappingService.RemapRemoteToLocal(Settings.Host, category.FullPath) }; } - if (config.Misc.history_retention.IsNullOrWhiteSpace()) - { - status.RemovesCompletedDownloads = false; - } - else if (config.Misc.history_retention.EndsWith("d")) - { - int.TryParse(config.Misc.history_retention.AsSpan(0, config.Misc.history_retention.Length - 1), - out var daysRetention); - status.RemovesCompletedDownloads = daysRetention < 14; - } - else - { - status.RemovesCompletedDownloads = config.Misc.history_retention != "0"; - } + status.RemovesCompletedDownloads = RemovesCompletedDownloads(config); return status; } @@ -548,6 +535,44 @@ private bool ContainsCategory(IEnumerable categories, string category) return categories.Contains(category); } + private bool RemovesCompletedDownloads(SabnzbdConfig config) + { + var retention = config.Misc.history_retention; + var option = config.Misc.history_retention_option; + var number = config.Misc.history_retention_number; + + switch (option) + { + case "all": + return false; + case "number-archive": + case "number-delete": + return true; + case "days-archive": + case "days-delete": + return number < 14; + case "all-archive": + case "all-delete": + return true; + } + + // TODO: Remove these checks once support for SABnzbd < 4.3 is removed + + if (retention.IsNullOrWhiteSpace()) + { + return false; + } + + if (retention.EndsWith("d")) + { + int.TryParse(config.Misc.history_retention.AsSpan(0, config.Misc.history_retention.Length - 1), + out var daysRetention); + return daysRetention < 14; + } + + return retention != "0"; + } + private bool ValidatePath(DownloadClientItem downloadClientItem) { var downloadItemOutputPath = downloadClientItem.OutputPath; diff --git a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs index aa04edc5dd..740b34ddb0 100644 --- a/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs +++ b/src/NzbDrone.Core/Download/Clients/Sabnzbd/SabnzbdCategory.cs @@ -32,6 +32,8 @@ public class SabnzbdConfigMisc public bool enable_date_sorting { get; set; } public bool pre_check { get; set; } public string history_retention { get; set; } + public string history_retention_option { get; set; } + public int history_retention_number { get; set; } } public class SabnzbdCategory From ba4ccbb0bd6ad6c281339168c75296985c5481e5 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 26 Nov 2024 17:36:53 -0800 Subject: [PATCH 103/579] Deluge communication improvements (cherry picked from commit 183b8b574a4dd948b5fada94d0e645b87710f223) --- .../Download/Clients/Deluge/Deluge.cs | 31 ++++++----- .../Download/Clients/Deluge/DelugeProxy.cs | 52 +++++++------------ 2 files changed, 39 insertions(+), 44 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs index 8e4fba2e88..01d0217257 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/Deluge.cs @@ -20,6 +20,7 @@ namespace NzbDrone.Core.Download.Clients.Deluge public class Deluge : TorrentClientBase { private readonly IDelugeProxy _proxy; + private bool _hasAttemptedReconnecting; public Deluge(IDelugeProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, @@ -128,14 +129,9 @@ public override IEnumerable GetItems() foreach (var torrent in torrents) { - // Silently ignore torrents with no hash - if (torrent.Hash.IsNullOrWhiteSpace()) - { - continue; - } - - // Ignore torrents without a name, but track to log a single warning for all invalid torrents. - if (torrent.Name.IsNullOrWhiteSpace()) + // Ignore torrents without a hash or name, but track to log a single warning + // for all invalid torrents as well as reconnect to the Daemon. + if (torrent.Hash.IsNullOrWhiteSpace() || torrent.Name.IsNullOrWhiteSpace()) { ignoredCount++; continue; @@ -199,9 +195,20 @@ public override IEnumerable GetItems() items.Add(item); } - if (ignoredCount > 0) + if (ignoredCount > 0 && _hasAttemptedReconnecting) { - _logger.Warn("{0} torrent(s) were ignored because they did not have a title. Check Deluge and remove any invalid torrents"); + if (_hasAttemptedReconnecting) + { + _logger.Warn("{0} torrent(s) were ignored because they did not have a hash or title. Deluge may have disconnected from it's daemon. If you continue to see this error, check Deluge for invalid torrents.", ignoredCount); + } + else + { + _proxy.ReconnectToDaemon(Settings); + } + } + else + { + _hasAttemptedReconnecting = false; } return items; @@ -322,9 +329,9 @@ private ValidationFailure TestCategory() return null; } - var enabledPlugins = _proxy.GetEnabledPlugins(Settings); + var methods = _proxy.GetMethods(Settings); - if (!enabledPlugins.Contains("Label")) + if (!methods.Any(m => m.StartsWith("label."))) { return new NzbDroneValidationFailure("MovieCategory", _localizationService.GetLocalizedString("DownloadClientDelugeValidationLabelPluginInactive")) { diff --git a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs index cbe7a985c6..98f35d3fc3 100644 --- a/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Deluge/DelugeProxy.cs @@ -18,8 +18,7 @@ public interface IDelugeProxy Dictionary GetConfig(DelugeSettings settings); DelugeTorrent[] GetTorrents(DelugeSettings settings); DelugeTorrent[] GetTorrentsByLabel(string label, DelugeSettings settings); - string[] GetAvailablePlugins(DelugeSettings settings); - string[] GetEnabledPlugins(DelugeSettings settings); + string[] GetMethods(DelugeSettings settings); string[] GetAvailableLabels(DelugeSettings settings); DelugeLabel GetLabelOptions(DelugeSettings settings); void SetTorrentLabel(string hash, string label, DelugeSettings settings); @@ -30,6 +29,7 @@ public interface IDelugeProxy string AddTorrentFromFile(string filename, byte[] fileContent, DelugeSettings settings); bool RemoveTorrent(string hash, bool removeData, DelugeSettings settings); void MoveTorrentToTopInQueue(string hash, DelugeSettings settings); + void ReconnectToDaemon(DelugeSettings settings); } public class DelugeProxy : IDelugeProxy @@ -51,25 +51,14 @@ public DelugeProxy(ICacheManager cacheManager, IHttpClient httpClient, Logger lo public string GetVersion(DelugeSettings settings) { - try + var methods = GetMethods(settings); + + if (methods.Contains("daemon.get_version")) { - var response = ProcessRequest(settings, "daemon.info"); - - return response; + return ProcessRequest(settings, "daemon.get_version"); } - catch (DownloadClientException ex) - { - if (ex.Message.Contains("Unknown method")) - { - // Deluge v2 beta replaced 'daemon.info' with 'daemon.get_version'. - // It may return or become official, for now we just retry with the get_version api. - var response = ProcessRequest(settings, "daemon.get_version"); - return response; - } - - throw; - } + return ProcessRequest(settings, "daemon.info"); } public Dictionary GetConfig(DelugeSettings settings) @@ -101,6 +90,13 @@ public DelugeTorrent[] GetTorrentsByLabel(string label, DelugeSettings settings) return GetTorrents(response); } + public string[] GetMethods(DelugeSettings settings) + { + var response = ProcessRequest(settings, "system.listMethods"); + + return response; + } + public string AddTorrentFromMagnet(string magnetLink, DelugeSettings settings) { dynamic options = new ExpandoObject(); @@ -159,20 +155,6 @@ public void MoveTorrentToTopInQueue(string hash, DelugeSettings settings) ProcessRequest(settings, "core.queue_top", (object)new string[] { hash }); } - public string[] GetAvailablePlugins(DelugeSettings settings) - { - var response = ProcessRequest(settings, "core.get_available_plugins"); - - return response; - } - - public string[] GetEnabledPlugins(DelugeSettings settings) - { - var response = ProcessRequest(settings, "core.get_enabled_plugins"); - - return response; - } - public string[] GetAvailableLabels(DelugeSettings settings) { var response = ProcessRequest(settings, "label.get_labels"); @@ -223,6 +205,12 @@ public void SetTorrentLabel(string hash, string label, DelugeSettings settings) ProcessRequest(settings, "label.set_torrent", hash, label); } + public void ReconnectToDaemon(DelugeSettings settings) + { + ProcessRequest(settings, "web.disconnect"); + ConnectDaemon(BuildRequest(settings)); + } + private JsonRpcRequestBuilder BuildRequest(DelugeSettings settings) { var url = HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase); From 617b9c5d35e73561f3ca8f28cff0541528531e91 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 4 Nov 2024 15:24:45 +0200 Subject: [PATCH 104/579] Console warnings for missing translations on development builds (cherry picked from commit 67a1ecb0fea4e6c7dfdb68fbe3ef30d4c22398d8) Closes #10669 --- frontend/src/Utilities/String/translate.ts | 6 ++++++ frontend/typings/Globals.d.ts | 1 + 2 files changed, 7 insertions(+) diff --git a/frontend/src/Utilities/String/translate.ts b/frontend/src/Utilities/String/translate.ts index 8081995ab7..f4cab8ec6d 100644 --- a/frontend/src/Utilities/String/translate.ts +++ b/frontend/src/Utilities/String/translate.ts @@ -27,6 +27,12 @@ export default function translate( key: string, tokens: Record = {} ) { + const { isProduction = true } = window.Radarr; + + if (!isProduction && !(key in translations)) { + console.warn(`Missing translation for key: ${key}`); + } + const translation = translations[key] || key; tokens.appName = 'Radarr'; diff --git a/frontend/typings/Globals.d.ts b/frontend/typings/Globals.d.ts index 29136ac483..21e40447bd 100644 --- a/frontend/typings/Globals.d.ts +++ b/frontend/typings/Globals.d.ts @@ -7,5 +7,6 @@ interface Window { theme: string; urlBase: string; version: string; + isProduction: boolean; }; } From 114d260f42612117dad4f8219d1dac6b56136e14 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 18 Nov 2024 16:50:56 -0800 Subject: [PATCH 105/579] Deprecate Sizeleft and Timeleft queue item properties Rename SizeLeft and TimeLeft queue item properties (cherry picked from commit b51a49097941e5f306cae5785c63985b319784fd) Fixed: Error loading queue (cherry picked from commit f9606518eef78117f1e06a8bcc34af57ab0d2454) --- .../Download/Pending/PendingReleaseService.cs | 10 +-- src/NzbDrone.Core/Queue/Queue.cs | 4 +- src/NzbDrone.Core/Queue/QueueService.cs | 8 +- .../ApiTests/QueueFixture.cs | 73 +++++++++++++++++++ .../Client/QueueClient.cs | 13 ++++ .../IntegrationTestBase.cs | 2 + src/Radarr.Api.V3/Queue/QueueController.cs | 10 +-- src/Radarr.Api.V3/Queue/QueueResource.cs | 27 +++++-- 8 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 src/NzbDrone.Integration.Test/ApiTests/QueueFixture.cs create mode 100644 src/NzbDrone.Integration.Test/Client/QueueClient.cs diff --git a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs index 75299e6c54..56f1b7a457 100644 --- a/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs +++ b/src/NzbDrone.Core/Download/Pending/PendingReleaseService.cs @@ -311,11 +311,11 @@ private Queue.Queue GetQueueItem(PendingRelease pendingRelease, Lazy n ect = ect.AddMinutes(_configService.RssSyncInterval); } - var timeleft = ect.Subtract(DateTime.UtcNow); + var timeLeft = ect.Subtract(DateTime.UtcNow); - if (timeleft.TotalSeconds < 0) + if (timeLeft.TotalSeconds < 0) { - timeleft = TimeSpan.Zero; + timeLeft = TimeSpan.Zero; } string downloadClientName = null; @@ -336,9 +336,9 @@ private Queue.Queue GetQueueItem(PendingRelease pendingRelease, Lazy n Languages = pendingRelease.RemoteMovie.Languages, Title = pendingRelease.Title, Size = pendingRelease.RemoteMovie.Release.Size, - Sizeleft = pendingRelease.RemoteMovie.Release.Size, + SizeLeft = pendingRelease.RemoteMovie.Release.Size, RemoteMovie = pendingRelease.RemoteMovie, - Timeleft = timeleft, + TimeLeft = timeLeft, EstimatedCompletionTime = ect, Added = pendingRelease.Added, Status = Enum.TryParse(pendingRelease.Reason.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown, diff --git a/src/NzbDrone.Core/Queue/Queue.cs b/src/NzbDrone.Core/Queue/Queue.cs index acfd7bbd97..aba9f5704e 100644 --- a/src/NzbDrone.Core/Queue/Queue.cs +++ b/src/NzbDrone.Core/Queue/Queue.cs @@ -17,8 +17,8 @@ public class Queue : ModelBase public QualityModel Quality { get; set; } public decimal Size { get; set; } public string Title { get; set; } - public decimal Sizeleft { get; set; } - public TimeSpan? Timeleft { get; set; } + public decimal SizeLeft { get; set; } + public TimeSpan? TimeLeft { get; set; } public DateTime? EstimatedCompletionTime { get; set; } public DateTime? Added { get; set; } public QueueStatus Status { get; set; } diff --git a/src/NzbDrone.Core/Queue/QueueService.cs b/src/NzbDrone.Core/Queue/QueueService.cs index 92ec872371..e4607b943d 100644 --- a/src/NzbDrone.Core/Queue/QueueService.cs +++ b/src/NzbDrone.Core/Queue/QueueService.cs @@ -62,8 +62,8 @@ private Queue MapMovie(TrackedDownload trackedDownload, Movie movie) Quality = trackedDownload.RemoteMovie?.ParsedMovieInfo.Quality ?? new QualityModel(Quality.Unknown), Title = trackedDownload.DownloadItem.Title, Size = trackedDownload.DownloadItem.TotalSize, - Sizeleft = trackedDownload.DownloadItem.RemainingSize, - Timeleft = trackedDownload.DownloadItem.RemainingTime, + SizeLeft = trackedDownload.DownloadItem.RemainingSize, + TimeLeft = trackedDownload.DownloadItem.RemainingTime, Status = Enum.TryParse(trackedDownload.DownloadItem.Status.ToString(), out QueueStatus outValue) ? outValue : QueueStatus.Unknown, TrackedDownloadStatus = trackedDownload.Status, TrackedDownloadState = trackedDownload.State, @@ -82,9 +82,9 @@ private Queue MapMovie(TrackedDownload trackedDownload, Movie movie) queue.Id = HashConverter.GetHashInt31($"trackedDownload-{trackedDownload.DownloadClient}-{trackedDownload.DownloadItem.DownloadId}"); - if (queue.Timeleft.HasValue) + if (queue.TimeLeft.HasValue) { - queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.Timeleft.Value); + queue.EstimatedCompletionTime = DateTime.UtcNow.Add(queue.TimeLeft.Value); } return queue; diff --git a/src/NzbDrone.Integration.Test/ApiTests/QueueFixture.cs b/src/NzbDrone.Integration.Test/ApiTests/QueueFixture.cs new file mode 100644 index 0000000000..e659ca5b1f --- /dev/null +++ b/src/NzbDrone.Integration.Test/ApiTests/QueueFixture.cs @@ -0,0 +1,73 @@ +using System.IO; +using System.Linq; +using System.Threading; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Messaging.Commands; +using NzbDrone.Integration.Test.Client; +using Radarr.Api.V3.Queue; +using Radarr.Http; + +namespace NzbDrone.Integration.Test.ApiTests +{ + [TestFixture] + public class QueueFixture : IntegrationTest + { + private PagingResource GetFirstPage() + { + var request = Queue.BuildRequest(); + request.AddParameter("includeUnknownMovieItems", true); + + return Queue.Get>(request); + } + + private void RefreshQueue() + { + var command = Commands.Post(new SimpleCommandResource { Name = "RefreshMonitoredDownloads" }); + + for (var i = 0; i < 30; i++) + { + var updatedCommand = Commands.Get(command.Id); + + if (updatedCommand.Status == CommandStatus.Completed) + { + return; + } + + Thread.Sleep(1000); + i++; + } + } + + [Test] + [Order(0)] + public void ensure_queue_is_empty_when_download_client_is_configured() + { + EnsureNoDownloadClient(); + EnsureDownloadClient(); + + var queue = GetFirstPage(); + + queue.TotalRecords.Should().Be(0); + queue.Records.Should().BeEmpty(); + } + + [Test] + [Order(1)] + public void ensure_queue_is_not_empty() + { + EnsureNoDownloadClient(); + + var client = EnsureDownloadClient(); + var directory = client.Fields.First(v => v.Name == "watchFolder").Value as string; + + File.WriteAllText(Path.Combine(directory, "Movie.Title.2024.mkv"), "Test Download"); + RefreshQueue(); + + var queue = GetFirstPage(); + + queue.TotalRecords.Should().Be(1); + queue.Records.Should().NotBeEmpty(); + } + } +} diff --git a/src/NzbDrone.Integration.Test/Client/QueueClient.cs b/src/NzbDrone.Integration.Test/Client/QueueClient.cs new file mode 100644 index 0000000000..bc669d2905 --- /dev/null +++ b/src/NzbDrone.Integration.Test/Client/QueueClient.cs @@ -0,0 +1,13 @@ +using Radarr.Api.V3.Queue; +using RestSharp; + +namespace NzbDrone.Integration.Test.Client +{ + public class QueueClient : ClientBase + { + public QueueClient(IRestClient restClient, string apiKey) + : base(restClient, apiKey) + { + } + } +} diff --git a/src/NzbDrone.Integration.Test/IntegrationTestBase.cs b/src/NzbDrone.Integration.Test/IntegrationTestBase.cs index 517fa27d27..4ba8e73918 100644 --- a/src/NzbDrone.Integration.Test/IntegrationTestBase.cs +++ b/src/NzbDrone.Integration.Test/IntegrationTestBase.cs @@ -53,6 +53,7 @@ public abstract class IntegrationTestBase public ClientBase Tags; public ClientBase WantedMissing; public ClientBase WantedCutoffUnmet; + public QueueClient Queue; private List _signalRReceived; @@ -115,6 +116,7 @@ protected virtual void InitRestClients() Tags = new ClientBase(RestClient, ApiKey); WantedMissing = new ClientBase(RestClient, ApiKey, "wanted/missing"); WantedCutoffUnmet = new ClientBase(RestClient, ApiKey, "wanted/cutoff"); + Queue = new QueueClient(RestClient, ApiKey); } [OneTimeTearDown] diff --git a/src/Radarr.Api.V3/Queue/QueueController.cs b/src/Radarr.Api.V3/Queue/QueueController.cs index 0b506fea43..00095ed136 100644 --- a/src/Radarr.Api.V3/Queue/QueueController.cs +++ b/src/Radarr.Api.V3/Queue/QueueController.cs @@ -214,8 +214,8 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource if (pagingSpec.SortKey == "timeleft") { ordered = ascending - ? fullQueue.OrderBy(q => q.Timeleft, new TimeleftComparer()) - : fullQueue.OrderByDescending(q => q.Timeleft, new TimeleftComparer()); + ? fullQueue.OrderBy(q => q.TimeLeft, new TimeleftComparer()) + : fullQueue.OrderByDescending(q => q.TimeLeft, new TimeleftComparer()); } else if (pagingSpec.SortKey == "estimatedCompletionTime") { @@ -266,7 +266,7 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource ordered = ascending ? fullQueue.OrderBy(orderByFunc) : fullQueue.OrderByDescending(orderByFunc); } - ordered = ordered.ThenByDescending(q => q.Size == 0 ? 0 : 100 - (q.Sizeleft / q.Size * 100)); + ordered = ordered.ThenByDescending(q => q.Size == 0 ? 0 : 100 - (q.SizeLeft / q.Size * 100)); pagingSpec.Records = ordered.Skip((pagingSpec.Page - 1) * pagingSpec.PageSize).Take(pagingSpec.PageSize).ToList(); pagingSpec.TotalRecords = fullQueue.Count; @@ -300,9 +300,9 @@ public PagingResource GetQueue([FromQuery] PagingRequestResource return q => q.Size; case "progress": // Avoid exploding if a download's size is 0 - return q => 100 - (q.Sizeleft / Math.Max(q.Size * 100, 1)); + return q => 100 - (q.SizeLeft / Math.Max(q.Size * 100, 1)); default: - return q => q.Timeleft; + return q => q.TimeLeft; } } diff --git a/src/Radarr.Api.V3/Queue/QueueResource.cs b/src/Radarr.Api.V3/Queue/QueueResource.cs index e3826396b9..e28b896a45 100644 --- a/src/Radarr.Api.V3/Queue/QueueResource.cs +++ b/src/Radarr.Api.V3/Queue/QueueResource.cs @@ -22,8 +22,11 @@ public class QueueResource : RestResource public int CustomFormatScore { get; set; } public decimal Size { get; set; } public string Title { get; set; } - public decimal Sizeleft { get; set; } - public TimeSpan? Timeleft { get; set; } + + // Collides with existing properties due to case-insensitive deserialization + // public decimal SizeLeft { get; set; } + // public TimeSpan? TimeLeft { get; set; } + public DateTime? EstimatedCompletionTime { get; set; } public DateTime? Added { get; set; } public QueueStatus Status { get; set; } @@ -37,6 +40,12 @@ public class QueueResource : RestResource public bool DownloadClientHasPostImportCategory { get; set; } public string Indexer { get; set; } public string OutputPath { get; set; } + + [Obsolete("Will be replaced by SizeLeft")] + public decimal Sizeleft { get; set; } + + [Obsolete("Will be replaced by TimeLeft")] + public TimeSpan? Timeleft { get; set; } } public static class QueueResourceMapper @@ -62,8 +71,11 @@ public static QueueResource ToResource(this NzbDrone.Core.Queue.Queue model, boo CustomFormatScore = customFormatScore, Size = model.Size, Title = model.Title, - Sizeleft = model.Sizeleft, - Timeleft = model.Timeleft, + + // Collides with existing properties due to case-insensitive deserialization + // SizeLeft = model.SizeLeft, + // TimeLeft = model.TimeLeft, + EstimatedCompletionTime = model.EstimatedCompletionTime, Added = model.Added, Status = model.Status, @@ -76,7 +88,12 @@ public static QueueResource ToResource(this NzbDrone.Core.Queue.Queue model, boo DownloadClient = model.DownloadClient, DownloadClientHasPostImportCategory = model.DownloadClientHasPostImportCategory, Indexer = model.Indexer, - OutputPath = model.OutputPath + OutputPath = model.OutputPath, + + #pragma warning disable CS0618 + Sizeleft = model.SizeLeft, + Timeleft = model.TimeLeft, + #pragma warning restore CS0618 }; } From 5bac157d365ccefbb0fa883e15f5a0baa57420e4 Mon Sep 17 00:00:00 2001 From: Gylesie <86306812+Gylesie@users.noreply.github.com> Date: Mon, 2 Dec 2024 01:22:04 +0100 Subject: [PATCH 106/579] Remove unnecessary heap allocations in local IP check (cherry picked from commit ed536a85ad5f2062bf6f01f80efddb19fa935f63) --- src/NzbDrone.Common/Extensions/IpAddressExtensions.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs b/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs index 7feb431c45..b60d4271ab 100644 --- a/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs +++ b/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs @@ -39,18 +39,18 @@ public static bool IsLocalAddress(this IPAddress ipAddress) private static bool IsLocalIPv4(byte[] ipv4Bytes) { // Link local (no IP assigned by DHCP): 169.254.0.0 to 169.254.255.255 (169.254.0.0/16) - bool IsLinkLocal() => ipv4Bytes[0] == 169 && ipv4Bytes[1] == 254; + var isLinkLocal = ipv4Bytes[0] == 169 && ipv4Bytes[1] == 254; // Class A private range: 10.0.0.0 – 10.255.255.255 (10.0.0.0/8) - bool IsClassA() => ipv4Bytes[0] == 10; + var isClassA = ipv4Bytes[0] == 10; // Class B private range: 172.16.0.0 – 172.31.255.255 (172.16.0.0/12) - bool IsClassB() => ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31; + var isClassB = ipv4Bytes[0] == 172 && ipv4Bytes[1] >= 16 && ipv4Bytes[1] <= 31; // Class C private range: 192.168.0.0 – 192.168.255.255 (192.168.0.0/16) - bool IsClassC() => ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168; + var isClassC = ipv4Bytes[0] == 192 && ipv4Bytes[1] == 168; - return IsLinkLocal() || IsClassA() || IsClassC() || IsClassB(); + return isLinkLocal || isClassA || isClassC || isClassB; } } } From 3449a5d3fe7696bafdf3a8e0fc795e529d83b7a1 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 1 Dec 2024 08:59:44 -0800 Subject: [PATCH 107/579] Fixed: Don't fail import if symlink target can't be resolved (cherry picked from commit 8cb58a63d8ec1b290bc57ad2cf1e90809ceebce9) --- src/NzbDrone.Common/Disk/DiskProviderBase.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/NzbDrone.Common/Disk/DiskProviderBase.cs b/src/NzbDrone.Common/Disk/DiskProviderBase.cs index 8983b92989..fcc31f2b45 100644 --- a/src/NzbDrone.Common/Disk/DiskProviderBase.cs +++ b/src/NzbDrone.Common/Disk/DiskProviderBase.cs @@ -190,16 +190,23 @@ public long GetFileSize(string path) var fi = new FileInfo(path); - // If the file is a symlink, resolve the target path and get the size of the target file. - if (fi.Attributes.HasFlag(FileAttributes.ReparsePoint)) + try { - var targetPath = fi.ResolveLinkTarget(true)?.FullName; - - if (targetPath != null) + // If the file is a symlink, resolve the target path and get the size of the target file. + if (fi.Attributes.HasFlag(FileAttributes.ReparsePoint)) { - fi = new FileInfo(targetPath); + var targetPath = fi.ResolveLinkTarget(true)?.FullName; + + if (targetPath != null) + { + fi = new FileInfo(targetPath); + } } } + catch (IOException ex) + { + Logger.Trace(ex, "Unable to resolve symlink target for {0}", path); + } return fi.Length; } From 3cc4105d7191088a536507ed9148c3df924ca093 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 2 Dec 2024 14:30:04 +0200 Subject: [PATCH 108/579] Bump NLog, Npgsql, Ical.Net, IPAddressRange, ImageSharp and Polly --- src/NzbDrone.Common/Radarr.Common.csproj | 10 +++++----- src/NzbDrone.Core/Radarr.Core.csproj | 8 ++++---- src/NzbDrone.Test.Common/Radarr.Test.Common.csproj | 2 +- src/NzbDrone.Update/Radarr.Update.csproj | 4 ++-- src/NzbDrone.Windows/Radarr.Windows.csproj | 4 ++-- src/Radarr.Api.V3/Radarr.Api.V3.csproj | 4 ++-- src/Radarr.Http/Radarr.Http.csproj | 2 +- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/src/NzbDrone.Common/Radarr.Common.csproj b/src/NzbDrone.Common/Radarr.Common.csproj index 02944054d3..eb1cc9eb41 100644 --- a/src/NzbDrone.Common/Radarr.Common.csproj +++ b/src/NzbDrone.Common/Radarr.Common.csproj @@ -5,14 +5,14 @@ - + - - - - + + + + diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 33f37e0a5d..fe9167364f 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -7,8 +7,8 @@ - - + + @@ -20,9 +20,9 @@ - + - + diff --git a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj index 6496d4b058..cdb1bdf1c0 100644 --- a/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj +++ b/src/NzbDrone.Test.Common/Radarr.Test.Common.csproj @@ -6,7 +6,7 @@ - + diff --git a/src/NzbDrone.Update/Radarr.Update.csproj b/src/NzbDrone.Update/Radarr.Update.csproj index 489f0c3c0e..8edbe598a9 100644 --- a/src/NzbDrone.Update/Radarr.Update.csproj +++ b/src/NzbDrone.Update/Radarr.Update.csproj @@ -6,9 +6,9 @@ - + - \ No newline at end of file + diff --git a/src/NzbDrone.Windows/Radarr.Windows.csproj b/src/NzbDrone.Windows/Radarr.Windows.csproj index 0c5b8ca284..824b22b849 100644 --- a/src/NzbDrone.Windows/Radarr.Windows.csproj +++ b/src/NzbDrone.Windows/Radarr.Windows.csproj @@ -4,10 +4,10 @@ true - + - \ No newline at end of file + diff --git a/src/Radarr.Api.V3/Radarr.Api.V3.csproj b/src/Radarr.Api.V3/Radarr.Api.V3.csproj index 4a25c8f6e9..25f1e025ad 100644 --- a/src/Radarr.Api.V3/Radarr.Api.V3.csproj +++ b/src/Radarr.Api.V3/Radarr.Api.V3.csproj @@ -4,8 +4,8 @@ - - + + diff --git a/src/Radarr.Http/Radarr.Http.csproj b/src/Radarr.Http/Radarr.Http.csproj index 1c7991aa9c..fec98212ab 100644 --- a/src/Radarr.Http/Radarr.Http.csproj +++ b/src/Radarr.Http/Radarr.Http.csproj @@ -5,7 +5,7 @@ - + From a2b38c5b7d8de16b4c844c4406b39de9d20f19ea Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 15 Nov 2024 04:59:25 +0200 Subject: [PATCH 109/579] New: Labels support for Transmission 4.0 (cherry picked from commit 675e3cd38a14ea33c27f2d66a4be2bf802e17d88) --- .../Extensions/IEnumerableExtensions.cs | 5 - .../TransmissionTests/TransmissionFixture.cs | 10 +- .../TransmissionFixtureBase.cs | 5 +- .../Clients/Transmission/Transmission.cs | 48 ++++++- .../Clients/Transmission/TransmissionBase.cs | 62 ++++++--- .../Clients/Transmission/TransmissionProxy.cs | 123 +++++++++++++----- .../Transmission/TransmissionSettings.cs | 12 +- .../Transmission/TransmissionTorrent.cs | 3 + .../Download/Clients/Vuze/Vuze.cs | 5 +- 9 files changed, 200 insertions(+), 73 deletions(-) diff --git a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs index 4e592c5755..6eb544c1da 100644 --- a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs +++ b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs @@ -148,10 +148,5 @@ public static string ConcatToString(this IEnumerable source, F { return string.Join(separator, source.Select(predicate)); } - - public static HashSet ToHashSet(this IEnumerable source, IEqualityComparer comparer = null) - { - return new HashSet(source, comparer); - } } } diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs index faa7daa1bf..8786961cd3 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixture.cs @@ -13,6 +13,14 @@ namespace NzbDrone.Core.Test.Download.DownloadClientTests.TransmissionTests [TestFixture] public class TransmissionFixture : TransmissionFixtureBase { + [SetUp] + public void Setup_Transmission() + { + Mocker.GetMock() + .Setup(v => v.GetClientVersion(It.IsAny(), It.IsAny())) + .Returns("4.0.6"); + } + [Test] public void queued_item_should_have_required_properties() { @@ -272,7 +280,7 @@ public void should_fix_forward_slashes() public void should_only_check_version_number(string version) { Mocker.GetMock() - .Setup(s => s.GetClientVersion(It.IsAny())) + .Setup(s => s.GetClientVersion(It.IsAny(), true)) .Returns(version); Subject.Test().IsValid.Should().BeTrue(); diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixtureBase.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixtureBase.cs index d6e2db822a..4d4ad679ea 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixtureBase.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/TransmissionTests/TransmissionFixtureBase.cs @@ -29,7 +29,8 @@ public void Setup() Host = "127.0.0.1", Port = 2222, Username = "admin", - Password = "pass" + Password = "pass", + MovieCategory = "" }; Subject.Definition = new DownloadClientDefinition(); @@ -152,7 +153,7 @@ protected virtual void GivenTorrents(List torrents) } Mocker.GetMock() - .Setup(s => s.GetTorrents(It.IsAny())) + .Setup(s => s.GetTorrents(null, It.IsAny())) .Returns(torrents); } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs index 1cfc134c55..23f3a4f4c8 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/Transmission.cs @@ -1,9 +1,11 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Text.RegularExpressions; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; +using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Core.Blocklisting; using NzbDrone.Core.Configuration; @@ -15,6 +17,9 @@ namespace NzbDrone.Core.Download.Clients.Transmission { public class Transmission : TransmissionBase { + public override string Name => "Transmission"; + public override bool SupportsLabels => HasClientVersion(4, 0); + public Transmission(ITransmissionProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, IHttpClient httpClient, @@ -28,9 +33,48 @@ public Transmission(ITransmissionProxy proxy, { } + public override void MarkItemAsImported(DownloadClientItem downloadClientItem) + { + if (!SupportsLabels) + { + throw new NotSupportedException($"{Name} does not support marking items as imported"); + } + + // set post-import category + if (Settings.MovieImportedCategory.IsNotNullOrWhiteSpace() && + Settings.MovieImportedCategory != Settings.MovieCategory) + { + var hash = downloadClientItem.DownloadId.ToLowerInvariant(); + var torrent = _proxy.GetTorrents(new[] { hash }, Settings).FirstOrDefault(); + + if (torrent == null) + { + _logger.Warn("Could not find torrent with hash \"{0}\" in Transmission.", hash); + return; + } + + try + { + var labels = torrent.Labels.ToHashSet(StringComparer.InvariantCultureIgnoreCase); + labels.Add(Settings.MovieImportedCategory); + + if (Settings.MovieCategory.IsNotNullOrWhiteSpace()) + { + labels.Remove(Settings.MovieCategory); + } + + _proxy.SetTorrentLabels(hash, labels, Settings); + } + catch (DownloadClientException ex) + { + _logger.Warn(ex, "Failed to set post-import torrent label \"{0}\" for {1} in Transmission.", Settings.MovieImportedCategory, downloadClientItem.Title); + } + } + } + protected override ValidationFailure ValidateVersion() { - var versionString = _proxy.GetClientVersion(Settings); + var versionString = _proxy.GetClientVersion(Settings, true); _logger.Debug("Transmission version information: {0}", versionString); @@ -44,7 +88,5 @@ protected override ValidationFailure ValidateVersion() return null; } - - public override string Name => "Transmission"; } } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs index 61a342506b..441d3d3c4f 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionBase.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Text.RegularExpressions; using FluentValidation.Results; using NLog; using NzbDrone.Common.Disk; @@ -18,6 +19,8 @@ namespace NzbDrone.Core.Download.Clients.Transmission { public abstract class TransmissionBase : TorrentClientBase { + public abstract bool SupportsLabels { get; } + protected readonly ITransmissionProxy _proxy; public TransmissionBase(ITransmissionProxy proxy, @@ -37,7 +40,7 @@ public TransmissionBase(ITransmissionProxy proxy, public override IEnumerable GetItems() { var configFunc = new Lazy(() => _proxy.GetConfig(Settings)); - var torrents = _proxy.GetTorrents(Settings); + var torrents = _proxy.GetTorrents(null, Settings); var items = new List(); @@ -45,36 +48,45 @@ public override IEnumerable GetItems() { var outputPath = new OsPath(torrent.DownloadDir); - if (Settings.MovieDirectory.IsNotNullOrWhiteSpace()) + if (Settings.MovieCategory.IsNotNullOrWhiteSpace() && SupportsLabels && torrent.Labels is { Count: > 0 }) { - if (!new OsPath(Settings.MovieDirectory).Contains(outputPath)) + if (!torrent.Labels.Contains(Settings.MovieCategory, StringComparer.InvariantCultureIgnoreCase)) { continue; } } - else if (Settings.MovieCategory.IsNotNullOrWhiteSpace()) + else { - var directories = outputPath.FullPath.Split('\\', '/'); - if (!directories.Contains(Settings.MovieCategory)) + if (Settings.MovieDirectory.IsNotNullOrWhiteSpace()) { - continue; + if (!new OsPath(Settings.MovieDirectory).Contains(outputPath)) + { + continue; + } + } + else if (Settings.MovieCategory.IsNotNullOrWhiteSpace()) + { + var directories = outputPath.FullPath.Split('\\', '/'); + if (!directories.Contains(Settings.MovieCategory)) + { + continue; + } } } outputPath = _remotePathMappingService.RemapRemoteToLocal(Settings.Host, outputPath); - var item = new DownloadClientItem(); - item.DownloadId = torrent.HashString.ToUpper(); - item.Category = Settings.MovieCategory; - item.Title = torrent.Name; - - item.DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, false); - - item.OutputPath = GetOutputPath(outputPath, torrent); - item.TotalSize = torrent.TotalSize; - item.RemainingSize = torrent.LeftUntilDone; - item.SeedRatio = torrent.DownloadedEver <= 0 ? 0 : - (double)torrent.UploadedEver / torrent.DownloadedEver; + var item = new DownloadClientItem + { + DownloadId = torrent.HashString.ToUpper(), + Category = Settings.MovieCategory, + Title = torrent.Name, + DownloadClientInfo = DownloadClientItemClientInfo.FromDownloadClient(this, Settings.MovieImportedCategory.IsNotNullOrWhiteSpace() && SupportsLabels), + OutputPath = GetOutputPath(outputPath, torrent), + TotalSize = torrent.TotalSize, + RemainingSize = torrent.LeftUntilDone, + SeedRatio = torrent.DownloadedEver <= 0 ? 0 : (double)torrent.UploadedEver / torrent.DownloadedEver + }; if (torrent.Eta >= 0) { @@ -300,7 +312,7 @@ private ValidationFailure TestGetTorrents() { try { - _proxy.GetTorrents(Settings); + _proxy.GetTorrents(null, Settings); } catch (Exception ex) { @@ -310,5 +322,15 @@ private ValidationFailure TestGetTorrents() return null; } + + protected bool HasClientVersion(int major, int minor) + { + var rawVersion = _proxy.GetClientVersion(Settings); + + var versionResult = Regex.Match(rawVersion, @"(?= new Version(major, minor); + } } } diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs index 45190fb16a..2de2b26e74 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs @@ -1,5 +1,8 @@ using System; using System.Collections.Generic; +using System.Collections.Immutable; +using System.Collections.ObjectModel; +using System.Linq; using System.Net; using Newtonsoft.Json.Linq; using NLog; @@ -12,15 +15,16 @@ namespace NzbDrone.Core.Download.Clients.Transmission { public interface ITransmissionProxy { - List GetTorrents(TransmissionSettings settings); + IReadOnlyCollection GetTorrents(IReadOnlyCollection hashStrings, TransmissionSettings settings); void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings); void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings); void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration seedConfiguration, TransmissionSettings settings); TransmissionConfig GetConfig(TransmissionSettings settings); string GetProtocolVersion(TransmissionSettings settings); - string GetClientVersion(TransmissionSettings settings); + string GetClientVersion(TransmissionSettings settings, bool force = false); void RemoveTorrent(string hash, bool removeData, TransmissionSettings settings); void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings); + void SetTorrentLabels(string hash, IEnumerable labels, TransmissionSettings settings); } public class TransmissionProxy : ITransmissionProxy @@ -28,50 +32,66 @@ public class TransmissionProxy : ITransmissionProxy private readonly IHttpClient _httpClient; private readonly Logger _logger; - private ICached _authSessionIDCache; + private readonly ICached _authSessionIdCache; + private readonly ICached _versionCache; public TransmissionProxy(ICacheManager cacheManager, IHttpClient httpClient, Logger logger) { _httpClient = httpClient; _logger = logger; - _authSessionIDCache = cacheManager.GetCache(GetType(), "authSessionID"); + _authSessionIdCache = cacheManager.GetCache(GetType(), "authSessionID"); + _versionCache = cacheManager.GetCache(GetType(), "versions"); } - public List GetTorrents(TransmissionSettings settings) + public IReadOnlyCollection GetTorrents(IReadOnlyCollection hashStrings, TransmissionSettings settings) { - var result = GetTorrentStatus(settings); + var result = GetTorrentStatus(hashStrings, settings); - var torrents = ((JArray)result.Arguments["torrents"]).ToObject>(); + var torrents = ((JArray)result.Arguments["torrents"]).ToObject>(); return torrents; } public void AddTorrentFromUrl(string torrentUrl, string downloadDirectory, TransmissionSettings settings) { - var arguments = new Dictionary(); - arguments.Add("filename", torrentUrl); - arguments.Add("paused", settings.AddPaused); + var arguments = new Dictionary + { + { "filename", torrentUrl }, + { "paused", settings.AddPaused } + }; if (!downloadDirectory.IsNullOrWhiteSpace()) { arguments.Add("download-dir", downloadDirectory); } + if (settings.MovieCategory.IsNotNullOrWhiteSpace()) + { + arguments.Add("labels", new List { settings.MovieCategory }); + } + ProcessRequest("torrent-add", arguments, settings); } public void AddTorrentFromData(byte[] torrentData, string downloadDirectory, TransmissionSettings settings) { - var arguments = new Dictionary(); - arguments.Add("metainfo", Convert.ToBase64String(torrentData)); - arguments.Add("paused", settings.AddPaused); + var arguments = new Dictionary + { + { "metainfo", Convert.ToBase64String(torrentData) }, + { "paused", settings.AddPaused } + }; if (!downloadDirectory.IsNullOrWhiteSpace()) { arguments.Add("download-dir", downloadDirectory); } + if (settings.MovieCategory.IsNotNullOrWhiteSpace()) + { + arguments.Add("labels", new List { settings.MovieCategory }); + } + ProcessRequest("torrent-add", arguments, settings); } @@ -82,8 +102,10 @@ public void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration return; } - var arguments = new Dictionary(); - arguments.Add("ids", new[] { hash }); + var arguments = new Dictionary + { + { "ids", new List { hash } } + }; if (seedConfiguration.Ratio != null) { @@ -97,6 +119,12 @@ public void SetTorrentSeedingConfiguration(string hash, TorrentSeedConfiguration arguments.Add("seedIdleMode", 1); } + // Avoid extraneous request if no limits are to be set + if (arguments.All(arg => arg.Key == "ids")) + { + return; + } + ProcessRequest("torrent-set", arguments, settings); } @@ -107,11 +135,16 @@ public string GetProtocolVersion(TransmissionSettings settings) return config.RpcVersion; } - public string GetClientVersion(TransmissionSettings settings) + public string GetClientVersion(TransmissionSettings settings, bool force = false) { - var config = GetConfig(settings); + var cacheKey = $"version:{$"{GetBaseUrl(settings)}:{settings.Password}".SHA256Hash()}"; - return config.Version; + if (force) + { + _versionCache.Remove(cacheKey); + } + + return _versionCache.Get(cacheKey, () => GetConfig(settings).Version, TimeSpan.FromHours(6)); } public TransmissionConfig GetConfig(TransmissionSettings settings) @@ -124,21 +157,36 @@ public TransmissionConfig GetConfig(TransmissionSettings settings) public void RemoveTorrent(string hashString, bool removeData, TransmissionSettings settings) { - var arguments = new Dictionary(); - arguments.Add("ids", new string[] { hashString }); - arguments.Add("delete-local-data", removeData); + var arguments = new Dictionary + { + { "ids", new List { hashString } }, + { "delete-local-data", removeData } + }; ProcessRequest("torrent-remove", arguments, settings); } public void MoveTorrentToTopInQueue(string hashString, TransmissionSettings settings) { - var arguments = new Dictionary(); - arguments.Add("ids", new string[] { hashString }); + var arguments = new Dictionary + { + { "ids", new List { hashString } } + }; ProcessRequest("queue-move-top", arguments, settings); } + public void SetTorrentLabels(string hash, IEnumerable labels, TransmissionSettings settings) + { + var arguments = new Dictionary + { + { "ids", new List { hash } }, + { "labels", labels.ToImmutableHashSet() } + }; + + ProcessRequest("torrent-set", arguments, settings); + } + private TransmissionResponse GetSessionVariables(TransmissionSettings settings) { // Retrieve transmission information such as the default download directory, bandwidth throttling and seed ratio. @@ -151,14 +199,9 @@ private TransmissionResponse GetSessionStatistics(TransmissionSettings settings) return ProcessRequest("session-stats", null, settings); } - private TransmissionResponse GetTorrentStatus(TransmissionSettings settings) - { - return GetTorrentStatus(null, settings); - } - private TransmissionResponse GetTorrentStatus(IEnumerable hashStrings, TransmissionSettings settings) { - var fields = new string[] + var fields = new List { "id", "hashString", // Unique torrent ID. Use this instead of the client id? @@ -179,11 +222,14 @@ private TransmissionResponse GetTorrentStatus(IEnumerable hashStrings, T "seedIdleLimit", "seedIdleMode", "fileCount", - "file-count" + "file-count", + "labels" }; - var arguments = new Dictionary(); - arguments.Add("fields", fields); + var arguments = new Dictionary + { + { "fields", fields } + }; if (hashStrings != null) { @@ -195,9 +241,14 @@ private TransmissionResponse GetTorrentStatus(IEnumerable hashStrings, T return result; } + private string GetBaseUrl(TransmissionSettings settings) + { + return HttpRequestBuilder.BuildBaseUrl(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase); + } + private HttpRequestBuilder BuildRequest(TransmissionSettings settings) { - var requestBuilder = new HttpRequestBuilder(settings.UseSsl, settings.Host, settings.Port, settings.UrlBase) + var requestBuilder = new HttpRequestBuilder(GetBaseUrl(settings)) .Resource("rpc") .Accept(HttpAccept.Json); @@ -212,11 +263,11 @@ private void AuthenticateClient(HttpRequestBuilder requestBuilder, TransmissionS { var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password); - var sessionId = _authSessionIDCache.Find(authKey); + var sessionId = _authSessionIdCache.Find(authKey); if (sessionId == null || reauthenticate) { - _authSessionIDCache.Remove(authKey); + _authSessionIdCache.Remove(authKey); var authLoginRequest = BuildRequest(settings).Build(); authLoginRequest.SuppressHttpError = true; @@ -244,7 +295,7 @@ private void AuthenticateClient(HttpRequestBuilder requestBuilder, TransmissionS _logger.Debug("Transmission authentication succeeded."); - _authSessionIDCache.Set(authKey, sessionId); + _authSessionIdCache.Set(authKey, sessionId); } requestBuilder.SetHeader("X-Transmission-Session-Id", sessionId); diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs index ae9be1acdc..9e8c86e9d7 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs @@ -32,6 +32,7 @@ public TransmissionSettings() Host = "localhost"; Port = 9091; UrlBase = "/transmission/"; + MovieCategory = "radarr"; } [FieldDefinition(0, Label = "Host", Type = FieldType.Textbox)] @@ -59,16 +60,19 @@ public TransmissionSettings() [FieldDefinition(6, Label = "Category", Type = FieldType.Textbox, HelpText = "DownloadClientSettingsCategorySubFolderHelpText")] public string MovieCategory { get; set; } - [FieldDefinition(7, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientTransmissionSettingsDirectoryHelpText")] + [FieldDefinition(7, Label = "PostImportCategory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientSettingsPostImportCategoryHelpText")] + public string MovieImportedCategory { get; set; } + + [FieldDefinition(8, Label = "Directory", Type = FieldType.Textbox, Advanced = true, HelpText = "DownloadClientTransmissionSettingsDirectoryHelpText")] public string MovieDirectory { get; set; } - [FieldDefinition(8, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsRecentPriorityMovieHelpText")] + [FieldDefinition(9, Label = "DownloadClientSettingsRecentPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsRecentPriorityMovieHelpText")] public int RecentMoviePriority { get; set; } - [FieldDefinition(9, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")] + [FieldDefinition(10, Label = "DownloadClientSettingsOlderPriority", Type = FieldType.Select, SelectOptions = typeof(TransmissionPriority), HelpText = "DownloadClientSettingsOlderPriorityMovieHelpText")] public int OlderMoviePriority { get; set; } - [FieldDefinition(10, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] + [FieldDefinition(11, Label = "DownloadClientSettingsAddPaused", Type = FieldType.Checkbox)] public bool AddPaused { get; set; } public override NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs index 4e66b7a02a..687bab40b3 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionTorrent.cs @@ -1,3 +1,5 @@ +using System; +using System.Collections.Generic; using Newtonsoft.Json; namespace NzbDrone.Core.Download.Clients.Transmission @@ -11,6 +13,7 @@ public class TransmissionTorrent public long TotalSize { get; set; } public long LeftUntilDone { get; set; } public bool IsFinished { get; set; } + public IReadOnlyCollection Labels { get; set; } = Array.Empty(); public long Eta { get; set; } public TransmissionTorrentStatus Status { get; set; } public long SecondsDownloading { get; set; } diff --git a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs index 234ec43c21..2c5a84d60f 100644 --- a/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs +++ b/src/NzbDrone.Core/Download/Clients/Vuze/Vuze.cs @@ -15,6 +15,9 @@ public class Vuze : TransmissionBase { private const int MINIMUM_SUPPORTED_PROTOCOL_VERSION = 14; + public override string Name => "Vuze"; + public override bool SupportsLabels => false; + public Vuze(ITransmissionProxy proxy, ITorrentFileInfoReader torrentFileInfoReader, IHttpClient httpClient, @@ -67,7 +70,5 @@ protected override ValidationFailure ValidateVersion() return null; } - - public override string Name => "Vuze"; } } From 6ac9cca9532b3257a6084ffbb455dca8dae5453a Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 27 Nov 2024 23:55:50 +0200 Subject: [PATCH 110/579] Avoid default category on existing Transmission configurations Co-authored-by: Mark McDowall (cherry picked from commit bd656ae7f66fc9224ef2a57857152ee5d54d54f8) --- .../Clients/Transmission/TransmissionSettings.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs index 9e8c86e9d7..ffb16e9d1d 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionSettings.cs @@ -1,3 +1,4 @@ +using System.Text.Json.Serialization; using System.Text.RegularExpressions; using FluentValidation; using NzbDrone.Common.Extensions; @@ -27,6 +28,7 @@ public class TransmissionSettings : DownloadClientSettingsBase Date: Mon, 2 Dec 2024 15:29:50 +0200 Subject: [PATCH 111/579] Add return type for movie lookup and import endpoints Closes #10737 --- src/Radarr.Api.V3/Movies/MovieImportController.cs | 4 +++- src/Radarr.Api.V3/Movies/MovieLookupController.cs | 9 ++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Radarr.Api.V3/Movies/MovieImportController.cs b/src/Radarr.Api.V3/Movies/MovieImportController.cs index c7078288d6..f923a43657 100644 --- a/src/Radarr.Api.V3/Movies/MovieImportController.cs +++ b/src/Radarr.Api.V3/Movies/MovieImportController.cs @@ -29,7 +29,9 @@ protected override MovieResource GetResourceById(int id) } [HttpPost] - public object Import([FromBody] List resource) + [Consumes("application/json")] + [Produces("application/json")] + public IEnumerable Import([FromBody] List resource) { var newMovies = resource.ToModel(); diff --git a/src/Radarr.Api.V3/Movies/MovieLookupController.cs b/src/Radarr.Api.V3/Movies/MovieLookupController.cs index 7b7d117472..3d8729e188 100644 --- a/src/Radarr.Api.V3/Movies/MovieLookupController.cs +++ b/src/Radarr.Api.V3/Movies/MovieLookupController.cs @@ -54,7 +54,8 @@ protected override MovieResource GetResourceById(int id) } [HttpGet("tmdb")] - public object SearchByTmdbId(int tmdbId) + [Produces("application/json")] + public MovieResource SearchByTmdbId(int tmdbId) { var availDelay = _configService.AvailabilityDelay; var result = new Movie { MovieMetadata = _movieInfo.GetMovieInfo(tmdbId).Item1 }; @@ -63,7 +64,8 @@ public object SearchByTmdbId(int tmdbId) } [HttpGet("imdb")] - public object SearchByImdbId(string imdbId) + [Produces("application/json")] + public MovieResource SearchByImdbId(string imdbId) { var result = new Movie { MovieMetadata = _movieInfo.GetMovieByImdbId(imdbId) }; @@ -73,7 +75,8 @@ public object SearchByImdbId(string imdbId) } [HttpGet] - public object Search([FromQuery] string term) + [Produces("application/json")] + public IEnumerable Search([FromQuery] string term) { var searchResults = _searchProxy.SearchForNewMovie(term); From 348c29c9d782e10fe1f7c785f157529c87e5c1a3 Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 2 Dec 2024 00:31:38 +0000 Subject: [PATCH 112/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Ardenet <1213193613@qq.com> Co-authored-by: Languages add-on Co-authored-by: Robin Dadswell Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: mryx007 Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/de.json | 844 ++++++++++++------ .../Localization/Core/zh_CN.json | 8 +- .../Core/{zh_HANS.json => zh_Hans.json} | 2 +- 3 files changed, 585 insertions(+), 269 deletions(-) rename src/NzbDrone.Core/Localization/Core/{zh_HANS.json => zh_Hans.json} (100%) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 9af5e9beb2..8bbfc4db94 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -33,25 +33,25 @@ "DownloadClientCheckUnableToCommunicateMessage": "Kommunikation mit {downloadClientName} nicht möglich.", "DownloadClientStatusCheckAllClientMessage": "Alle Download Clients sind aufgrund von Fehlern nicht verfügbar", "DownloadClientStatusCheckSingleClientMessage": "Download Clients aufgrund von Fehlern nicht verfügbar: {downloadClientNames}", - "DownloadClients": "Downloader", + "DownloadClients": "Download Clients", "Downloaded": "Heruntergeladen", "Edit": "Bearbeiten", - "Events": "Events", + "Events": "Ereignisse", "FailedDownloadHandling": "Verarbeitung fehlgeschlagener Downloads", "FileManagement": "Dateiverwaltung", "Files": "Dateien", "Filter": "Filter", "Folder": "Ordner", - "Forecast": "Prognose", + "Forecast": "Vorhersage", "Formats": "Formate", - "FreeSpace": "Freier Speicher", + "FreeSpace": "Freier Platz", "General": "Allgemein", - "GrabSelected": "Auswahl erfassen", - "Health": "Zustandsüberwachung", - "HideAdvanced": "Erweiterte Ansicht", + "GrabSelected": "Auswahl abrufen", + "Health": "Gesundheit", + "HideAdvanced": "Erweiterte Einstellungen ausblenden", "History": "Verlauf", "Host": "Host", - "Import": "Importieren", + "Import": "Import", "ImportHeader": "Importiere eine bereits vorhandene organisierte Mediathek um Filme hinzuzufügen", "ImportMechanismHealthCheckMessage": "Aktiviere die Verarbeitung der abgeschlossenen Downloads", "ImportTipsMessage": "Einige Tipps um sicherzustellen, dass der Import reibungslos verläuft:", @@ -64,9 +64,9 @@ "IndexerStatusCheckSingleClientMessage": "Indexer aufgrund von Fehlern nicht verfügbar: {indexerNames}", "Indexers": "Indexer", "Languages": "Sprachen", - "ImportListExclusions": "Listenausschlüsse", - "ImportLists": "Listen", - "LogFiles": "Protokolle", + "ImportListExclusions": "Ausschlüsse aus der Importliste", + "ImportLists": "Importlisten", + "LogFiles": "Protokolldateien", "Logging": "Protokollierung", "ManualImport": "Manueller Import", "MediaManagement": "Medienverwaltung", @@ -74,7 +74,7 @@ "MinAvailability": "Min. Verfügbarkeit", "MinimumAvailability": "Mindestverfügbarkeit", "Missing": "Fehlend", - "Monitor": "Beobachten", + "Monitor": "Überwachen", "Month": "Monat", "MoreInfo": "Mehr Infos", "MountMovieHealthCheckMessage": "Der Einhängepunkt, welcher einen Filmpfad enthält, ist schreibgeschützt eingehängt: ", @@ -89,7 +89,7 @@ "NoChanges": "Keine Änderungen", "Options": "Optionen", "Path": "Pfad", - "PreviewRename": "Umbenennen", + "PreviewRename": "Vorschau Umbenennung", "Profiles": "Profile", "Proxy": "Proxy", "ProxyCheckBadRequestMessage": "Proxy konnte nicht getestet werden. StatusCode: {statusCode}", @@ -106,23 +106,23 @@ "RefreshAndScan": "Aktualisieren und scannen", "ReleaseBranchCheckOfficialBranchMessage": "Zweig {0} ist kein gültiger {appName}-Release-Zweig. Sie erhalten keine Updates", "RemotePathMappings": "Remote-Pfadzuordnungen", - "RemoveSelected": "Auswahl entfernen", + "RemoveSelected": "Ausgewählte entfernen", "RemovedMovieCheckMultipleMessage": "Filme {movies} wurden aus TMDb entfernt", "RemovedMovieCheckSingleMessage": "Film {movie} wurde aus TMDb entfernt", "RenameFiles": "Dateien umbenennen", "RestoreBackup": "Sicherung wiederherstellen", "Restrictions": "Beschränkungen", - "RootFolder": "Stammordner", + "RootFolder": "Root-Ordner", "RootFolderCheckMultipleMessage": "Es fehlen mehrere Stammordner: {rootFolderPaths}", "RootFolderCheckSingleMessage": "Fehlender Stammordner: {rootFolderPath}", - "RootFolders": "Stammordner", + "RootFolders": "Root-Ordner", "SaveChanges": "Änderungen speichern", "Scheduled": "Geplant", - "Search": "Suche", - "SearchAll": "Suche alle", + "Search": "Suchen", + "SearchAll": "Alle durchsuchen", "SearchFiltered": "Suche gefilterte", - "SearchForMissing": "Suche fehlende", - "SearchSelected": "Auswahl suchen", + "SearchForMissing": "Suche nach fehlenden Episoden", + "SearchSelected": "Ausgewählte durchsuchen", "Security": "Sicherheit", "SelectAll": "Alle wählen", "SetTags": "Tags festlegen", @@ -159,7 +159,7 @@ "Size": "Größe", "Runtime": "Laufzeit", "Renamed": "Umbenannt", - "ReleaseTitle": "Release Titel", + "ReleaseTitle": "Release-Titel", "ReleaseStatus": "Releasestatus", "ReleaseGroup": "Release-Gruppe", "Ratings": "Bewertung", @@ -170,23 +170,23 @@ "PhysicalRelease": "VÖ Disc", "OutputPath": "Ausgabe-Pfad", "MovieTitle": "Filmtitel", - "MonitoredOnly": "Nur beobachtete", + "MonitoredOnly": "Nur überwacht", "MetadataSettingsMovieSummary": "Erstelle Metadaten wenn Filme importiert oder aktualisiert werden", "MassMovieSearch": "Massen Filmsuche", - "ImportListsSettingsSummary": "Listen importieren, Listenausschlüsse", - "LastWriteTime": "Zuletzt beschrieben", + "ImportListsSettingsSummary": "Importiere von einer anderen {appName}-Instanz oder Trakt-Listen und verwalte Listen-Ausschlüsse", + "LastWriteTime": "Letzte Schreibzeit", "IndexersSettingsSummary": "Indexer- und Releasebeschränkungen", "Indexer": "Indexer", "InCinemas": "VÖ Kino", "Imported": "Importiert", "Ignored": "Ignoriert", - "DownloadClientsSettingsSummary": "Download Clients, Downloadverarbeitung und Remote-Pfadzuordnungen", - "Grabbed": "Erfasste", + "DownloadClientsSettingsSummary": "Download Clients, Download-Verwaltung und Remote-Pfadzuordnungen", + "Grabbed": "Geholt", "Genres": "Genres", - "GeneralSettingsSummary": "Port, SSL, Benutzername/Passwort, Proxy, Analytik und Updates", + "GeneralSettingsSummary": "Port, SSL, Benutzername/Kennwort, Proxy, Analyse und Updates", "Filename": "Dateiname", "Failed": "Fehlgeschlagen", - "EventType": "Event Typ", + "EventType": "Ereignistyp", "DigitalRelease": "VÖ Digital", "Details": "Einzelheiten", "Deleted": "Gelöscht", @@ -208,26 +208,26 @@ "TestAll": "Alle prüfen", "Test": "Prüfen", "TableOptionsColumnsMessage": "Wähle aus welche Spalten angezeigt werden und in welcher Reihenfolge", - "TableOptions": "Tabellen Optionen", + "TableOptions": "Tabellenoptionen", "Source": "Quelle", "Shutdown": "Herunterfahren", "Seeders": "Seeders", "Save": "Speichern", "Restart": "Neu starten", - "RemoveRootFolder": "Stammverzeichnis entfernen", - "Reload": "Neuladen", + "RemoveRootFolder": "Root-Ordner entfernen", + "Reload": "Neu laden", "RelativePath": "Relativer Pfad", "RejectionCount": "Anzahl der Ablehnungen", "Peers": "Peers", "Organize": "Organisieren", - "Ok": "OK", + "Ok": "Ok", "OAuthPopupMessage": "Dein Browser blockiert Pop-ups", "Name": "Name", "MoveFiles": "Dateien verschieben", - "Monitored": "Beobachtet", + "Monitored": "Überwacht", "Message": "Nachricht", - "Location": "Speicherort", - "Level": "Stufe", + "Location": "Standort", + "Level": "Level", "KeyboardShortcuts": "Tastenkürzel", "ImportExistingMovies": "Vorhandene Filme importieren", "Info": "Info", @@ -246,49 +246,49 @@ "AllMoviesHiddenDueToFilter": "Alle Filme sind wegen dem Filter ausgeblendet.", "Age": "Alter", "AddNewMovie": "Neuen Film hinzufügen", - "SystemTimeHealthCheckMessage": "Die Systemzeit ist um einen Tag versetzt. Bis die Zeit korrigiert wurde, könnten die geplanten Aufgaben nicht korrekt ausgeführt werden", + "SystemTimeHealthCheckMessage": "Die Systemzeit ist mehr als einen Tag abweichend. Geplante Aufgaben könnten nicht korrekt ausgeführt werden, bis die Zeit korrigiert ist.", "UnsavedChanges": "Nicht gespeicherte Änderungen", "Table": "Tabelle", "ShowTitle": "Titel anzeigen", "ShowStudio": "Studio anzeigen", - "ShowSizeOnDisk": "Belegter Speicherplatz anzeigen", - "ShowSearchHelpText": "Suchbutton anzeigen beim draufzeigen", + "ShowSizeOnDisk": "Größe auf der Festplatte anzeigen", + "ShowSearchHelpText": "Suchschaltfläche beim Überfahren anzeigen", "ShowSearch": "Suche anzeigen", - "ShowQualityProfile": "Qualitätsdefinition anzeigen", + "ShowQualityProfile": "Qualitätsprofil anzeigen", "ShowPath": "Pfad anzeigen", "ShowDateAdded": "Datum der Hinzufügung anzeigen", "WeekColumnHeaderHelpText": "Wird in der Wochenansicht über jeder Spalte angezeigt", - "WeekColumnHeader": "Wochen Spalten Titel", + "WeekColumnHeader": "Spaltenüberschrift „Woche“.", "TimeFormat": "Zeitformat", - "ShowRelativeDatesHelpText": "Relatives (z.B.: Heute, gestern, etc) oder absolutes Datum anzeigen", - "ShowRelativeDates": "Relatives Datum anzeigen", + "ShowRelativeDatesHelpText": "Relative (Heute/Gestern/etc.) oder absolute Daten anzeigen", + "ShowRelativeDates": "Relative Daten anzeigen", "ShortDateFormat": "Kurzes Datumsformat", - "RemotePathMappingRemotePathHelpText": "Root-Pfad zum Verzeichnis, auf das der Download-Client zugreift", - "RemotePathMappingLocalPathHelpText": "Pfad, den {appName} verwenden sollte, um lokal auf den Entfernten-Pfad zuzugreifen", - "RemotePath": "Entfernter-Pfad", + "RemotePathMappingRemotePathHelpText": "Root-Pfad zu dem Verzeichnis, auf das der Download-Client zugreift.", + "RemotePathMappingLocalPathHelpText": "Pfad, den {appName} verwenden soll, um auf den Remote-Pfad lokal zuzugreifen.", + "RemotePath": "Remote-Pfad", "LocalPath": "Lokaler Pfad", "RemotePathMappingHostHelpText": "Derselbe Host, den du für den Remote-Download-Client angegeben hast", "LongDateFormat": "Langes Datumsformat", "FirstDayOfWeek": "Erster Tag der Woche", - "EnableColorImpairedMode": "Farbbeeinträchtigter Modus aktivieren", - "EnableColorImpairedModeHelpText": "Alternativer Stil, um farbbeeinträchtigten Benutzern eine bessere Unterscheidung farbcodierter Informationen zu ermöglichen", + "EnableColorImpairedMode": "Farbenblindmodus aktivieren", + "EnableColorImpairedModeHelpText": "Stiländerung, um es Farbenblinden Benutzern zu ermöglichen, farbcodierte Informationen besser zu unterscheiden", "SelectFolder": "Ordner auswählen", "SearchOnAdd": "Beim hinzufügen suchen", "SearchMovie": "Film suchen", - "RecentFolders": "Letzte Ordner", + "RecentFolders": "Kürzliche Ordner", "QuickImport": "Automatisch verschieben", - "PosterSize": "Plakatgröße", - "Posters": "Plakate", - "PosterOptions": "Poster Optionen", - "PendingChangesStayReview": "Auf der Seite bleiben", - "PendingChangesMessage": "Es gibt noch ungespeicherte Änderungen, bist du sicher, dass du die Seite verlassen möchtest?", - "PendingChangesDiscardChanges": "Änderungen verwerfen und schließen", - "OverviewOptions": "Übersichts Optionen", - "Overview": "Übersicht", + "PosterSize": "Postergröße", + "Posters": "Poster", + "PosterOptions": "Poster-Optionen", + "PendingChangesStayReview": "Bleiben und Änderungen überprüfen", + "PendingChangesMessage": "Du hast ungespeicherte Änderungen, bist du sicher, dass du diese Seite verlassen möchtest?", + "PendingChangesDiscardChanges": "Änderungen verwerfen und verlassen", + "OverviewOptions": "Überblick-Optionen", + "Overview": "Überblick", "MonitorMovie": "Film beobachten", - "InteractiveImport": "Interaktiver Import", + "InteractiveImport": "Interaktive Importe", "ExistingMovies": "Vorhandene Filme", - "EditRemotePathMapping": "Entfernte Pfadzuordnung bearbeiten", + "EditRemotePathMapping": "Remote Pfadzuordnung bearbeiten", "DetailedProgressBarHelpText": "Text auf Fortschrittsbalken anzeigen", "DetailedProgressBar": "Detaillierter Fortschrittsbalken", "AddRemotePathMapping": "Remote Pfad Zuordnung hinzufügen", @@ -304,7 +304,7 @@ "AnalyseVideoFiles": "Video Dateien analysieren", "AppDataDirectory": "AppData-Verzeichnis", "ApplyTags": "Schlagworte anwenden", - "ICalShowAsAllDayEventsHelpText": "Events werden als ganztags Event in deinem Kalender angezeigt", + "ICalShowAsAllDayEventsHelpText": "Ereignisse werden als ganztägige Ereignisse in deinem Kalender angezeigt", "Authentication": "Authentifizierung", "Automatic": "Automatisch", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Auf der Festplatte gelöschte Filme auch automatisch in {appName} nicht mehr beobachten", @@ -355,14 +355,14 @@ "EditMovie": "Film bearbeiten", "EditPerson": "Schausteller bearbeiten", "Enable": "Aktivieren", - "EnableAutomaticAdd": "Automatisch hinzufügen", + "EnableAutomaticAdd": "Automatisches Hinzufügen aktivieren", "EnableAutomaticSearch": "Automatische Suche einschalten", - "EnableCompletedDownloadHandlingHelpText": "Importiere fertige Downloads vom Downloader automatisch", + "EnableCompletedDownloadHandlingHelpText": "Automatischer Import abgeschlossener Downloads vom Download Client", "ListEnabledHelpText": "Aktiviere diese Liste", - "EnableMetadataHelpText": "Metadaten Dateien erstellen für diesen Metadata Typ", + "EnableMetadataHelpText": "Aktiviere die Erstellung von Metadaten-Dateien für diesen Metadaten-Typ", "EnableInteractiveSearch": "Interaktive Suche einschalten", "EnableRss": "RSS aktivieren", - "EnableSsl": "SSL", + "EnableSsl": "SSL aktivieren", "EnableSslHelpText": " Erfordert einen Neustart als Administrator", "Ended": "Beendet", "ChangeFileDateHelpText": "Aktualisiere das Erstelldatum beim Import oder Re-Scan", @@ -371,41 +371,41 @@ "Folders": "Ordner", "FollowPerson": "Schausteller folgen", "GeneralSettings": "Allgemeine Einstellungen", - "Global": "Global", - "Grab": "Erfasse", - "GrabRelease": "Release erfassen", + "Global": "Weltweit", + "Grab": "Holen", + "GrabRelease": "Release holen", "Group": "Gruppe", "Hostname": "Hostname", - "ICalFeed": "iCal-Feed", + "ICalFeed": "iCal Feed", "IconForCutoffUnmet": "Symbol für Schwelle nicht erreicht", "IgnoredAddresses": "Ignorierte Adressen", "IgnoreDeletedMovies": "Gelöschte Filme nicht mehr beobachten", "IllRestartLater": "Später neustarten", - "ImportExtraFiles": "Extra Dateien importieren", + "ImportExtraFiles": "Zusätzliche Dateien importieren", "Importing": "Importiere", "ImportMovies": "Filme importieren", - "IncludeCustomFormatWhenRenaming": "Eigenes Format beim umbennen einfügen", - "IncludeCustomFormatWhenRenamingHelpText": "In {Custom Formats} umbennenungs Format", - "IncludeUnmonitored": "Nicht beobachtete einbeziehen", + "IncludeCustomFormatWhenRenaming": "Benutzerdefiniertes Format beim Umbenennen einbeziehen", + "IncludeCustomFormatWhenRenamingHelpText": "In {Custom Formats} Umbenennungsformat einbeziehen", + "IncludeUnmonitored": "Unüberwachte einbeziehen", "IndexerFlags": "Indexer-Flags", "Interval": "Intervall", "LanguageHelpText": "Sprache für Releases", "Links": "Links", - "ImportListSettings": "Listen Einstellungen", + "ImportListSettings": "Importlisteneinstellungen", "ListSyncLevelHelpText": "Die Filme in der Bibliothek werden auf der Grundlage dieser Auswahl behandelt, wenn sie nicht auf einer Liste auftauchen", "Local": "Lokal", - "LogLevel": "Log Level", + "LogLevel": "Protokollstufe", "Logs": "Protokolle", "MarkAsFailed": "Als fehlgeschlagen markieren", "MaximumSize": "Maximale Größe", - "Mechanism": "Verfahren", - "MediaInfo": "Medien Information", - "MediaManagementSettings": "Medienverwaltungs Einstellungen", + "Mechanism": "Mechanismus", + "MediaInfo": "Medieninfo", + "MediaManagementSettings": "Einstellungen zur Medienverwaltung", "MIA": "MIA", "MinimumAge": "Mindestalter", - "MinimumFreeSpace": "Mindest freier Speicher", - "MinimumFreeSpaceHelpText": "Importieren verhindern wenn weniger als dieser Wert als freier Speicher zur Verfügung steht", - "MinimumLimits": "Mindest Grenzen", + "MinimumFreeSpace": "Mindestfreier Speicherplatz", + "MinimumFreeSpaceHelpText": "Verhindere den Import, wenn dadurch weniger als dieser Speicherplatz auf der Festplatte verfügbar bleibt", + "MinimumLimits": "Minimale Grenzen", "Mode": "Modus", "MonitoredHelpText": "Herunterladen wenn der Film verfügbar ist", "MovieFiles": "Film Dateien", @@ -416,22 +416,22 @@ "MovieTitleToExcludeHelpText": "Der Titel des Filmes der augeschlossen werden soll", "MovieYear": "Erscheinungsjahr", "MovieYearToExcludeHelpText": "Das Erscheinungsjahr des Filmes der ausgeschlossen werden soll", - "MustContain": "Muss beinhalten", - "MustNotContain": "Darf nicht beinhalten", - "NamingSettings": "Bennenungs Einstellungen", + "MustContain": "Muss enthalten", + "MustNotContain": "Darf nicht enthalten", + "NamingSettings": "Benennungseinstellungen", "DotNetVersion": ".NET", "New": "Neu", - "NoLeaveIt": "Nein, nicht ändern", - "NoLimitForAnyRuntime": "Keine Begrenzung der Laufzeiten", + "NoLeaveIt": "Nein, lass es", + "NoLimitForAnyRuntime": "Kein Limit für beliebige Laufzeit", "NotAvailable": "Nicht verfügbar", - "NotificationTriggers": "Benachrichtigungs Auslöser", + "NotificationTriggers": "Benachrichtigungs-Auslöser", "NotMonitored": "Nicht beobachtet", "OpenBrowserOnStart": "Browser beim Start öffnen", - "Original": "Orginal", - "PackageVersion": "Paket Version", + "Original": "Original", + "PackageVersion": "Paketversion", "Password": "Passwort", "Port": "Port", - "PortNumber": "Port Nummer", + "PortNumber": "Portnummer", "PreferIndexerFlagsHelpText": "Priorisiere Releases mit speziellen Flags", "PreferredSize": "Bevorzugte Größe", "Proper": "Korrekt", @@ -455,14 +455,14 @@ "RemovedFromTaskQueue": "Aus der Aufgabenwarteschlange entfernt", "RemoveFailedDownloadsHelpText": "Fehlgeschlagene Downloads aus dem Downloader Verlauf entfernen", "RemoveFilter": "Filter entfernen", - "RemoveFromQueue": "Aus der Warteschlage entfernen", + "RemoveFromQueue": "Aus der Warteschlange entfernen", "RenameMovies": "Filme umbenennen", "RenameMoviesHelpText": "Wenn das umbennen deaktiviert ist, wird der vorhandene Dateiname benutzt", - "Reorder": "Neu sortieren", - "ReplaceIllegalCharacters": "Sonderzeichen ersetzen", + "Reorder": "Neu anordnen", + "ReplaceIllegalCharacters": "Illegale Zeichen ersetzen", "ReplaceIllegalCharactersHelpText": "Ersetze illegale Zeichen. Wenn nicht ausgewählt, werden sie stattdessen von {appName} entfernt", "RescanAfterRefreshMovieHelpText": "Nach dem aktualisieren des Films, den Filmordner neu scannen", - "RescanAfterRefreshHelpTextWarning": "Wenn nicht \"Immer (Always)\" ausgewählt wird, werden Dateiänderungen nicht automatisch durch {appName} erkannt", + "RescanAfterRefreshHelpTextWarning": "{appName} erkennt Änderungen an Dateien nicht automatisch, wenn es nicht auf „Immer“ eingestellt ist.", "RescanMovieFolderAfterRefresh": "Nach dem aktualisieren den Filmordner neu scannen", "Reset": "Zurücksetzen", "ResetAPIKey": "API-Schlüssel zurücksetzen", @@ -470,15 +470,15 @@ "RestartRadarr": "{appName} Neustarten", "Result": "Ergebnis", "RetentionHelpText": "Nur Usenet: Auf Null setzen, um eine unbegrenzte Aufbewahrung festzulegen", - "RssSyncInterval": "RSS Synchronisierungs Intervall", - "ScriptPath": "Script Pfad", - "SetPermissions": "Rechte setzen", + "RssSyncInterval": "RSS-Sync-Intervall", + "ScriptPath": "Skript-Pfad", + "SetPermissions": "Berechtigungen festlegen", "SetPermissionsLinuxHelpTextWarning": "Wenn Sie nicht sicher sind, was diese Einstellungen bewirken, ändern Sie sie nicht.", "ListMonitorMovieHelpText": "Sollen von dieser Liste hinzugefügte Filme oder Sammlungen als beobachtet hinzugefügt werden", - "ICalShowAsAllDayEvents": "Als Ganztags Events anzeigen", - "IconForCutoffUnmetHelpText": "Symbol zeigen wenn die Qualitätsschwelle noch nicht erreicht wurde", + "ICalShowAsAllDayEvents": "Als ganztägige Ereignisse anzeigen", + "IconForCutoffUnmetHelpText": "Symbol für Dateien anzeigen, wenn die Grenze nicht erreicht wurde", "ShowMovieInformationHelpText": "Genre und Zertifizierung anzeigen", - "ShowQualityProfileHelpText": "Qualitätsprofil unter dem Plakat anzeigen", + "ShowQualityProfileHelpText": "Qualitätsprofil unter dem Poster anzeigen", "ShowMovieInformation": "Filminformationen anzeigen", "ShowTitleHelpText": "Filmtitel unter dem Plakat anzeigen", "ShowUnknownMovieItems": "Unzugeordente Filmeinträge anzeigen", @@ -498,7 +498,7 @@ "TestAllLists": "Prüfe alle Listen", "UpdateMechanismHelpText": "Verwenden Sie den integrierten Updater von {appName} oder ein Skript", "UpdateScriptPathHelpText": "Pfad zu einem benutzerdefinierten Skript, das ein extrahiertes Update-Paket übernimmt und den Rest des Update-Prozesses abwickelt", - "UpgradesAllowedHelpText": "Wenn deaktiviert wird die Qualität nicht verbessert", + "UpgradesAllowedHelpText": "Wenn deaktiviert, werden Qualitäten nicht aktualisiert.", "Uptime": "Betriebszeit", "UrlBase": "URL-Basis", "TMDBId": "TMDb ID", @@ -511,15 +511,15 @@ "CustomFormatsLoadError": "Eigene Formate konnten nicht geladen werden", "DelayProfilesLoadError": "Verzögerungsprofile konnten nicht geladen werden", "IndexersLoadError": "Indexer konnten nicht geladen werden", - "ImportListExclusionsLoadError": "Listenausschlüsse konnten nicht geladen werden", - "ImportListsLoadError": "Listen konnten nicht geladen werden", - "MetadataLoadError": "Metadaten konnten nicht geladen werden", - "NotificationsLoadError": "Benachrichtigungen konnten nicht geladen werden", + "ImportListExclusionsLoadError": "Konnte Ausschlüsse aus der Importliste nicht laden", + "ImportListsLoadError": "Konnte Importlisten nicht laden", + "MetadataLoadError": "Kann Metadaten nicht laden", + "NotificationsLoadError": "Benachrichtigungen können nicht geladen werden", "QualityDefinitionsLoadError": "Qualitätsdefinitionen konnten nicht geladen werden", "QualityProfilesLoadError": "Qualitätsprofile konnten nicht geladen werden", "UnableToLoadRestrictions": "Beschränkungen konnten nicht geladen werden", "TagsLoadError": "Tags konnten nicht geladen werden", - "Ungroup": "Gruppe entfernen", + "Ungroup": "Gruppierung aufheben", "ICalIncludeUnmonitoredMoviesHelpText": "Nicht beobachtete Filme im iCal-Feed einschließen", "UseHardlinksInsteadOfCopy": "Verwende Hardlinks statt Kopieren", "Usenet": "Usenet", @@ -535,45 +535,45 @@ "AddImportListExclusion": "Listenausschluss hinzufügen", "RequiredHelpText": "Diese {0} Bedingungen müsen zutreffen damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.", "AllowHardcodedSubsHelpText": "Filme mit hartcodierten Untertiteln werden auch automatisch heruntergeladen", - "ICalFeedHelpText": "Füge diese URL in deinen Client ein oder klicke auf abonnieren wenn dein Browser Webcal untertützt", - "NoMinimumForAnyRuntime": "Kein Minimum für Laufzeiten", + "ICalFeedHelpText": "Kopiere diese URL in deine(n) Client(s) oder klicke zum Abonnieren, wenn dein Browser webcal unterstützt", + "NoMinimumForAnyRuntime": "Kein Minimum für beliebige Laufzeit", "AnalyticsEnabledHelpText": "Senden Sie anonyme Nutzungs- und Fehlerinformationen an die Server von {appName}. Dazu gehören Informationen zu Ihrem Browser, welche {appName}-WebUI-Seiten Sie verwenden, Fehlerberichte sowie Betriebssystem- und Laufzeitversion. Wir werden diese Informationen verwenden, um Funktionen und Fehlerbehebungen zu priorisieren.", "IgnoredHelpText": "Ein Release wird abgelehnt, wenn es einen oder mehrere dieser Begriffe enthält (Groß- und Kleinschreibung wird nicht berücksichtigt)", "RestartRequiredHelpTextWarning": "Erfordert einen Neustart, damit die Aktion wirksam wird", "ApiKey": "API-Schlüssel", "ImportedTo": "Importiert nach", - "Permissions": "Rechte", + "Permissions": "Berechtigungen", "ImportExtraFilesMovieHelpText": "Importiere zutreffende Extra Dateien (Untertitel, nfo, etc.) nach dem Importieren einer Filmdatei", "PreferIndexerFlags": "Bevorzugte Indexer Flags", "CopyUsingHardlinksMovieHelpText": "Hardlinks erlauben es {appName}, Torrents zu importieren die derzeit geseeded werden, ohne dabei weiteren Speicherplatz zu belegen oder die Datei vollständig zu kopieren. Hardlinks funktionieren nur, wenn sich die Quelle und das Ziel auf dem selben Volume befinden", "SearchForMovie": "Film suchen", "AuthenticationMethodHelpText": "Für den Zugriff auf {appName} sind Benutzername und Passwort erforderlich", "CopyUsingHardlinksHelpTextWarning": "Gelegentlich können Dateisperren das Umbenennen von Dateien verhindern, die geseedet werden. Sie können das Seeding vorübergehend deaktivieren und als Workaround die Umbenennungsfunktion von {appName} verwenden.", - "IndexerSettings": "Indexer Einstellungen", + "IndexerSettings": "Indexer-Einstellungen", "ProxyPasswordHelpText": "Sie müssen nur einen Benutzernamen und ein Passwort eingeben, wenn dies erforderlich ist. Andernfalls lassen Sie sie leer.", "SendAnonymousUsageData": "Sende anonyme Nutzungsdaten", "AutoRedownloadFailedHelpText": "Suchen Sie automatisch nach einer anderen Version und versuchen Sie, sie herunterzuladen", "DatabaseMigration": "DB Migration", "LaunchBrowserHelpText": " Öffne die Startseite von {appName} im Webbrowser nach dem Start.", "ReadTheWikiForMoreInformation": "Lesen Sie das Wiki für weitere Informationen", - "SetPermissionsLinuxHelpText": "Soll CHMOD ausgeführt werden wenn Datien importiert/umbenannt werden?", + "SetPermissionsLinuxHelpText": "Soll chmod beim Importieren/Umbenennen von Dateien ausgeführt werden?", "BackupFolderHelpText": "Relative Pfade befinden sich im AppData-Verzeichnis von {appName}", "DelayProfile": "Verzögerungsprofil", "MaximumLimits": "Maximale Grenzen", "RecyclingBinCleanupHelpTextWarning": "Datien im Papierkorb die älter sind als der gewählte Wert, werden endgültig gelöscht", - "RemotePathMappingsLoadError": "Entfernte Pfadzuordnungen konnten nicht geladen werden", + "RemotePathMappingsLoadError": "Kann Remote-Pfadzuordnungen nicht laden", "DeleteEmptyFoldersHelpText": "Lösche leere Filmeordner während des Scans oder wenn Filmdateien gelöscht werden", - "MaximumSizeHelpText": "Maximale Größe für ein zu erfassendes Release in MB. 0 bedeutet unbegrenzt", + "MaximumSizeHelpText": "Maximale Größe für einen Release, der heruntergeladen wird, in MB. Setze auf Null, um es auf unbegrenzt zu setzen.", "ReleaseDates": "VÖ Termine", "CertificationCountryHelpText": "Wähle ein Land für die Film Zertifizierungen", "DeleteNotification": "Benachrichtigung löschen", - "MetadataSettings": "Metadaten Einstellungen", - "RemoveCompletedDownloadsHelpText": "Importierte Downloads aus dem Downloader Verlauf entfernen", + "MetadataSettings": "Einstellungen für Metadaten", + "RemoveCompletedDownloadsHelpText": "Entferne importierte Downloads aus der Download-Client-Historie", "CloneIndexer": "Indexer klonen", "DeleteQualityProfile": "Qualitätsprofil löschen", - "MinimumCustomFormatScoreHelpText": "Mindester eigener Format Score bis zum Download", + "MinimumCustomFormatScoreHelpText": "Mindestwert für benutzerdefinierte Formate, der zum Herunterladen zugelassen wird", "ConnectSettings": "Verbindungseinstellungen", - "MinimumAgeHelpText": "Nur Usenet: Mindestalter in Minuten der NZBs bevor sie erfasst werden. Gebe damit neuen Releases Zeit, sich bei deinem Usenet Provider zu verbreiten.", + "MinimumAgeHelpText": "Nur Usenet: Mindestalter in Minuten von NZBs, bevor sie heruntergeladen werden. Verwende dies, um neuen Releases Zeit zu geben, zu deinem Usenet-Anbieter zu propagieren.", "RemoveFromDownloadClient": "Aus dem Download Client entfernen", "WaitingToProcess": "Warten auf Bearbeitung", "WaitingToImport": "Warten auf Import", @@ -589,13 +589,13 @@ "ShowCertification": "Zertifikation anzeigen", "RuntimeFormat": "Laufzeit Format", "ListSearchOnAddMovieHelpText": "Nach Filmen auf dieser Liste suchen, wenn sie der Bibliothek hinzugefügt werden", - "RssSyncIntervalHelpTextWarning": "Dies wird alle Indexer betreffen. Bitte folge deren Regeln", - "RssIsNotSupportedWithThisIndexer": "RSS wird von diesem Indexer nicht unterstützt", + "RssSyncIntervalHelpTextWarning": "Dies gilt für alle Indexer. Bitte befolge die von ihnen festgelegten Regeln", + "RssIsNotSupportedWithThisIndexer": "RSS wird mit diesem Indexer nicht unterstützt", "RemovingTag": "Tag entfernen", "Queued": "In Warteschlange", "Pending": "Ausstehend", "Paused": "Pausiert", - "NegateHelpText": "Wenn aktiviert wird das eigene Format nicht angewendet solange diese {0} Bedingung zutrifft.", + "NegateHelpText": "Wenn aktiviert, wird das benutzerdefinierte Format nicht angewendet, wenn diese {implementationName}-Bedingung zutrifft.", "MoviesSelectedInterp": "{0} Film(e) ausgewählt", "MovieIsUnmonitored": "Film wird nicht beobachtet", "MovieIsMonitored": "Film wird beobachtet", @@ -603,21 +603,21 @@ "MovieAlreadyExcluded": "Film ist schon ausgeschlossen", "MarkAsFailedMessageText": "'{0}' wirklich als fehlgeschlagen markieren?", "Manual": "Manuell", - "LogLevelTraceHelpTextWarning": "Trace logging sollte nur kurzzeitig aktiviert werden", + "LogLevelTraceHelpTextWarning": "Die Trace-Protokollierung sollte nur vorübergehend aktiviert werden", "LastDuration": "Letzte Dauer", "IncludeRecommendationsHelpText": "{appName}s Empfehlungen in der Entdeckungsansicht mit einbeziehen", "IncludeRadarrRecommendations": "{appName} Empfehlungen einbeziehen", "ImportFailed": "Import fehlgeschlagen: {0}", - "HiddenClickToShow": "Versteckt, klicken zum anzeigen", + "HiddenClickToShow": "Versteckt, zum Anzeigen anklicken", "GrabReleaseMessageText": "Das Release konnte keinem Film zugeordnet werden. Ein automatischer Import wird nicht möglich sein. Trotzdem '{0}' erfassen?", "GoToInterp": "Zu {0} gehen", "ExistingTag": "Vorhandener Tag", "ExcludeMovie": "Film ausschließen", - "SearchIsNotSupportedWithThisIndexer": "Der Indexer unterstützt keine Suchen", - "EnableInteractiveSearchHelpText": "Wird bei der manuellen Suche benutzt", - "EnableAutomaticSearchHelpText": "Wird für automatische Suchen genutzt die vom Benutzer oder von {appName} gestartet werden", - "DownloadWarning": "Download Warnung: {0}", - "Downloading": "Lädt herunter", + "SearchIsNotSupportedWithThisIndexer": "Suche wird von diesem Indexer nicht unterstützt", + "EnableInteractiveSearchHelpText": "Wird verwendet, wenn die interaktive Suche verwendet wird", + "EnableAutomaticSearchHelpText": "Wird verwendet, wenn die automatische Suche über die Benutzeroberfläche oder durch {appName} durchgeführt wird.", + "DownloadWarning": "Download Warnung: {warningMessage}", + "Downloading": "wird runtergeladen", "DownloadFailed": "Download fehlgeschlagen", "DeleteTagMessageText": "Bist du sicher, dass du den Tag '{label}' wirklich löschen willst?", "DeleteRestrictionHelpText": "Beschränkung '{0}' wirklich löschen?", @@ -639,12 +639,12 @@ "UiSettingsLoadError": "Oberflächen Einstellungen konnten nicht geladen werden", "CalendarLoadError": "Kalender konnte nicht geladen werden", "UnableToLoadRootFolders": "Stammordner können nicht geladen werden", - "MediaManagementSettingsLoadError": "Media Verwaltungseinstellungen konnten nicht geladen werden", - "NamingSettingsLoadError": "Umbenennungeinstellungen konnten nicht geladen werden", + "MediaManagementSettingsLoadError": "Kann die Einstellungen zur Medienverwaltung nicht laden", + "NamingSettingsLoadError": "Benennungseinstellungen konnten nicht geladen werden", "UnableToLoadMovies": "Filme konnten nicht geladen werden", - "ListOptionsLoadError": "Listen Einstellungen konnten nicht geladen werden", - "IndexerOptionsLoadError": "Indexer Einstellungen konnten nicht geladen werden", - "GeneralSettingsLoadError": "Allgemeine Einstellungen konnten nicht geladen werden", + "ListOptionsLoadError": "Kann Listenoptionen nicht laden", + "IndexerOptionsLoadError": "Indexer-Optionen konnten nicht geladen werden", + "GeneralSettingsLoadError": "Allgemeine Einstellungen können nicht geladen werden", "DownloadClientOptionsLoadError": "Downloader Einstellungen konnten nicht geladen werden", "BackupsLoadError": "Sicherrungen können nicht geladen werden", "AddRemotePathMappingError": "Es konnte keine neue Remote-Pfadzuordnung hinzugefügt werden. Bitte versuchen Sie es erneut.", @@ -656,22 +656,22 @@ "AddDownloadClientError": "Der neue Downloader konnte nicht hinzugefügt werden, bitte erneut probieren.", "AddCustomFormatError": "Das neue eigene Format konnte nicht hinzugefügt werden, bitte erneut probieren.", "AddConditionError": "Die neue Bedingung konnte nicht hinzugefügt werden, bitte erneut probieren.", - "FileBrowserPlaceholderText": "Eingeben oder unten auswählen", + "FileBrowserPlaceholderText": "Beginne mit der Eingabe oder wähle unten einen Pfad aus", "Restore": "Wiederherstellen", "RegularExpressionsCanBeTested": "Reguläre Ausdrücke können [hier](http://regexstorm.net/tester) getestet werden.", - "SupportedCustomConditions": "Benutzerdefinierte Bedingungen gegen die unten aufgeführten Release-Eigenschaften werden unterstützt.", + "SupportedCustomConditions": "{appName} unterstützt benutzerdefinierte Bedingungen für die Release-Eigenschaften unten.", "SupportedListsMovie": "RSS Film Listen sowie unten aufgelistete werden untertützt.", - "SupportedIndexers": "Jeder Indexer der den Newznab-Standard verwendet oder unten aufgelistet ist wird untertützt.", - "SupportedDownloadClients": "{appName} unterstützt viele bekannte Torrent- und Usenetdownloader.", + "SupportedIndexers": "{appName} unterstützt jeden Indexer, der den Newznab-Standard verwendet, sowie andere Indexer, die unten aufgelistet sind.", + "SupportedDownloadClients": "{appName} unterstützt viele populäre Torrent- und Usenet-Download-Clients.", "NoUpdatesAreAvailable": "Es sind keine Updates verfügbar", - "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags erstellt", - "NoLogFiles": "Keine Log-Dateien", - "NoHistory": "Kein Verlauf", - "NoBackupsAreAvailable": "Es sind keine Backups vorhanden", + "NoTagsHaveBeenAddedYet": "Es wurden noch keine Tags hinzugefügt", + "NoLogFiles": "Keine Logdateien", + "NoHistory": "Keine Historie", + "NoBackupsAreAvailable": "Keine Sicherungen verfügbar", "MoreDetails": "Mehr Details", "MissingMonitoredAndConsideredAvailable": "Fehlend (beobachtet)", "MissingNotMonitored": "Fehlend (unbeobachtet)", - "MinutesSixty": "60 Minuten: {0}", + "MinutesSixty": "60 Minuten: {sixty}", "MinutesNinety": "90 Minuten: {0}", "MinutesHundredTwenty": "120 Minuten: {0}", "MaintenanceRelease": "Maintenance Release: Fehlerbehebungen und andere Verbesserungen. Siehe Github Commit Verlauf für weitere Details", @@ -683,14 +683,14 @@ "HaveNotAddedMovies": "Es gibt noch keine FIlme in der Bibliothek. Sollen einige oder alles Filme zuerst importiert werden?", "SupportedIndexersMoreInfo": "Für mehr Infomationen klicke auf die Info-Knöpfe.", "SupportedListsMoreInfo": "Für mehr Infomationen klicke auf die Info-Knöpfe.", - "SupportedDownloadClientsMoreInfo": "Für mehr Infomationen klicke auf die 'Mehr Info'-Knöpfe.", + "SupportedDownloadClientsMoreInfo": "Für mehr Informationen zu den einzelnen Download-Clients klicke auf die 'Mehr Infos'-Schaltflächen.", "FilterPlaceHolder": "Filme suchen", "FailedLoadingSearchResults": "Suchergebnisse konnten nicht geladen werden, bitte erneut versuchen.", - "ExtraFileExtensionsHelpTextsExamples": "Vorschläge: sub, nfo, srt, jpg", - "ExtraFileExtensionsHelpText": "Kommaseparierte Liste von Dateiendungen die als Extra Dateien importiert werden sollen ( .nfo wird in .nfo-orig umbenannt )", + "ExtraFileExtensionsHelpTextsExamples": "Beispiele: '.sub, .nfo' oder 'sub,nfo'", + "ExtraFileExtensionsHelpText": "Kommagetrennte Liste von zusätzlichen Dateien, die importiert werden sollen (.nfo wird als .nfo-orig importiert)", "Excluded": "Ausgeschlossen", "Exception": "Ausnahme", - "ErrorLoadingContents": "Fehler beim laden der Inhalte", + "ErrorLoadingContents": "Fehler beim Laden von Inhalten", "DownloadedButNotMonitored": "Heruntergeladen (unbeobachtet)", "DownloadedAndMonitored": "Heruntergeladen (beobachtet)", "CouldNotFindResults": "Es konnten keine Ergebnisse für „{term}“ gefunden werden", @@ -701,19 +701,19 @@ "UiLanguage": "Oberflächen Sprache ( UI Language )", "MovieInfoLanguageHelpText": "Sprache der Filminformationen", "MovieInfoLanguage": "Filminfo Sprache", - "ImportCustomFormat": "Eigenes Format importieren", - "ExportCustomFormat": "Eigenes Format exportieren", + "ImportCustomFormat": "Benutzerdefiniertes Format importieren", + "ExportCustomFormat": "Benutzerdefiniertes Format exportieren", "CustomFormatUnknownConditionOption": "Unbekannte Option '{key}' für die Bedingung '{implementation}'", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Benutze 'Nicht bevorzugen' um den eigene Formate Score über Proper oder Repacks zu sortieren", - "DownloadPropersAndRepacksHelpTextWarning": "Benutze eigene Formate um automatisch auf Proper oder Repack releases zu upgraden", - "DownloadPropersAndRepacksHelpText": "Automatisch Proper oder Repacks zum upgraden eines Filmes zulassen", - "DownloadPropersAndRepacks": "Propers und Repacks", + "DownloadPropersAndRepacksHelpTextCustomFormat": "Verwende 'Nicht bevorzugen', um benutzerdefinierte Formatbewertungen über Propers/Repacks zu sortieren", + "DownloadPropersAndRepacksHelpTextWarning": "Verwende benutzerdefinierte Formate für automatische Upgrades auf Propers/Repacks", + "DownloadPropersAndRepacksHelpText": "Ob automatisch auf Proper/Repacks aktualisiert werden soll oder nicht", + "DownloadPropersAndRepacks": "Props und Repacks", "CopyToClipboard": "In die Zwischenablage kopieren", "CloneCustomFormat": "Benutzerdefiniertes Format klonen", "Priority": "Priorität", "InteractiveSearch": "Interaktive Suche", - "IndexerPriorityHelpText": "Indexer Priorität von 1 (höchste) bis 50 (niedrigste). Standard: 25. Wird beim Erfassen von Releases als Entscheidungskriterium für andernfalls gleiche Releases verwendet, {appName} wird trotzdem alle aktivierten Indexer für RSS-Sync und Suche verwenden", - "IndexerPriority": "Priorität", + "IndexerPriorityHelpText": "Indexer-Priorität von 1 (Höchste) bis 50 (Niedrigste). Standard: 25. Wird verwendet, um bei gleichwertigen Releases eine Entscheidung zu treffen, {appName} wird jedoch weiterhin alle aktivierten Indexer für RSS-Sync und Suche verwenden", + "IndexerPriority": "Indexer-Priorität", "Disabled": "Deaktiviert", "AutomaticSearch": "Automatische Suche", "AddIndexer": "Indexer hinzufügen", @@ -730,13 +730,13 @@ "StartImport": "Import starten", "SearchFailedPleaseTryAgainLater": "Suche fehlgeschlagen, bitte versuche es später nocheinmal.", "Released": "Veröffentlicht", - "NoMatchFound": "Keine Übereinstimmung gefunden!", + "NoMatchFound": "Kein Treffer gefunden!", "ImportRootPath": "Wähle den Ordner der alle deine Filme beinhaltet, nicht einen einzelnen Filmordner (z.B.: `{0}` und nicht `{1}`). Zusätzlich muss jeder Film in dieem Stammordner in einem eigenen Unterordner sein.", "ImportIncludeQuality": "Stelle sicher, dass die Qualität im Dateinamen vorkommt ( z.B.: {0} )", "ImportErrors": "Import Fehler", "Existing": "Vorhanden", "StartProcessing": "Verarbeitung starten", - "ProcessingFolders": "Verarbeitungsordner", + "ProcessingFolders": "Verarbeitende Ordner", "CancelProcessing": "Verarbeitung abbrechen", "EditRestriction": "Beschränkung bearbeiten", "AddRestriction": "Beschränkung hinzufügen", @@ -752,14 +752,14 @@ "ListSyncLevelHelpTextWarning": "Filmdateien werden dauerhaft gelöcht, dies kann deine ganze Mediathek leeren wenn deine Listen leer sind", "ConsideredAvailable": "Verfügbarkeit angenommen", "Announced": "Angekündigt", - "MappedNetworkDrivesWindowsService": "Zugeordnete Netzlaufwerke sind nicht verfügbar, wenn Prowlarr als Windows-Dienst ausgeführt wird. Bitte lesen Sie die FAQ für weitere Informationen", + "MappedNetworkDrivesWindowsService": "Zugriff auf gemappte Netzlaufwerke ist nicht verfügbar, wenn als Windows-Dienst ausgeführt. Weitere Informationen findest du in den [FAQ]({url}).", "CouldNotConnectSignalR": "Es konnte keine Verbindung zu SignalR hergestellt werden, die Benutzeroberfläche wird nicht aktualisiert", "ChownGroupHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der {appName} ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die gleiche Gruppe wie {appName} verwendet.", "ChownGroupHelpText": "Gruppenname oder gid. Verwenden Sie gid für entfernte Dateisysteme.", "ChmodFolderHelpTextWarning": "Dies funktioniert nur, wenn der Benutzer, der {appName} ausführt, der Eigentümer der Datei ist. Es ist besser, sicherzustellen, dass der Download-Client die Berechtigungen richtig festlegt.", "ChmodFolderHelpText": "Oktal, angewendet beim Importieren/Umbenennen auf Medienordner und -dateien (ohne Ausführungsbits)", "ChmodFolder": "chmod Ordner", - "FileNameTokens": "Dateinamen Teile", + "FileNameTokens": "Dateinamen Token", "YesMoveFiles": "Ja, Dateien verschieben", "WouldYouLikeToRestoreBackup": "Willst du das Backup '{name}' wiederherstellen?", "Wiki": "Wiki", @@ -772,8 +772,8 @@ "UpgradeUntilCustomFormatScore": "Upgrade bis zur benutzerdefinierten Formatbewertung", "UpgradesAllowed": "Upgrades erlaubt", "UnmappedFilesOnly": "Nur nicht zugeordnete Dateien", - "Unlimited": "Unlimitiert", - "UpdateAppDirectlyLoadError": "{appName} konnte nicht direkt aktualisiert werden,", + "Unlimited": "Unbegrenzt", + "UpdateAppDirectlyLoadError": "{appName} kann nicht direkt aktualisiert werden.", "UnableToLoadManualImportItems": "Einträge für manuelles importieren konnten nicht geladen werden", "AlternativeTitlesLoadError": "Alternative Titel konnten nicht geladen werden.", "Trigger": "Auslöser", @@ -786,7 +786,7 @@ "TheLogLevelDefault": "Die Protokollebene ist standardmäßig auf „Info“ eingestellt und kann unter „Allgemeine Einstellungen“ (/settings/general) geändert werden.", "Sunday": "Sonntag", "SomeResultsHiddenFilter": "Einige Ergebnisse werden wegen der aktiven Filter nicht angezeigt", - "Socks5": "Socks5 (unterstützt TOR)", + "Socks5": "Socks5 (Unterstützt TOR)", "Socks4": "Socks4", "Small": "Klein", "SelectQuality": "Qualität auswählen", @@ -815,29 +815,29 @@ "QualityLimitsMovieRuntimeHelpText": "Limitierungen werden automatisch an die Filmlänge angepasst.", "QualitiesHelpText": "Qualitätsprofile oben sind mehr bevorzugt, auch wenn diese nicht angehakt sind. Profile in einer Gruppe sind gleichgestellt. Nur ausgewählte werden gesucht", "Qualities": "Qualitäten", - "PrioritySettings": "Priorität: {0}", + "PrioritySettings": "Priorität: {priority}", "PreviewRenameHelpText": "Tipp: Um eine Vorschau der Umbenennung zu bekommen, wähle Abbrechen und klicke auf einen Filmtitel und benutze den", "Presets": "Voreinstellungen", - "PreferUsenet": "Usenet bevorzugt", - "PreferTorrent": "Torrent bevorzugt", + "PreferUsenet": "Bevorzuge Usenet", + "PreferTorrent": "Bevorzuge Torrent", "Preferred": "Bevorzugt", - "PreferAndUpgrade": "Bevorzugen und upgraden", + "PreferAndUpgrade": "Bevorzugen und Upgrade", "PhysicalReleaseDate": "Disc Veröffentlichungsdatum", "OrganizeSelectedMovies": "Ausgewählte Filme organisieren", "OrganizeConfirm": "Bist du sicher, dass du alle Datien der {0} ausgewählten Filme organisieren willst?", "OnRename": "Bei Umbenennung", "OnlyUsenet": "Nur Usenet", - "OnlyTorrent": "Nur Torrents", - "OnLatestVersion": "Die aktuellste Version ist bereits installiert", - "OnHealthIssue": "Bei Zustandsproblem", - "OnGrab": "Bei Erfassung", + "OnlyTorrent": "Nur Torrent", + "OnLatestVersion": "Die neueste Version von {appName} ist bereits installiert", + "OnHealthIssue": "Bei Gesundheitsproblem", + "OnGrab": "Bei Abruf", "NoResultsFound": "Keine Ergebnisse gefunden", "None": "Keine", "NoMoviesExist": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren.", "NoMoveFilesSelf": " Nein, Dateien selbst verschieben", "NoListRecommendations": "Keine Listeneinträge oder Empfehlungen gefunden. Zum Start solltest du einen Film hinzufügen, vorhandene importieren oder eine Liste hinzufügen.", "NoLinks": "Keine Links", - "NoEventsFound": "Keine Events gefunden", + "NoEventsFound": "Keine Ereignisse gefunden", "NoAlternativeTitles": "Keine alternativen Titel.", "NextExecution": "Nächste Ausführung", "Negated": "Negiert", @@ -848,46 +848,46 @@ "MovieChat": "Filmchat", "MoveFolders1": "Wilst du die Filmordner nach '{0}' verschieben ?", "Months": "Monate", - "MonitoredStatus": "Beobachtet/Status", + "MonitoredStatus": "Überwacht/Status", "Monday": "Montag", "Minutes": "Minuten", - "MinimumCustomFormatScore": "Minimum der eigenen Formate Bewertungspunkte", - "Min": "Min.", - "MegabytesPerMinute": "Megabytes pro Minute", + "MinimumCustomFormatScore": "Mindestwert für benutzerdefinierte Formate", + "Min": "Min", + "MegabytesPerMinute": "Megabyte pro Minute", "Medium": "Medium", - "Max": "Max.", + "Max": "Max", "ManualImportSelectQuality": " Manueller Import - Qualität auswählen", "ManualImportSelectMovie": "Manueler Import - Film auswählen", "ManualImportSelectLanguage": "Manueller Import - Sprache auswählen", - "Lowercase": "Kleingeschrieben", + "Lowercase": "Kleinbuchstaben", "LookingForReleaseProfiles2": "stattdessen.", "LookingForReleaseProfiles1": "Suchst du nach Release Profilen? Versuche", - "LogOnly": "Nur Log", - "LastUsed": "Zuletzt benutzt", + "LogOnly": "Nur Protokollieren", + "LastUsed": "Zuletzt verwendet", "LastExecution": "Letzte Ausführung", "Large": "Groß", "KeepAndUnmonitorMovie": "Film behalten aber nicht beobachten", "InvalidFormat": "Ungültiges Format", - "InstallLatest": "Jetzt updaten", + "InstallLatest": "Neueste Version installieren", "InCinemasMovieDescription": "Film ist im Kino", "InCinemasDate": "Kinodatum", "IMDb": "IMDb", "Images": "Bilder", - "HttpHttps": "HTTP/S", + "HttpHttps": "HTTP(S)", "Hours": "Stunden", - "HomePage": "Startseite", + "HomePage": "Hauptseite", "FolderMoveRenameWarning": "Dies wird auch den Filmordner nach dem Filmordnerformat aus den Einstellungen umbennen.", - "FeatureRequests": "Funktionsanfragen", + "FeatureRequests": "Feature Anfragen", "FailedToLoadMovieFromAPI": "Film konnte nicht über die API geladen werden", - "ExternalUpdater": "{appName} wurde so konfiguriert, dass ein externer Update Mechanismus benutzt wird", + "ExternalUpdater": "{appName} ist so konfiguriert, dass es einen externen Aktualisierungsmechanismus verwendet", "ExcludeTitle": "{0} ausschließen? Dies wird {appName} daran hindern, es automatisch beim Listen synchronisieren hinzuzufügen.", - "ErrorRestoringBackup": "Fehler beim Wiederherstellen", + "ErrorRestoringBackup": "Fehler beim Wiederherstellen der Sicherung", "Enabled": "Aktiviert", "EditQualityProfile": "Qualitätsprofil bearbeiten", - "EditImportListExclusion": "Listenausschlüsse bearbeiten", - "EditGroups": "Gruppen bearbeiten", - "EditDelayProfile": "Verzögerungsprofil bearbeiten", - "EditCustomFormat": "Eigenes Format bearbeiten", + "EditImportListExclusion": "Importliste-Ausnahmen bearbeiten", + "EditGroups": "Gruppen Bearbeiten", + "EditDelayProfile": "Delay Profil bearbeiten", + "EditCustomFormat": "Benutzerdefiniertes Format bearbeiten", "DoNotUpgradeAutomatically": "Nicht automatisch aktualisieren", "DoNotPrefer": "Nicht bevorzugen", "DoneEditingGroups": "Bearbeiten der Gruppen abgeschlossen", @@ -945,7 +945,7 @@ "More": "Mehr", "Download": "Herunterladen", "DownloadClientRootFolderHealthCheckMessage": "Download-Client {downloadClientName} legt Downloads im Stammordner {rootFolderPath} ab. Sie sollten nicht in einen Stammordner herunterladen.", - "UpdateAvailableHealthCheckMessage": "Neue Version verfügbar", + "UpdateAvailableHealthCheckMessage": "Ein neues Update ist verfügbar: {version}", "RemotePathMappingCheckFilesLocalWrongOSPath": "Downloader {downloadClientName} meldet Dateien in {path}, aber dies ist kein valider {osName} Pfad. Überprüfe die Downloader Einstellungen.", "RemotePathMappingCheckFilesBadDockerPath": "Docker erkannt; Downloader {downloadClientName} meldet Dateien in {path}, aber dies ist kein valider {osName} Pfad. Überprüfe deine Remote-Pfadzuordnungen und die Downloader Einstellungen.", "RemotePathMappingCheckFilesWrongOSPath": "Downloader {downloadClientName} meldet Dateien in {path}, aber dies ist kein valider {osName} Pfad. Überprüfe deine Remote-Pfadzuordnungen und die Downloader Einstellungen.", @@ -968,18 +968,18 @@ "TaskUserAgentTooltip": "Benutzeragent, bereitgestellt von der App, die die API aufgerufen hat", "Letterboxd": "Letterboxd", "From": "von", - "NotificationTriggersHelpText": "Auslöser für diese Benachrichtigung auswählen", + "NotificationTriggersHelpText": "Wähle aus, welche Ereignisse diese Benachrichtigung auslösen sollen", "Blocklist": "Sperrliste", "BlocklistRelease": "Release sperren", "RemoveFromBlocklist": "Aus der Sperrliste entfernen", "Blocklisted": "Gesperrt", "BlocklistReleases": "Release sperren", "IndexerTagMovieHelpText": "Benutze den Indexer nur für Filme mit mindesens einen zutreffenden Tag. Leer lassen für alle Filme.", - "RemoveSelectedItem": "Entferne ausgewählten Eintrag", + "RemoveSelectedItem": "Ausgewähltes Element entfernen", "RemoveSelectedItems": "Markierte Einträge löschen", "RemoveFailed": "Fehlgeschlagene entfernen", "RemoveCompleted": "Abgeschlossene entfernen", - "RemoveDownloadsAlert": "Die Einstellungen zum Entfernen wurden in die individuellen Download Client Einstellungen in der obigen Tabelle verschoben.", + "RemoveDownloadsAlert": "Die Entfernen-Einstellungen wurden in die einzelnen Download-Client-Einstellungen in der Tabelle oben verschoben.", "AnnouncedMovieDescription": "Film ist angekündigt", "ClickToChangeReleaseGroup": "Klicken Sie hier, um die Release-Gruppe zu ändern", "Filters": "Filter", @@ -988,29 +988,29 @@ "ManualImportSetReleaseGroup": "Manueller Import - Releasegruppe setzen", "OnApplicationUpdate": "Bei Anwendungsaktualisierung", "SelectReleaseGroup": "Wähle Release-Gruppe", - "SizeLimit": "Grössenlimit", + "SizeLimit": "Größenlimit", "SetReleaseGroup": "Release-Gruppe festlegen", - "IndexerDownloadClientHelpText": "Wähle aus, welcher Download-Client für diesen Indexer verwendet wird", + "IndexerDownloadClientHelpText": "Gib an, welcher Download-Client für Abrufe von diesem Indexer verwendet wird", "DiscordUrlInSlackNotification": "Du hast eine Discord-Benachrichtigung als Slack-Benachrichtigung eingerichtet. Richte diese für bessere Funktionalität als Discord-Benachrichtigung ein. Folgende Benachrichtigen sind betroffen: {}", "Duration": "Dauer", - "ImportList": "Liste", + "ImportList": "Importliste", "Rating": "Bewertung", "Auto": "Automatisch", "ImdbRating": "IMDb Bewertung", "ImdbVotes": "IMDb Stimmen", - "Never": "Niemals", + "Never": "Nie", "Started": "Gestartet", "TmdbRating": "TMDb Bewertung", "TmdbVotes": "TMDb Stimmen", "Waiting": "warten", "OriginalTitle": "Originaler Titel", - "OriginalLanguage": "Originale Sprache", + "OriginalLanguage": "Originalsprache", "Database": "Datenbank", "AllCollectionsHiddenDueToFilter": "Alle Filme sind auf Grund des Filters ausgeblendet.", "Collections": "Sammlungen", "MonitorMovies": "Film beobachten", "NoCollections": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren", - "RssSyncIntervalHelpText": "Intervall in Minuten. Zum deaktivieren auf 0 setzen ( Dies wird das automatische Release erfassen deaktivieren )", + "RssSyncIntervalHelpText": "Intervall in Minuten. Setze auf null, um es zu deaktivieren (dies stoppt alle automatischen Release-Abfragen)", "CollectionOptions": "Sammlung Optionen", "ChooseImportMode": "Wählen Sie den Importmodus aus", "CountCollectionsSelected": "{count} Ausgewählte Sammlung(en)", @@ -1034,7 +1034,7 @@ "OnMovieAdded": "Bei Film hinzugefügt", "UnableToLoadCollections": "Sammlungen können nicht geladen werden", "InstanceName": "Instanzname", - "InstanceNameHelpText": "Instanzname im Browser-Tab und für Syslog-Anwendungsname", + "InstanceNameHelpText": "Instanzname im Tab und für den Syslog-App-Namen", "RottenTomatoesRating": "Tomato Bewertung", "TotalMovies": "Filme insgesamt", "ApplicationURL": "Anwendungs-URL", @@ -1045,7 +1045,7 @@ "ThemeHelpText": "Anwendungsdesign ändern, das 'Auto' Design passt sich an den Light/Dark-Mode deines Systems an. Inspiriert von Theme.Park", "ResetTitles": "Titel zurücksetzen", "Theme": "Design", - "EnableRssHelpText": "Wird benutzt, wenn {appName} mittels RSS-Sync regelmäßig nach Releases schaut", + "EnableRssHelpText": "Wird verwendet, wenn {appName} regelmäßig nach Releases über RSS-Sync sucht", "DownloadClientSortingCheckMessage": "Downloader {downloadClientName} hat die {sortingMode} Sortierung für {appName}s Kategorie aktiviert. Dies sollte deaktiviert werden, um Import-Probleme zu vermeiden.", "File": "Datei", "MovieMatchType": "Filmübereinstimmungstyp", @@ -1055,17 +1055,17 @@ "ShowCinemaReleaseHelpText": "Kino-Erscheinungsdatum unter Poster anzeigen", "ApiKeyValidationHealthCheckMessage": "Bitte den API Schlüssel korrigieren, dieser muss mindestens {length} Zeichen lang sein. Die Änderung kann über die Einstellungen oder die Konfigurationsdatei erfolgen", "StopSelecting": "Auswahl stoppen", - "ImportScriptPath": "Pfad zum Importscript", - "ImportUsingScript": "Import per Script", - "OnManualInteractionRequired": "Wenn manuelles Eingreifen erforderlich ist", + "ImportScriptPath": "Import-Skript-Pfad", + "ImportUsingScript": "Mit Skript importieren", + "OnManualInteractionRequired": "Bei erforderlicher manueller Interaktion", "OnManualInteractionRequiredHelpText": "Wenn manuelles Eingreifen erforderlich ist", "RemoveCompletedDownloads": "Entferne abgeschlossene Downloads", "RemoveFailedDownloads": "Fehlgeschlagene Downloads entfernen", - "ImportScriptPathHelpText": "Pfad zum Script für den Import", - "ImportUsingScriptHelpText": "Kopiere Dateien zum Import mithilfe eines Scripts (z.B.: für Transkodierungen)", - "OnHealthRestored": "Bei Wiederherstellung des Zustands", + "ImportScriptPathHelpText": "Der Pfad zum Skript, das für den Import verwendet wird", + "ImportUsingScriptHelpText": "Dateien für den Import mit einem Skript kopieren (z. B. für Transkodierung)", + "OnHealthRestored": "Bei Wiederherstellung der Gesundheit", "Loading": "Lade", - "UpdateFiltered": "Gefilterte updaten", + "UpdateFiltered": "Update gefiltert", "ThereWasAnErrorLoadingThisItem": "Beim Laden des Eintrags ist ein Fehler aufgetreten", "ThereWasAnErrorLoadingThisPage": "Beim Laden der Seite ist ein Fehler aufgetreten", "DeleteRemotePathMapping": "Remote-Pfad-Zuordnung löschen", @@ -1082,7 +1082,7 @@ "DeleteCondition": "Bedingung löschen", "ResetQualityDefinitionsMessageText": "Sind Sie sicher, dass Sie Qualitätsdefinitionen zurücksetzen möchten?", "Complete": "Vollständig", - "ListWillRefreshEveryInterval": "Liste wird alle [0] aktualisiert", + "ListWillRefreshEveryInterval": "Die Liste wird alle {refreshInterval} aktualisiert", "ListRefreshInterval": "Listen Aktualisierungsintervall", "DownloadClientMovieTagHelpText": "Nutze nur diesen Download Client für Filme mit mindestens einen übereinstimmenden tag. Leerlassen um für alle Filme zu nutzen.", "EditSelectedIndexers": "Ausgewähle Indexer bearbeiten", @@ -1110,11 +1110,11 @@ "DeleteImportList": "Importliste löschen", "DeleteImportListMessageText": "Bist du sicher, dass du die Liste '{name}' wirklich löschen willst?", "DeleteQualityProfileMessageText": "Bist du sicher, dass du das Qualitätsprofil '{name}' wirklich löschen willst?", - "RemoveQueueItemConfirmation": "Bist du sicher, dass du {0} Einträge aus der Warteschlange entfernen willst?", - "SkipRedownload": "Überspringe erneuten Download", + "RemoveQueueItemConfirmation": "Bist du sicher, dass du '{sourceTitle}' aus der Warteschlange entfernen möchtest?", + "SkipRedownload": "Neu-Download überspringen", "MoveAutomatically": "Automatisch verschieben", "AutoTaggingNegateHelpText": "Falls aktiviert wird die Auto Tagging Regel nicht angewendet, solange diese Bedingung {implementationName} zutrifft.", - "AutoTaggingRequiredHelpText": "Diese {0} Bedingungen müssen erfüllt sein, damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.", + "AutoTaggingRequiredHelpText": "Diese {implementationName}-Bedingung muss übereinstimmen, damit die automatische Tagging-Regel angewendet wird. Andernfalls reicht ein einziges {implementationName}-Match aus.", "DeleteAutoTagHelpText": "Sind Sie sicher, dass Sie das automatische Tag „{name}“ löschen möchten?", "DeleteSelectedDownloadClientsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Download-Clients löschen möchten?", "DeleteSelectedImportListsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Importliste(n) löschen möchten?", @@ -1125,9 +1125,9 @@ "DeleteRootFolder": "Stammordner löschen", "AddConnection": "Verbindung hinzufügen", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Mindestpunktzahl für benutzerdefiniertes Format", - "NotificationStatusAllClientHealthCheckMessage": "Wegen Fehlern sind keine Applikationen verfügbar", - "NotificationStatusSingleClientHealthCheckMessage": "Applikationen wegen folgender Fehler nicht verfügbar: {notificationNames}", - "DownloadClientsLoadError": "Downloader konnten nicht geladen werden", + "NotificationStatusAllClientHealthCheckMessage": "Alle Benachrichtigungen sind aufgrund von Fehlern nicht verfügbar", + "NotificationStatusSingleClientHealthCheckMessage": "Benachrichtigungen nicht verfügbar wegen Fehlern: {notificationNames}", + "DownloadClientsLoadError": "Download Clients können nicht geladen werden", "IMDbId": "TMDb ID", "DisabledForLocalAddresses": "Für lokale Adressen deaktiviert", "AddCondition": "Bedingung hinzufügen", @@ -1149,8 +1149,8 @@ "AuthenticationRequiredHelpText": "Ändern, welche anfragen Authentifizierung benötigen. Ändere nichts wenn du dir nicht des Risikos bewusst bist.", "AudioLanguages": "Audio Sprachen", "AuthenticationMethodHelpTextWarning": "Bitte wähle eine gültige Authentifizierungsmethode aus", - "AuthenticationRequiredPasswordHelpTextWarning": "Gib ein neues Passwort ein", - "AuthenticationRequiredUsernameHelpTextWarning": "Gib einen neuen Benutzernamen ein", + "AuthenticationRequiredPasswordHelpTextWarning": "Neues Passwort eingeben", + "AuthenticationRequiredUsernameHelpTextWarning": "Neuen Benutzernamen eingeben", "AuthenticationRequiredWarning": "Um unberechtigte Fernzugriffe zu vermeiden benötigt {appName} jetzt , dass Authentifizierung eingeschaltet ist. Du kannst Authentifizierung optional für lokale Adressen ausschalten.", "AutoRedownloadFailed": "Erneuter Download fehlgeschlagen", "AutoRedownloadFailedFromInteractiveSearch": "Erneuter Download aus Interaktiver Suche fehlgeschlagen", @@ -1165,7 +1165,7 @@ "DefaultNameCopiedProfile": "{name} – Kopieren", "DelayingDownloadUntil": "Download wird bis zum {date} um {time} verzögert", "DeleteAutoTag": "Auto-Tag löschen", - "DeletedReasonManual": "Die Datei wurde über die Benutzeroberfläche gelöscht", + "DeletedReasonManual": "Datei wurde mit {appName} gelöscht, entweder manuell oder durch ein anderes Tool über die API", "DeletedReasonUpgrade": "Die Datei wurde gelöscht, um ein Upgrade zu importieren", "RemoveTagsAutomatically": "Tags automatisch entfernen", "RetryingDownloadOn": "Erneuter Downloadversuch am {date} um {time}", @@ -1192,8 +1192,8 @@ "AddRootFolderError": "Stammverzeichnis kann nicht hinzugefügt werden", "ClearBlocklist": "Sperrliste leeren", "CloneAutoTag": "Automatische Tags kopieren", - "Retention": "Aufbewahrung ( Retention )", - "Unmonitored": "Nicht beobachtet", + "Retention": "Aufbewahrung", + "Unmonitored": "Nicht überwacht", "DownloadClientFreeboxUnableToReachFreebox": "Die Freebox-API kann nicht erreicht werden. Überprüfen Sie die Einstellungen „Host“, „Port“ oder „SSL verwenden“. (Fehler: {exceptionMessage})", "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Sie müssen sich bei Ihrer Diskstation als {username} anmelden und sie manuell in den DownloadStation-Einstellungen unter BT/HTTP/FTP/NZB -> Standort einrichten.", "UsenetBlackhole": "Usenet Blackhole", @@ -1218,12 +1218,12 @@ "DeleteReleaseProfile": "Release-Profil löschen", "Label": "Label", "BlackholeWatchFolder": "Überwachter Ordner", - "MonitorSelected": "Beobachte ausgewählte", + "MonitorSelected": "Ausgewählte überwachen", "DelayMinutes": "{delay} Minuten", "DownloadClientNzbgetSettingsAddPausedHelpText": "Diese Option erfordert mindestens NzbGet Version 16.0", - "InteractiveImportLoadError": "Einträge für manuelles importieren konnten nicht geladen werden", - "IncludeHealthWarnings": "Zustandswarnung", - "ShowMonitoredHelpText": "Beobachtungsstatus unter dem Plakat anzeigen", + "InteractiveImportLoadError": "Manuelle Importitems konnten nicht geladen werden", + "IncludeHealthWarnings": "Gesundheitswarnungen einbeziehen", + "ShowMonitoredHelpText": "Überwachungsstatus unter dem Poster anzeigen", "NotificationsDiscordSettingsAuthor": "Autor", "Dash": "Bindestrich", "Donate": "Spenden", @@ -1235,7 +1235,7 @@ "DownloadClientDownloadStationValidationSharedFolderMissing": "Der freigegebene Ordner existiert nicht", "DownloadClientFloodSettingsPostImportTags": "Post-Import-Tags", "DownloadClientFreeboxSettingsApiUrl": "API-URL", - "DownloadClientFreeboxSettingsApiUrlHelpText": "Definieren Sie die Freebox-API-Basis-URL mit der API-Version, z. B. „{url}“, standardmäßig ist „{defaultApiUrl}“.", + "DownloadClientFreeboxSettingsApiUrlHelpText": "Definiere die Freebox-API-Basis-URL mit der API-Version, z. B. '{url}', standardmäßig '{defaultApiUrl}'.", "DownloadClientNzbVortexMultipleFilesMessage": "Der Download enthält mehrere Dateien und befindet sich nicht in einem Jobordner: {outputPath}", "DownloadClientQbittorrentSettingsFirstAndLastFirst": "Erster und Letzter Erster", "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Laden Sie zuerst das erste und das letzte Stück herunter (qBittorrent 4.1.0+)", @@ -1248,10 +1248,10 @@ "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "Die Verwendung von „Vor Download prüfen“ beeinträchtigt die Fähigkeit von {appName}, neue Downloads zu verfolgen. Außerdem empfiehlt Sabnzbd stattdessen „Jobs abbrechen, die nicht abgeschlossen werden können“, da dies effektiver ist.", "DownloadClientSabnzbdValidationEnableDisableDateSorting": "Deaktivieren Sie die Datumssortierung", "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Sie müssen die Datumssortierung für die von {appName} verwendete Kategorie deaktivieren, um Importprobleme zu vermeiden. Gehen Sie zu Sabnzbd, um das Problem zu beheben.", - "ListRootFolderHelpText": "Die Elemente im Stammverzeichnis werden hinzugefügt zu", + "ListRootFolderHelpText": "Root-Ordner-Listenelemente werden hinzugefügt zu", "RestartRequiredToApplyChanges": "{appName} erfordert einen Neustart, um die Änderungen zu übernehmen. Möchten Sie jetzt neu starten?", - "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht benutzt und kann gelöscht werden", - "NotificationsSimplepushSettingsEvent": "Auslöser", + "TagIsNotUsedAndCanBeDeleted": "Tag wird nicht verwendet und kann gelöscht werden", + "NotificationsSimplepushSettingsEvent": "Ereignis", "Destination": "Ziel", "DownloadClientDelugeSettingsUrlBaseHelpText": "Fügt der Deluge-JSON-URL ein Präfix hinzu, siehe {url}", "DownloadClientDelugeValidationLabelPluginFailure": "Konfiguration des Labels fehlgeschlagen", @@ -1277,8 +1277,8 @@ "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "Die NzbGet-Einstellung KeepHistory ist zu hoch eingestellt.", "DownloadClientQbittorrentSettingsUseSslHelpText": "Verwenden Sie eine sichere Verbindung. Siehe Optionen -> Web-Benutzeroberfläche -> „HTTPS statt HTTP verwenden“ in qBittorrent.", "DownloadClientQbittorrentTorrentStateError": "qBittorrent meldet einen Fehler", - "ReleaseProfileIndexerHelpText": "Angabe, welcher Indexer für das Profil gilt", - "UnmonitorSelected": "Ausgewählte nicht mehr beobachten", + "ReleaseProfileIndexerHelpText": "Gib an, auf welchen Indexer das Profil zutrifft", + "UnmonitorSelected": "Nicht überwachen ausgewählter Episoden", "DownloadClient": "Downloader", "DelayProfileProtocol": "Protokoll: {preferredProtocol}", "DownloadClientDelugeValidationLabelPluginInactive": "Label-Plugin nicht aktiviert", @@ -1307,28 +1307,28 @@ "DownloadClientQbittorrentValidationQueueingNotEnabled": "Warteschlangen nicht aktiviert", "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "Torrent Warteschlange ist in Ihren qBittorrent-Einstellungen nicht aktiviert. Aktivieren Sie es in qBittorrent oder wählen Sie „Letzte“ als Priorität.", "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent ist so konfiguriert, dass Torrents entfernt werden, wenn sie ihr Share-Ratio-Limit erreichen", - "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} kann die Behandlung abgeschlossener Downloads nicht wie konfiguriert durchführen. Sie können dies in qBittorrent beheben („Extras -> Optionen...“ im Menü), indem Sie „Optionen -> BitTorrent -> Freigabeverhältnisbegrenzung“ von „Entfernen“ in „Pause“ ändern.", + "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} kann das Handling abgeschlossener Downloads wie konfiguriert nicht durchführen. Du kannst das in qBittorrent beheben ('Werkzeuge -> Optionen...' im Menü), indem du 'Optionen -> BitTorrent -> Share Ratio Limiting' von 'Entfernen' auf 'Pausieren' änderst.", "DownloadClientRTorrentSettingsAddStopped": "Hinzufügen gestoppt", "DownloadClientRTorrentSettingsAddStoppedHelpText": "Durch die Aktivierung werden Torrents und Magnete im gestoppten Zustand zu rTorrent hinzugefügt. Dadurch können Magnetdateien beschädigt werden.", "DownloadClientRTorrentSettingsUrlPathHelpText": "Pfad zum XMLRPC-Endpunkt, siehe {url}. Dies ist normalerweise RPC2 oder [Pfad zu ruTorrent]{url2}, wenn ruTorrent verwendet wird.", "DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd-Entwicklungsversion, vorausgesetzt Version 3.0.0 oder höher.", "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Deaktivieren Sie die Filmsortierung", "DownloadClientSettingsAddPaused": "Pausiert hinzufügen", - "EditIndexerImplementation": "Indexer hinzufügen - {implementationName}", + "EditIndexerImplementation": "Indexer bearbeiten - {implementationName}", "Lists": "Listen", - "MustNotContainHelpText": "Ein Release wird abgelehnt, wenn es einen oder mehrere dieser Begriffe enthält (Groß- und Kleinschreibung wird nicht berücksichtigt)", + "MustNotContainHelpText": "Das Release wird abgelehnt, wenn einer oder mehrere dieser Begriffe enthalten sind (Groß- und Kleinschreibung ignorieren)", "RegularExpressionsTutorialLink": "Weitere Details zu regulären Ausdrücken finden Sie [hier](https://www.regular-expressions.info/tutorial.html).", "Release": "Veröffentlichung", "Space": "Platz", - "TablePageSize": "Einträge pro Seite", - "TablePageSizeHelpText": "Anzahl der Einträge pro Seite", + "TablePageSize": "Seitengröße", + "TablePageSizeHelpText": "Anzahl der Elemente, die auf jeder Seite angezeigt werden", "TypeOfList": "{typeOfList} Liste", "DeleteImportListExclusionMessageText": "Bist du sicher, dass du diesen Importlisten Ausschluss löschen willst?", "CustomFormatUnknownCondition": "Unbekannte Eigene Formatbedingung '{implementation}'", "DownloadClientAriaSettingsDirectoryHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", "FormatAgeDays": "Tage", "InteractiveSearchModalHeader": "Interaktive Suche", - "OrganizeNothingToRename": "Fertig! Keine weiteren Dateien zum umbennenen.", + "OrganizeNothingToRename": "Erfolg! Meine Arbeit ist erledigt, keine Dateien zum Umbenennen.", "Tags": "Tags", "RestartRequiredWindowsService": "Je nachdem, welcher Benutzer den {appName}-Dienst ausführt, müssen Sie {appName} möglicherweise einmal als Administrator neu starten, bevor der Dienst automatisch gestartet wird.", "SecretToken": "Geheimer Token", @@ -1336,27 +1336,27 @@ "TorrentBlackholeSaveMagnetFilesExtension": "Speicher die Magnet-Dateienerweiterung", "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText": "Anstatt Dateien zu verschieben, wird {appName} dadurch angewiesen, sie zu kopieren oder fest zu verknüpfen (abhängig von den Einstellungen/Systemkonfiguration).", "WantMoreControlAddACustomFormat": "Möchten Sie mehr Kontrolle darüber haben, welche Downloads bevorzugt werden? Fügen Sie ein [benutzerdefiniertes Format] hinzu (/settings/customformats)", - "ReleaseProfiles": "Veröffentlichungsprofile", - "EditReleaseProfile": "Release Profile bearbeiten", - "EnableProfileHelpText": "Anhaken um Veröffentlichungsprofile zu aktivieren", - "ShowMonitored": "Beobachtete anzeigen", - "RemoveSelectedBlocklistMessageText": "Bist du sicher, dass du die ausgewählten Einträge aus der Sperrliste entfernen willst?", - "OrganizeLoadError": "Fehler beim laden der Vorschauen", + "ReleaseProfiles": "Release-Profile", + "EditReleaseProfile": "Release Profil bearbeiten", + "EnableProfileHelpText": "Aktiviere das Release-Profil", + "ShowMonitored": "Überwachter Status anzeigen", + "RemoveSelectedBlocklistMessageText": "Bist du sicher, dass du die ausgewählten Elemente aus der Blockliste entfernen möchtest?", + "OrganizeLoadError": "Fehler beim Laden der Vorschauen", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Der Download-Client {downloadClientName} ist so eingestellt, dass abgeschlossene Downloads entfernt werden. Dies kann dazu führen, dass Downloads von Ihrem Client entfernt werden, bevor {appName} sie importieren kann.", "EnableProfile": "Profil aktivieren", "NotificationsGotifySettingsAppToken": "App-Token", - "DeleteReleaseProfileMessageText": "Sind Sie sicher, dass Sie dieses Release-Profil „{name}“ löschen möchten?", + "DeleteReleaseProfileMessageText": "Bist du sicher, dass du das Release-Profil '{name}' löschen möchtest?", "DeleteSpecification": "Spezifikation löschen", "DeleteSpecificationHelpText": "Sind Sie sicher, dass Sie die Spezifikation „{name}“ löschen möchten?", "DownloadClientDownloadStationProviderMessage": "{appName} kann keine Verbindung zur Download Station herstellen, wenn die 2-Faktor-Authentifizierung in Ihrem DSM-Konto aktiviert ist", "DownloadClientFloodSettingsPostImportTagsHelpText": "Fügt Tags hinzu, nachdem ein Download importiert wurde.", "DownloadClientFreeboxApiError": "Freebox-API hat Fehler zurückgegeben: {errorDescription}", "DownloadClientFreeboxSettingsHostHelpText": "Hostname oder Host-IP-Adresse der Freebox, standardmäßig „{url}“ (funktioniert nur im selben Netzwerk)", - "MustContainHelpText": "Das Release mus mindesten eines der Begriffe beinhalten ( Groß-/Kleinschreibung wird nicht beachtet )", + "MustContainHelpText": "Das Release muss mindestens einen dieser Begriffe enthalten (Groß- und Kleinschreibung ignorieren)", "UsenetBlackholeNzbFolder": "NZB-Ordner", "No": "Nein", "Directory": "Verzeichnis", - "EditDownloadClientImplementation": "Download-Client hinzufügen - {implementationName}", + "EditDownloadClientImplementation": "Download Client bearbeiten - {implementationName}", "DelayProfileMovieTagsHelpText": "Wird auf Filme mit mindestens einem passenden Tag angewandt", "DownloadClientDelugeTorrentStateError": "Deluge meldet einen Fehler", "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Um Kategorien verwenden zu können, muss das Label-Plugin in {clientName} aktiviert sein.", @@ -1369,7 +1369,7 @@ "DownloadClientFloodSettingsRemovalInfo": "{appName} übernimmt die automatische Entfernung von Torrents basierend auf den aktuellen Seed-Kriterien in Einstellungen -> Indexer", "DownloadClientFreeboxUnableToReachFreeboxApi": "Die Freebox-API kann nicht erreicht werden. Überprüfen Sie die Einstellung „API-URL“ für Basis-URL und Version.", "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} wird nicht versuchen, abgeschlossene Downloads ohne Kategorie zu importieren.", - "GrabId": "Erfass ID", + "GrabId": "ID holen", "ConditionUsingRegularExpressions": "Diese Bedingung entspricht der Verwendung regulärer Ausdrücke. Beachten Sie, dass die Zeichen „\\^$.|?*+()[{“ eine besondere Bedeutung haben und mit einem „\\“ maskiert werden müssen", "Yes": "Ja", "Recommendation": "Empfehlung", @@ -1387,7 +1387,7 @@ "DownloadClientValidationApiKeyRequired": "API-Key benötigt", "DownloadClientValidationAuthenticationFailure": "Authentifizierung fehlgeschlagen", "DownloadClientValidationErrorVersion": "{clientName} Version sollte mindestens {requiredVersion} sein. Die gemeldete Version ist {reportedVersion}", - "IndexerDownloadClientHealthCheckMessage": "Indexer mit ungültigen Downloader: {indexerNames}.", + "IndexerDownloadClientHealthCheckMessage": "Indexer mit ungültigen Download-Clients: {indexerNames}.", "CustomFormatsSpecificationFlag": "Markierung", "CustomFormatsSpecificationRegularExpressionHelpText": "Benutzerdefiniertes Format RegEx ist nicht groß-/kleinschreibungssensitiv", "DownloadClientSabnzbdValidationUnknownVersion": "Unbekannte Version: {rawVersion}", @@ -1412,7 +1412,7 @@ "DownloadClientSettingsCategorySubFolderHelpText": "Das Hinzufügen einer spezifischen Kategorie für {appName} vermeidet Konflikte mit nicht verwandten Downloads, die nicht {appName} sind. Die Verwendung einer Kategorie ist optional, wird aber dringend empfohlen. Erzeugt ein Unterverzeichnis [category] im Ausgabeverzeichnis.", "DownloadClientSettingsRecentPriority": "Neueste Priorität", "DownloadClientDelugeSettingsDirectory": "Download Verzeichnis", - "DownloadClientDelugeSettingsDirectoryCompleted": "Verschieben, wenn Verzeichnis abgeschlossen", + "DownloadClientDelugeSettingsDirectoryCompleted": "Verschieben, wenn abgeschlossen Verzeichnis", "IgnoreDownloads": "Downloads ignorieren", "BlocklistFilterHasNoItems": "Ausgewählter Blocklistenfilter enthält keine Elemente", "ChangeCategoryMultipleHint": "Änderung der Downloads in die 'Post-Import-Kategorie' vom Download-Client", @@ -1420,28 +1420,28 @@ "DownloadClientSettingsDestinationHelpText": "Legt das Ziel für den Download manuell fest; lassen Sie es leer, um die Standardeinstellung zu verwenden", "DownloadClientSettingsUseSslHelpText": "Sichere Verbindung verwenden, wenn Verbindung zu {clientName} hergestellt wird", "DownloadClientValidationCategoryMissingDetail": "Die von Ihnen eingegebene Kategorie existiert nicht in {clientName}. Erstellen Sie sie zuerst in {clientName}.", - "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Sie müssen die Datumssortierung für die von {appName} verwendete Kategorie deaktivieren, um Importprobleme zu vermeiden. Gehen Sie zu Sabnzbd, um das Problem zu beheben.", - "EditImportListImplementation": "Importliste hinzufügen - {implementationName}", + "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Du musst die Film-Sortierung für die Kategorie deaktivieren, die {appName} verwendet, um Importprobleme zu vermeiden. Gehe zu Sabnzbd, um das zu beheben.", + "EditImportListImplementation": "Import-Liste bearbeiten - {implementationName}", "MovieIsNotMonitored": "Film wird nicht beobachtet", "SearchForAllMissingMovies": "Suche nach allen fehlenden Alben", - "Trace": "Rückverfolgung", - "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Sie müssen die Datumssortierung für die von {appName} verwendete Kategorie deaktivieren, um Importprobleme zu vermeiden. Gehen Sie zu Sabnzbd, um das Problem zu beheben.", + "Trace": "Trace", + "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Du musst die TV-Sortierung für die Kategorie deaktivieren, die {appName} verwendet, um Importprobleme zu vermeiden. Gehe zu Sabnzbd, um das zu beheben.", "DownloadClientSettingsRecentPriorityMovieHelpText": "Priorität beim Abrufen von Episoden, die innerhalb der letzten 14 Tage ausgestrahlt wurden", - "EditConditionImplementation": "Verbindung hinzufügen - {implementationName}", - "FormatAgeHour": "Stunden", - "FormatAgeMinute": "Minuten", + "EditConditionImplementation": "Bedingung bearbeiten - {implementationName}", + "FormatAgeHour": "Stunde", + "FormatAgeMinute": "Minute", "MovieFileDeleted": "Bei Filmdatei löschen", "MovieSearchResultsLoadError": "Suchergebnisse für diesen Film konnten nicht geladen werden. Versuche es später nocheinmal", "DeleteSelectedMovieFilesHelpText": "Ausgewählte Filme wirklich löschen?", "ShowUnknownMovieItemsHelpText": "Einträge ohne eine Zuordnung in der Warteschlange anzeigen. Dies könnten gelöschte Filme oder alles andere mit {appName}s Downloadkategorie sein", "MovieFolderFormatHelpText": "Wird verwendet, wenn Sie eine neue Serie hinzufügen oder eine Serie über den Serieneditor verschieben", - "IndexerSettingsMultiLanguageRelease": "Mehrsprachig", - "NotificationsCustomScriptValidationFileDoesNotExist": "Ordner existiert nicht", + "IndexerSettingsMultiLanguageRelease": "Mehrsprachige Releases", + "NotificationsCustomScriptValidationFileDoesNotExist": "Datei existiert nicht", "DownloadClientSettingsOlderPriorityMovieHelpText": "Priorität beim Abrufen von Episoden, die vor mehr als 14 Tagen ausgestrahlt wurden", "EditConnectionImplementation": "Anwendung hinzufügen - {implementationName}", - "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", - "DownloadClientDelugeSettingsDirectoryHelpText": "Optionaler Speicherort für Downloads. Lassen Sie das Feld leer, um den standardmäßigen rTorrent-Speicherort zu verwenden", - "ListQualityProfileHelpText": "Qualitätsprofil mit dem Listemelemente hinzugefügt werden sollen", + "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Optionaler Ort, an den abgeschlossene Downloads verschoben werden, leer lassen, um den Standard-Deluge-Ort zu verwenden", + "DownloadClientDelugeSettingsDirectoryHelpText": "Optionaler Ort für Downloads, leer lassen, um den Standard-Deluge-Ort zu verwenden", + "ListQualityProfileHelpText": "Qualitätsprofil-Listenelemente werden mit hinzugefügt", "DeletedReasonMovieMissingFromDisk": "{appName} konnte die Datei auf der Festplatte nicht finden, daher wurde die Verknüpfung der Datei mit der Episode in der Datenbank aufgehoben", "ReleaseProfileTagMovieHelpText": "Veröffentlichungsprofile gelten für Künstler mit mindestens einem passenden Tag. Leer lassen, damit es für alle Künstler gilt", "SearchForAllMissingMoviesConfirmationCount": "Bist du dir sicher, dass du nach allen '{0}' fehlenden Alben suchen willst?", @@ -1454,22 +1454,338 @@ "DeleteMovieFoldersHelpText": "Löschen Sie die Serienordner und ihren gesamten Inhalt", "DeleteSelectedMovies": "Ausgewählte Serie löschen", "Any": "Beliebig", - "DeleteSelected": "Markierte löschen", - "DeleteSelectedImportListExclusionsMessageText": "Bist du sicher, dass du diesen Importlisten Ausschluss löschen willst?", + "DeleteSelected": "Ausgewählte löschen", + "DeleteSelectedImportListExclusionsMessageText": "Bist du sicher, dass du die ausgewählten Importlistenausschlüsse löschen möchtest?", "ProgressBarProgress": "Fortschrittsbalken bei {progress}%", - "DeleteSelectedCustomFormats": "Benutzerdefiniertes Format löschen", - "DeleteSelectedCustomFormatsMessageText": "Sind Sie sicher, dass Sie {count} ausgewählte Importliste(n) löschen möchten?", + "DeleteSelectedCustomFormats": "Custom Format(s) löschen", + "DeleteSelectedCustomFormatsMessageText": "Bist du sicher, dass du {count} ausgewählte Custom Format(s) löschen möchtest?", "ReleaseDate": "VÖ Termine", "ShowDigitalRelease": "Erscheinungsdatum des Kinos anzeigen", "ShowDigitalReleaseHelpText": "Kino-Erscheinungsdatum unter Poster anzeigen", "ShowPhysicalRelease": "Disc Veröffentlichungsdatum", "ShowPhysicalReleaseHelpText": "Kino-Erscheinungsdatum unter Poster anzeigen", - "FolderNameTokens": "Dateinamen Teile", + "FolderNameTokens": "Ordnernamen Token", "DefaultNotFoundMessage": "Sie müssen verloren sein, hier gibt es nichts zu sehen.", "ToggleMonitoredToUnmonitored": "Überwacht, klicken Sie, um die Überwachung aufzuheben", "ToggleUnmonitoredToMonitored": "Nicht überwacht, klicke zum Überwachen", - "DownloadIgnored": "Importiere herunterladen", - "Completed": "Vollständig", + "DownloadIgnored": "Download Ignoriert", + "Completed": "Fertiggestellt", "Delay": "Verzögerung", - "DownloadClientUnavailable": "Downloader ist nicht verfügbar" + "DownloadClientUnavailable": "Download Client nicht verfügbar", + "Fallback": "Fallback", + "FavoriteFolderAdd": "Favoritenordner hinzufügen", + "FavoriteFolderRemove": "Favoritenordner entfernen", + "FavoriteFolders": "Favoritenordner", + "DownloadClientValidationTestNzbs": "Die Liste der NZBs konnte nicht abgerufen werden: {exceptionMessage}", + "EditSelectedCustomFormats": "Ausgewählte benutzerdefinierte Formate bearbeiten", + "HourShorthand": "h", + "FileBrowser": "Dateibrowser", + "FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}", + "DownloadClientValidationUnableToConnect": "Verbindung zu {clientName} kann nicht hergestellt werden", + "DownloadClientValidationUnableToConnectDetail": "Bitte überprüfe den Hostnamen und den Port.", + "DownloadClientValidationUnknownException": "Unbekannte Ausnahme: {exception}", + "DownloadClientValidationVerifySslDetail": "Bitte überprüfe deine SSL-Konfiguration sowohl auf {clientName} als auch auf {appName}", + "DownloadClientQbittorrentSettingsContentLayout": "Inhaltslayout", + "External": "Extern", + "FailedToFetchUpdates": "Updates konnten nicht abgerufen werden", + "DownloadClientSabnzbdValidationEnableJobFolders": "Auftragsordner aktivieren", + "DownloadClientValidationVerifySsl": "Überprüfe die SSL-Einstellungen", + "DownloadStationStatusExtracting": "Extrahieren: {progress}%", + "FormatAgeDay": "Tag", + "FormatDateTime": "{formattedDate} {formattedTime}", + "Example": "Beispiel", + "False": "Falsch", + "CustomFormatsSpecificationExceptLanguage": "Ausgenommen Sprache", + "DownloadClientValidationTestTorrents": "Die Liste der Torrents konnte nicht abgerufen werden: {exceptionMessage}", + "EditAutoTag": "Automatische Tags bearbeiten", + "LogFilesLocation": "Protokolldateien befinden sich unter: {location}", + "NotificationsSignalSettingsSenderNumberHelpText": "Telefonnummer des Absenders, die bei signal-api registriert ist", + "FormatShortTimeSpanHours": "{hours} Stunde(n)", + "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} bevorzugt es, dass jeder Download einen eigenen Ordner hat. Mit * am Ordner/Path wird Sabnzbd diese Job-Ordner nicht erstellen. Gehe zu Sabnzbd, um das zu beheben.", + "NotificationsAppriseSettingsServerUrl": "Apprise Server URL", + "NotificationsAppriseSettingsStatelessUrlsHelpText": "Eine oder mehrere URLs, durch Kommas getrennt, die angeben, wohin die Benachrichtigung gesendet werden soll. Leer lassen, wenn persistenter Speicher verwendet wird.", + "NotificationsCustomScriptSettingsName": "Benutzerdefiniertes Skript", + "NotificationsKodiSettingsUpdateLibraryHelpText": "Bibliothek bei Import & Umbenennung aktualisieren?", + "NotificationsSendGridSettingsApiKeyHelpText": "Der von SendGrid generierte API-Schlüssel", + "NotificationsDiscordSettingsAvatarHelpText": "Ändere den Avatar, der für Nachrichten dieser Integration verwendet wird", + "EditMetadata": "{metadataType}-Metadaten bearbeiten", + "IndexerSettingsRejectBlocklistedTorrentHashes": "Blockierte Torrent-Hashes beim Abrufen ablehnen", + "LogSizeLimit": "Protokollgrößenlimit", + "Logout": "Abmelden", + "ManageCustomFormats": "Benutzerdefinierte Formate verwalten", + "FormatShortTimeSpanMinutes": "{minutes} Minute(n)", + "FullColorEvents": "Vollfarbige Ereignisse", + "NotificationsDiscordSettingsOnImportFields": "On Import Felder", + "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "Ändere die Felder, die für diese 'On Manual Interaction'-Benachrichtigung übergeben werden", + "NotificationsJoinSettingsNotificationPriority": "Benachrichtigungspriorität", + "RootFolderPath": "Root-Ordner-Pfad", + "FormatRuntimeHours": "{hours}h", + "FormatRuntimeMinutes": "{minutes}m", + "CountCustomFormatsSelected": "{count} benutzerdefiniertes Format(e) ausgewählt", + "IndexerSettingsSeedRatioHelpText": "Das Verhältnis, das ein Torrent erreichen muss, bevor er gestoppt wird. Leer verwendet das Standardverhältnis des Download-Clients. Das Verhältnis sollte mindestens 1,0 betragen und den Regeln des Indexers folgen.", + "InstallMajorVersionUpdateMessageLink": "Weitere Informationen findest du unter [{domain}]({url}).", + "InteractiveImportNoImportMode": "Ein Importmodus muss ausgewählt werden", + "Menu": "Menü", + "NotificationsPlexSettingsServer": "Server", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "Fügt der {clientName}-rpc-URL ein Präfix hinzu, z. B. {url}, standardmäßig '{defaultUrl}'", + "DownloadClientValidationAuthenticationFailureDetail": "Bitte überprüfe deinen Benutzernamen und dein Passwort. Stelle auch sicher, dass der Host, der {appName} ausführt, nicht durch WhiteList-Beschränkungen in der {clientName}-Konfiguration blockiert wird.", + "DownloadClientValidationSslConnectFailureDetail": "{appName} kann keine Verbindung zu {clientName} über SSL herstellen. Dieses Problem könnte mit dem Computer zusammenhängen. Versuche, sowohl {appName} als auch {clientName} so zu konfigurieren, dass sie kein SSL verwenden.", + "FormatTimeSpanDays": "{days}d {time}", + "FullColorEventsHelpText": "Änderung des Stils, um das gesamte Ereignis mit der Statusfarbe zu färben, anstatt nur den linken Rand. Gilt nicht für Agenda", + "InfoUrl": "Info-URL", + "MassSearchCancelWarning": "Dies kann nicht abgebrochen werden, sobald es gestartet wurde, ohne {appName} neu zu starten oder alle Indexer zu deaktivieren.", + "MinimumCustomFormatScoreIncrement": "Mindeststeigerung des benutzerdefinierten Formatwerts", + "DayOfWeekAt": "{day} um {time}", + "NotificationsAppriseSettingsNotificationType": "Apprise Benachrichtigungstyp", + "Underscore": "Unterstrich", + "NotificationsAppriseSettingsTags": "Apprise Tags", + "NotificationsTwitterSettingsConnectToTwitter": "Mit Twitter / X verbinden", + "LabelIsRequired": "Label ist erforderlich", + "NotificationsNtfySettingsTagsEmojis": "Ntfy-Tags und Emojis", + "NotificationsKodiSettingsGuiNotification": "GUI-Benachrichtigung", + "NotificationsSettingsWebhookUrl": "Webhook-URL", + "OverrideGrabNoLanguage": "Mindestens eine Sprache muss ausgewählt werden", + "OverrideGrabNoQuality": "Qualität muss ausgewählt werden", + "NotificationsEmbySettingsUpdateLibraryHelpText": "Bibliothek bei Import, Umbenennung oder Löschung aktualisieren", + "InteractiveImportNoQuality": "Qualität muss für jede ausgewählte Datei gewählt werden", + "CutoffUnmetLoadError": "Fehler beim Laden der nicht erfüllten Cutoff-Elemente", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Ob das konfigurierte Inhaltslayout von qBittorrent, das ursprüngliche Layout des Torrents oder immer ein Unterordner erstellt werden soll (qBittorrent 4.3.2+)", + "InteractiveImportNoFilesFound": "Keine Videodateien im ausgewählten Ordner gefunden", + "NoDelay": "Keine Verzögerung", + "NotificationsAppriseSettingsUsernameHelpText": "HTTP Basic Auth Benutzername", + "NotificationsDiscordSettingsAuthorHelpText": "Überschreibe den Embed-Autor, der für diese Benachrichtigung angezeigt wird. Leer ist der Instanzname", + "NotificationsNtfySettingsTagsEmojisHelpText": "Optionale Liste von Tags oder Emojis zur Verwendung", + "NotificationsPushoverSettingsSound": "Ton", + "NotificationsPushoverSettingsUserKey": "Benutzer-Schlüssel", + "NotificationsSynologyValidationInvalidOs": "Muss ein Synology sein", + "NotificationsPushoverSettingsExpireHelpText": "Maximale Zeit, um Notfallwarnungen zu wiederholen, maximal 86400 Sekunden", + "NotificationsSlackSettingsChannelHelpText": "Überschreibt den Standardkanal für den eingehenden Webhook (#anderer-kanal)", + "NotificationsValidationInvalidAccessToken": "Access-Token ist ungültig", + "OneMinute": "1 Minute", + "IndexerSettingsMultiLanguageReleaseHelpText": "Welche Sprachen sind normalerweise in einem Release mit mehreren Sprachen auf diesem Indexer?", + "NotificationsAppriseSettingsStatelessUrls": "Apprise Stateless URLs", + "NotificationsDiscordSettingsAvatar": "Avatar", + "NotificationsEmailSettingsRecipientAddress": "Empfängeradresse(n)", + "NotificationsGotifySettingsAppTokenHelpText": "Das von Gotify generierte Anwendungstoken", + "NotificationsJoinSettingsApiKeyHelpText": "Der API-Schlüssel aus deinen Join-Kontoeinstellungen (klicke auf den Join API-Button).", + "NotificationsNtfySettingsPasswordHelpText": "Optionales Passwort", + "NotificationsPushoverSettingsExpire": "Ablauf", + "NotificationsSlackSettingsIcon": "Symbol", + "NotificationsSlackSettingsWebhookUrlHelpText": "Webhook-URL des Slack-Kanals", + "NotificationsTwitterSettingsConsumerKeyHelpText": "Consumer Key aus einer Twitter-Anwendung", + "LastSearched": "Letzte Suche", + "MissingNoItems": "Keine fehlenden Elemente", + "NotificationsAppriseSettingsPasswordHelpText": "HTTP Basic Auth Passwort", + "NotificationsAppriseSettingsServerUrlHelpText": "Apprise Server-URL, einschließlich http(s):// und Port, falls erforderlich", + "NotificationsAppriseSettingsTagsHelpText": "Benachrichtige optional nur diejenigen, die entsprechend markiert sind.", + "NotificationsCustomScriptSettingsArgumentsHelpText": "Argumente, die an das Skript übergeben werden sollen", + "NotificationsDiscordSettingsOnImportFieldsHelpText": "Ändere die Felder, die für diese 'On Import'-Benachrichtigung übergeben werden", + "NotificationsDiscordSettingsOnManualInteractionFields": "On Manual Interaction Felder", + "NotificationsDiscordSettingsWebhookUrlHelpText": "Discord Channel Webhook URL", + "NotificationsEmailSettingsBccAddress": "BCC-Adresse(n)", + "NotificationsEmailSettingsBccAddressHelpText": "Durch Kommas getrennte Liste der BCC-Empfänger", + "NotificationsEmailSettingsCcAddress": "CC-Adresse(n)", + "NotificationsEmailSettingsCcAddressHelpText": "Durch Kommas getrennte Liste der CC-Empfänger", + "NotificationsEmailSettingsServer": "Server", + "NotificationsEmailSettingsUseEncryption": "Verschlüsselung verwenden", + "NotificationsEmbySettingsSendNotifications": "Benachrichtigungen senden", + "NotificationsEmbySettingsSendNotificationsHelpText": "Lass Emby Benachrichtigungen an konfigurierte Anbieter senden. Nicht unterstützt auf Jellyfin.", + "NotificationsGotifySettingsPriorityHelpText": "Priorität der Benachrichtigung", + "NotificationsGotifySettingsServer": "Gotify-Server", + "NotificationsGotifySettingsServerHelpText": "Gotify Server URL, einschließlich http(s):// und Port, falls erforderlich", + "NotificationsJoinSettingsDeviceIds": "Geräte-IDs", + "NotificationsJoinSettingsDeviceIdsHelpText": "Veraltet, verwende stattdessen Gerätenamen. Durch Kommas getrennte Liste der Geräte-IDs, an die du Benachrichtigungen senden möchtest. Wenn nicht gesetzt, erhalten alle Geräte Benachrichtigungen.", + "NotificationsJoinSettingsDeviceNamesHelpText": "Durch Kommas getrennte Liste der vollständigen oder teilweisen Gerätenamen, an die du Benachrichtigungen senden möchtest. Wenn nicht gesetzt, erhalten alle Geräte Benachrichtigungen.", + "NotificationsKodiSettingAlwaysUpdateHelpText": "Bibliothek auch aktualisieren, wenn ein Video abgespielt wird?", + "NotificationsKodiSettingsDisplayTime": "Anzeigezeit", + "NotificationsMailgunSettingsApiKeyHelpText": "Der von MailGun generierte API-Schlüssel", + "NotificationsNotifiarrSettingsApiKeyHelpText": "Dein API-Schlüssel aus deinem Profil", + "NotificationsNtfySettingsClickUrl": "Klick-URL", + "NotificationsNtfySettingsTopics": "Themen", + "NotificationsNtfySettingsTopicsHelpText": "Liste von Themen, an die Benachrichtigungen gesendet werden sollen", + "NotificationsPlexSettingsAuthToken": "Auth-Token", + "NotificationsPushBulletSettingsChannelTagsHelpText": "Liste von Kanal-Tags, an die Benachrichtigungen gesendet werden sollen", + "NotificationsPushoverSettingsRetryHelpText": "Intervall, um Notfallwarnungen zu wiederholen, mindestens 30 Sekunden", + "NotificationsSettingsUpdateMapPathsTo": "Pfade zu", + "NotificationsSettingsUseSslHelpText": "Mit {serviceName} über HTTPS anstatt HTTP verbinden", + "NotificationsSlackSettingsChannel": "Kanal", + "NotificationsValidationInvalidAuthenticationToken": "Authentifizierungstoken ist ungültig", + "NotificationsValidationInvalidUsernamePassword": "Ungültiger Benutzername oder Passwort", + "NotificationsValidationUnableToConnectToService": "Kann keine Verbindung zu {serviceName} herstellen", + "OptionalName": "Optionaler Name", + "ParseModalHelpTextDetails": "{appName} wird versuchen, den Titel zu parsen und dir Details darüber zu zeigen", + "NotificationsKodiSettingAlwaysUpdate": "Immer aktualisieren", + "NotificationsKodiSettingsCleanLibraryHelpText": "Bibliothek nach der Aktualisierung bereinigen", + "NotificationsTwitterSettingsMention": "Erwähnen", + "ParseModalHelpText": "Gib einen Release-Titel im Eingabefeld oben ein", + "ManualGrab": "Manuelles Greifen", + "SubtitleLanguages": "Untertitelsprache", + "NotificationsKodiSettingsCleanLibrary": "Bibliothek bereinigen", + "NotificationsTelegramSettingsBotToken": "Bot-Token", + "NotificationsJoinSettingsDeviceNames": "Gerätenamen", + "NotificationsJoinValidationInvalidDeviceId": "Geräte-IDs sind ungültig.", + "NotificationsMailgunSettingsSenderDomain": "Absenderdomain", + "NotificationsNtfySettingsAccessToken": "Zugriffs-Token", + "NotificationsPushBulletSettingsAccessToken": "Access-Token", + "NotificationsPushBulletSettingsDeviceIds": "Geräte-IDs", + "NotificationsPushcutSettingsNotificationName": "Benachrichtigungsname", + "Unknown": "Unbekannt", + "SmartReplace": "Smart Replace", + "InvalidUILanguage": "Die UI ist auf eine ungültige Sprache eingestellt, korrigiere sie und speichere die Einstellungen", + "LanguagesLoadError": "Sprachen konnten nicht geladen werden", + "NotificationsPushoverSettingsSoundHelpText": "Benachrichtigungston, leer lassen, um den Standardton zu verwenden", + "NotificationsSettingsWebhookMethodHelpText": "Welche HTTP-Methode zum Absenden an den Webservice verwendet werden soll", + "CountVotes": "{votes} Stimmen", + "OnFileImport": "Bei Dateiimport", + "OnFileUpgrade": "Bei Dateiupgrade", + "NotificationsGotifySettingsMetadataLinks": "Metadaten-Links", + "ManageFormats": "Formate verwalten", + "NotificationsSignalSettingsGroupIdPhoneNumber": "Gruppen-ID / Telefonnummer", + "VideoDynamicRange": "Video-Dynamikbereich", + "CustomFormatsSpecificationExceptLanguageHelpText": "Übereinstimmt, wenn eine andere Sprache als die ausgewählte Sprache vorhanden ist", + "CutoffUnmetNoItems": "Keine nicht erfüllten Cutoff-Elemente", + "DownloadClientQbittorrentTorrentStatePathError": "Import fehlgeschlagen. Der Pfad stimmt mit dem Basis-Download-Verzeichnis des Clients überein. Möglicherweise ist 'Obersten Ordner beibehalten' für diesen Torrent deaktiviert oder das 'Torrent-Inhaltslayout' ist nicht auf 'Original' oder 'Unterordner erstellen' eingestellt.", + "DownloadClientVuzeValidationErrorVersion": "Protokollversion nicht unterstützt, verwende Vuze 5.0.0.0 oder höher mit dem Vuze Web Remote Plugin.", + "FormatShortTimeSpanSeconds": "{seconds} Sekunde(n)", + "HealthMessagesInfoBox": "Weitere Informationen zur Ursache dieser Gesundheitsprüfungsnachrichten findest du, indem du auf den Wiki-Link (Buch-Symbol) am Ende der Zeile klickst oder deine [Protokolle]({link}) überprüfst. Wenn du Schwierigkeiten hast, diese Nachrichten zu interpretieren, kannst du unseren Support kontaktieren, über die Links unten.", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Wenn ein Torrent durch einen Hash blockiert wird, wird er möglicherweise nicht korrekt abgelehnt während RSS/Recherche für einige Indexer. Diese Option aktiviert die Ablehnung des Torrents nach dem Abrufen, aber bevor er an den Client gesendet wird.", + "IndexerSettingsSeedRatio": "Seed-Verhältnis", + "IndexerSettingsSeedTime": "Seed-Zeit", + "IndexerSettingsSeedTimeHelpText": "Die Zeit, die ein Torrent gesät werden sollte, bevor er gestoppt wird. Leer verwendet die Standardzeit des Download-Clients", + "Install": "Installieren", + "InstallMajorVersionUpdate": "Update installieren", + "InstallMajorVersionUpdateMessage": "Dieses Update wird eine neue Hauptversion installieren und ist möglicherweise nicht mit deinem System kompatibel. Bist du sicher, dass du dieses Update installieren möchtest?", + "LogSizeLimitHelpText": "Maximale Protokolldateigröße in MB, bevor archiviert wird. Standard ist 1MB.", + "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages unterstützen einen `:EN+DE`-Suffix, der es dir ermöglicht, die im Dateinamen enthaltenen Sprachen zu filtern. Verwende `-DE`, um spezifische Sprachen auszuschließen. Das Anhängen von `+` (z.B. `:EN+`) wird `[EN]`/`[EN+--]`/`[--]` ausgeben, je nachdem, welche Sprachen ausgeschlossen sind. Zum Beispiel `{MediaInfo Full:EN+DE}`.", + "MinimumCustomFormatScoreIncrementHelpText": "Mindestanforderung an die Verbesserung des benutzerdefinierten Formatwerts zwischen bestehenden und neuen Releases, bevor {appName} es als Upgrade betrachtet", + "MissingLoadError": "Fehler beim Laden der fehlenden Elemente", + "NoBlocklistItems": "Keine Blocklist-Elemente", + "NoCustomFormatsFound": "Keine benutzerdefinierten Formate gefunden", + "NoHistoryFound": "Keine Historie gefunden", + "NotificationsAppriseSettingsConfigurationKey": "Apprise Konfigurationsschlüssel", + "NotificationsAppriseSettingsConfigurationKeyHelpText": "Konfigurationsschlüssel für die Persistente Speicherlösung. Leer lassen, wenn Stateless URLs verwendet wird.", + "NotificationsCustomScriptSettingsArguments": "Argumente", + "NotificationsCustomScriptSettingsProviderMessage": "Das Testen führt das Skript mit dem EventType {eventTypeTest} aus, stelle sicher, dass dein Skript dies korrekt verarbeitet", + "NotificationsDiscordSettingsOnGrabFields": "On Grab Felder", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Ändere die Felder, die für diese 'On Grab'-Benachrichtigung übergeben werden", + "NotificationsDiscordSettingsUsernameHelpText": "Der Benutzername, unter dem gepostet wird, standardmäßig der Discord Webhook-Standard", + "NotificationsEmailSettingsFromAddress": "Von-Adresse", + "NotificationsEmailSettingsName": "E-Mail", + "NotificationsEmailSettingsRecipientAddressHelpText": "Durch Kommas getrennte Liste der Empfängeradressen", + "NotificationsEmailSettingsServerHelpText": "Hostname oder IP des E-Mail-Servers", + "NotificationsEmailSettingsUseEncryptionHelpText": "Ob bevorzugt Verschlüsselung verwendet werden soll, wenn auf dem Server konfiguriert, ob immer Verschlüsselung über SSL (nur Port 465) oder StartTLS (anderer Port) verwendet wird oder keine Verschlüsselung verwendet wird", + "NotificationsGotifySettingsPreferredMetadataLink": "Bevorzugter Metadaten-Link", + "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Metadaten-Link für Clients, die nur einen Link unterstützen", + "NotificationsKodiSettingsDisplayTimeHelpText": "Wie lange die Benachrichtigung angezeigt wird (in Sekunden)", + "NotificationsMailgunSettingsUseEuEndpoint": "EU-Endpunkt verwenden", + "NotificationsMailgunSettingsUseEuEndpointHelpText": "Aktiviere, um den EU-MailGun-Endpunkt zu verwenden", + "NotificationsNtfySettingsAccessTokenHelpText": "Optionale tokenbasierte Authentifizierung. Hat Vorrang vor Benutzername/Passwort", + "NotificationsNtfySettingsClickUrlHelpText": "Optionaler Link, wenn der Benutzer auf die Benachrichtigung klickt", + "NotificationsNtfySettingsServerUrl": "Server-URL", + "NotificationsNtfySettingsServerUrlHelpText": "Leer lassen, um den öffentlichen Server ({url}) zu verwenden", + "NotificationsNtfySettingsUsernameHelpText": "Optionaler Benutzername", + "NotificationsNtfyValidationAuthorizationRequired": "Autorisation erforderlich", + "NotificationsPlexSettingsAuthenticateWithPlexTv": "Mit Plex.tv authentifizieren", + "NotificationsPlexSettingsServerHelpText": "Wählen Sie den Server aus dem Plex.tv-Konto nach der Authentifizierung", + "NotificationsPushBulletSettingSenderId": "Sender-ID", + "NotificationsPushBulletSettingSenderIdHelpText": "Die Geräte-ID, von der Benachrichtigungen gesendet werden, verwenden Sie device_iden in der Geräte-URL auf pushbullet.com (leer lassen, um von sich selbst zu senden)", + "NotificationsPushBulletSettingsChannelTags": "Kanal-Tags", + "NotificationsPushBulletSettingsDeviceIdsHelpText": "Liste von Geräte-IDs (leer lassen, um an alle Geräte zu senden)", + "NotificationsPushcutSettingsApiKeyHelpText": "API-Schlüssel können in der Kontenansicht der Pushcut-App verwaltet werden", + "NotificationsPushcutSettingsNotificationNameHelpText": "Benachrichtigungsname aus dem Benachrichtigungsbereich der Pushcut-App", + "NotificationsPushcutSettingsTimeSensitive": "Zeitkritisch", + "NotificationsPushcutSettingsTimeSensitiveHelpText": "Aktivieren, um die Benachrichtigung als \"Zeitkritisch\" zu markieren", + "NotificationsPushoverSettingsDevices": "Geräte", + "NotificationsPushoverSettingsDevicesHelpText": "Liste von Gerätenamen (leer lassen, um an alle Geräte zu senden)", + "NotificationsPushoverSettingsRetry": "Wiederholen", + "NotificationsSettingsUpdateLibrary": "Bibliothek aktualisieren", + "NotificationsSettingsUpdateMapPathsFrom": "Pfade von", + "NotificationsSettingsWebhookMethod": "Methode", + "NotificationsSettingsWebhookHeaders": "Header", + "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "Gruppen-ID / Telefonnummer des Empfängers", + "NotificationsSignalSettingsPasswordHelpText": "Passwort, das zur Authentifizierung von Anfragen an signal-api verwendet wird", + "NotificationsSignalSettingsSenderNumber": "Absendernummer", + "NotificationsSignalSettingsUsernameHelpText": "Benutzername, der zur Authentifizierung von Anfragen an signal-api verwendet wird", + "NotificationsSignalValidationSslRequired": "SSL scheint erforderlich zu sein", + "NotificationsSimplepushSettingsEventHelpText": "Verhalten der Push-Benachrichtigungen anpassen", + "NotificationsSimplepushSettingsKey": "Schlüssel", + "NotificationsSlackSettingsIconHelpText": "Ändere das Symbol, das für Nachrichten verwendet wird, die in Slack gepostet werden (Emoji oder URL)", + "NotificationsSlackSettingsUsernameHelpText": "Benutzername, der in Slack gepostet wird", + "NotificationsSynologySettingsUpdateLibraryHelpText": "Synoindex auf dem lokalen Host aufrufen, um eine Bibliotheksdatei zu aktualisieren", + "NotificationsSynologyValidationTestFailed": "Kein Synology oder synoindex nicht verfügbar", + "NotificationsTelegramSettingsChatId": "Chat-ID", + "NotificationsTelegramSettingsChatIdHelpText": "Du musst eine Unterhaltung mit dem Bot starten oder ihn zu deiner Gruppe hinzufügen, um Nachrichten zu erhalten", + "NotificationsTelegramSettingsIncludeAppName": "{appName} im Titel einfügen", + "NotificationsTelegramSettingsIncludeAppNameHelpText": "Optional den Nachrichtentitel mit {appName} voranstellen, um Benachrichtigungen von verschiedenen Anwendungen zu unterscheiden", + "NotificationsTelegramSettingsSendSilently": "Still senden", + "NotificationsTelegramSettingsSendSilentlyHelpText": "Sendet die Nachricht still. Nutzer erhalten eine Benachrichtigung ohne Ton", + "NotificationsTelegramSettingsTopicId": "Themen-ID", + "NotificationsTelegramSettingsTopicIdHelpText": "Gib eine Themen-ID an, um Benachrichtigungen an dieses Thema zu senden. Leer lassen, um das allgemeine Thema zu verwenden (nur Supergruppen)", + "NotificationsTraktSettingsAccessToken": "Access-Token", + "NotificationsTraktSettingsAuthUser": "Auth-Benutzer", + "NotificationsTraktSettingsAuthenticateWithTrakt": "Mit Trakt authentifizieren", + "NotificationsTraktSettingsExpires": "Abläuft", + "NotificationsTraktSettingsRefreshToken": "Refresh-Token", + "NotificationsTwitterSettingsAccessToken": "Access-Token", + "NotificationsTwitterSettingsAccessTokenSecret": "Access-Token-Geheimnis", + "NotificationsTwitterSettingsConsumerKey": "Consumer Key", + "NotificationsTwitterSettingsConsumerSecret": "Consumer Secret", + "NotificationsTwitterSettingsConsumerSecretHelpText": "Consumer Secret aus einer Twitter-Anwendung", + "NotificationsTwitterSettingsDirectMessage": "Direktnachricht", + "NotificationsTwitterSettingsDirectMessageHelpText": "Sende eine Direktnachricht anstelle einer öffentlichen Nachricht", + "NotificationsTwitterSettingsMentionHelpText": "Erwähne diesen Benutzer in gesendeten Tweets", + "NotificationsValidationInvalidApiKey": "API-Schlüssel ist ungültig", + "NotificationsValidationInvalidApiKeyExceptionMessage": "API-Schlüssel ist ungültig: {exceptionMessage}", + "NotificationsValidationInvalidHttpCredentials": "HTTP-Auth-Daten sind ungültig: {exceptionMessage}", + "NotificationsValidationUnableToConnect": "Verbindung konnte nicht hergestellt werden: {exceptionMessage}", + "NotificationsValidationUnableToConnectToApi": "Verbindung zum {service} API konnte nicht hergestellt werden. Serververbindung fehlgeschlagen: ({responseCode}) {exceptionMessage}", + "NotificationsValidationUnableToSendTestMessage": "Kann keine Testnachricht senden: {exceptionMessage}", + "NotificationsValidationUnableToSendTestMessageApiResponse": "Kann keine Testnachricht senden. Antwort von der API: {error}", + "NzbgetHistoryItemMessage": "PAR-Status: {parStatus} - Entpack-Status: {unpackStatus} - Verschiebe-Status: {moveStatus} - Script-Status: {scriptStatus} - Lösch-Status: {deleteStatus} - Markierungs-Status: {markStatus}", + "Or": "oder", + "OrganizeModalHeader": "Organisieren & Umbenennen", + "OrganizeRelativePaths": "Alle Pfade sind relativ zu: `{path}`", + "OrganizeRenamingDisabled": "Umbenennen ist deaktiviert, nichts zum Umbenennen", + "OverrideAndAddToDownloadQueue": "Überschreiben und in die Download-Warteschlange einfügen", + "OverrideGrabModalTitle": "Überschreiben und Abrufen - {title}", + "PackageVersionInfo": "{packageVersion} von {packageAuthor}", + "Parse": "Parsen", + "ParseModalErrorParsing": "Fehler beim Parsen, bitte versuche es erneut.", + "ParseModalUnableToParse": "Kann den angegebenen Titel nicht parsen, bitte versuche es erneut.", + "PasswordConfirmation": "Passwortbestätigung", + "PendingDownloadClientUnavailable": "Ausstehend - Download-Client nicht verfügbar", + "Period": "Periode", + "PostImportCategory": "Post-Import-Kategorie", + "PreferProtocol": "Bevorzuge {preferredProtocol}", + "PreviouslyInstalled": "Früher installiert", + "QualityCutoffNotMet": "Qualitätsgrenze wurde nicht erreicht", + "ReleaseGroupFootNote": "Optional die Trunkierung auf eine maximale Byteanzahl inkl. Auslassungszeichen (`...`) steuern. Trunkierung vom Ende (z. B. `{Release Group:30}`) oder vom Anfang (z. B. `{Release Group:-30}`) sind beide möglich.", + "ReleaseProfileIndexerHelpTextWarning": "Das Festlegen eines bestimmten Indexers für ein Release-Profil sorgt dafür, dass dieses Profil nur für Releases von diesem Indexer gilt.", + "RemoveFromDownloadClientHint": "Entfernt den Download und die Datei(en) aus dem Download-Client", + "RemoveMultipleFromDownloadClientHint": "Entfernt Downloads und Dateien aus dem Download-Client", + "RemoveQueueItem": "Entfernen - {sourceTitle}", + "RemoveQueueItemRemovalMethod": "Entfernmethode", + "RemoveQueueItemRemovalMethodHelpTextWarning": "'Aus dem Download-Client entfernen' wird den Download und die Datei(en) aus dem Download-Client löschen.", + "RemoveQueueItemsRemovalMethodHelpTextWarning": "'Aus dem Download-Client entfernen' wird die Downloads und die Dateien aus dem Download-Client löschen.", + "Repack": "Repacken", + "SelectIndexerFlags": "Indexer-Flags auswählen", + "SetIndexerFlags": "Indexer-Flags festlegen", + "SetIndexerFlagsModalTitle": "{modalTitle} - Indexer-Flags festlegen", + "ShowTags": "Tags anzeigen", + "ShowTagsHelpText": "Tags unter dem Poster anzeigen", + "SkipFreeSpaceCheckHelpText": "Verwenden, wenn {appName} den freien Speicherplatz des Root-Ordners nicht erkennen kann", + "SkipRedownloadHelpText": "Verhindert, dass {appName} einen alternativen Release für dieses Objekt herunterlädt", + "SmartReplaceHint": "Dash oder Space Dash je nach Name", + "SupportedAutoTaggingProperties": "{appName} unterstützt die folgenden Eigenschaften für Auto-Tagging-Regeln", + "TableOptionsButton": "Tabellenoptionen-Schaltfläche", + "TablePageSizeMaximum": "Die Seitengröße darf {maximumValue} nicht überschreiten", + "TablePageSizeMinimum": "Die Seitengröße muss mindestens {minimumValue} betragen", + "TagDetails": "Tag-Details - {label}", + "TodayAt": "Heute um {time}", + "TomorrowAt": "Morgen um {time}", + "TorrentBlackhole": "Torrent Blackhole", + "UnableToImportAutomatically": "Kann nicht automatisch importiert werden", + "UnknownEventTooltip": "Unbekanntes Ereignis", + "Warning": "Warnung", + "YesterdayAt": "Gestern um {time}" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index dee5788dd9..6b2f3c7969 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -518,7 +518,7 @@ "AutoRedownloadFailedHelpText": "自动搜索并尝试下载不同的发布资源", "AutomaticSearch": "自动搜索", "ICalShowAsAllDayEventsHelpText": "事件将以全天事件的形式显示在日历中", - "AppDataLocationHealthCheckMessage": "无法更新,以防止在更新时删除 AppData", + "AppDataLocationHealthCheckMessage": "为防止在更新时删除 AppData,更新将无法进行", "Announced": "已公布", "Analytics": "分析", "AllMoviesInPathHaveBeenImported": "在 {path} 中的所有电影已被导入", @@ -584,7 +584,7 @@ "InstallLatest": "安装最新版", "IndexerStatusCheckSingleClientMessage": "下列索引器因错误不可用:{indexerNames}", "IndexerStatusCheckAllClientMessage": "所有索引器都因错误不可用", - "IndexerSearchCheckNoInteractiveMessage": "没有索引器开启手动搜索,{appName} 将不会提供任何手动搜索结果", + "IndexerSearchCheckNoInteractiveMessage": "没有启用交互式搜索的索引器,{appName}将不提供任何交互式搜索结果", "IndexerRssHealthCheckNoIndexers": "没有索引器开启 RSS 同步,{appName} 将不会自动抓取新版本", "IndexerLongTermStatusCheckSingleClientMessage": "由于故障超过6小时,下列索引器已不可用:{indexerNames}", "IndexerLongTermStatusCheckAllClientMessage": "由于故障超过6小时,所有索引器均不可用", @@ -914,7 +914,7 @@ "MIA": "MIA", "MegabytesPerMinute": "每分钟MB", "Mechanism": "机制", - "MappedNetworkDrivesWindowsService": "映射的网络驱动器在作为Windows服务运行时不可用。请参阅常见问题解答了解更多信息", + "MappedNetworkDrivesWindowsService": "作为 Windows 服务运行时,映射的网络驱动器不可用,请参阅 [FAQ]({url}) 获取更多信息。", "MaintenanceRelease": "维护版本:修复错误及其他改进,参见Github提交 查看更多详情", "LogOnly": "只有日志", "LogLevelTraceHelpTextWarning": "追踪日志只应该暂时启用", @@ -1712,7 +1712,7 @@ "Logout": "注销", "Recommendation": "推荐", "NotificationsSynologyValidationInvalidOs": "必须是 Synology(群辉)设备", - "NoMovieReleaseDatesAvailable": "TMDb 上未找到此电影的发布日期。", + "NoMovieReleaseDatesAvailable": "[TMDb]({url}) 上未找到此电影的发布日期。", "NotificationsSlackSettingsChannelHelpText": "覆盖传入 Webhook 的默认渠道(#other-channel)", "NotificationsTelegramSettingsIncludeAppName": "标题中包含 {appName}", "UnableToImportAutomatically": "无法自动导入", diff --git a/src/NzbDrone.Core/Localization/Core/zh_HANS.json b/src/NzbDrone.Core/Localization/Core/zh_Hans.json similarity index 100% rename from src/NzbDrone.Core/Localization/Core/zh_HANS.json rename to src/NzbDrone.Core/Localization/Core/zh_Hans.json index 8b9f6d1631..b49f406e72 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_HANS.json +++ b/src/NzbDrone.Core/Localization/Core/zh_Hans.json @@ -1,6 +1,6 @@ { - "About": "关于", "Add": "添加", + "About": "关于", "Always": "总是", "Analytics": "分析", "Username": "用户名" From 01a53d362425d3b41977b20c960160112b8e37ea Mon Sep 17 00:00:00 2001 From: Servarr Date: Mon, 2 Dec 2024 13:53:27 +0000 Subject: [PATCH 113/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 78 +++++++++++++++++++++------------- 1 file changed, 49 insertions(+), 29 deletions(-) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 1634327679..4c29ccb060 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -5365,28 +5365,22 @@ "$ref": "#/components/schemas/MovieResource" } } - }, - "text/json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MovieResource" - } - } - }, - "application/*+json": { - "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/MovieResource" - } - } } } }, "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MovieResource" + } + } + } + } } } } @@ -5408,7 +5402,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MovieResource" + } + } + } } } } @@ -5429,7 +5430,14 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MovieResource" + } + } + } } } } @@ -5450,7 +5458,17 @@ ], "responses": { "200": { - "description": "OK" + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/MovieResource" + } + } + } + } } } } @@ -11669,15 +11687,6 @@ "type": "string", "nullable": true }, - "sizeleft": { - "type": "number", - "format": "double" - }, - "timeleft": { - "type": "string", - "format": "date-span", - "nullable": true - }, "estimatedCompletionTime": { "type": "string", "format": "date-time", @@ -11729,6 +11738,17 @@ "outputPath": { "type": "string", "nullable": true + }, + "sizeleft": { + "type": "number", + "format": "double", + "deprecated": true + }, + "timeleft": { + "type": "string", + "format": "date-span", + "nullable": true, + "deprecated": true } }, "additionalProperties": false From a6d727fe2a734163fcd23fb7e1180d285115d327 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 1 Dec 2024 16:20:55 -0800 Subject: [PATCH 114/579] New: Kometa metadata file creation disabled (cherry picked from commit c62fc9d05bb9e1fe51b454d78e80bd9250e31f89) Closes #10738 --- frontend/.eslintrc.js | 1 - frontend/src/App/State/AppSectionState.ts | 21 ++- frontend/src/App/State/MetadataAppState.ts | 6 + frontend/src/App/State/SettingsAppState.ts | 2 + .../Components/Form/ProviderFieldFormGroup.js | 2 + .../EditImportListExclusionModalContent.tsx | 2 +- .../Metadata/Metadata/EditMetadataModal.js | 27 --- .../Metadata/Metadata/EditMetadataModal.tsx | 36 ++++ .../Metadata/EditMetadataModalConnector.js | 44 ----- .../Metadata/EditMetadataModalContent.css | 5 + .../EditMetadataModalContent.css.d.ts | 7 + .../Metadata/EditMetadataModalContent.js | 105 ----------- .../Metadata/EditMetadataModalContent.tsx | 128 +++++++++++++ .../EditMetadataModalContentConnector.js | 95 ---------- .../Settings/Metadata/Metadata/Metadata.js | 150 ---------------- .../Settings/Metadata/Metadata/Metadata.tsx | 107 +++++++++++ .../Settings/Metadata/Metadata/Metadatas.js | 44 ----- .../Settings/Metadata/Metadata/Metadatas.tsx | 52 ++++++ .../Metadata/Metadata/MetadatasConnector.js | 47 ----- .../src/Settings/Metadata/MetadataSettings.js | 4 +- .../EditReleaseProfileModalContent.tsx | 15 +- .../src/Store/Selectors/selectSettings.js | 104 ----------- .../src/Store/Selectors/selectSettings.ts | 168 ++++++++++++++++++ frontend/src/typings/DownloadClient.ts | 22 +-- frontend/src/typings/Field.ts | 23 +++ frontend/src/typings/ImportList.ts | 20 +-- frontend/src/typings/Indexer.ts | 20 +-- frontend/src/typings/Metadata.ts | 7 + frontend/src/typings/Notification.ts | 20 +-- frontend/src/typings/Provider.ts | 20 +++ frontend/src/typings/pending.ts | 52 +++++- .../Consumers/Kometa/KometaMetadata.cs | 39 +--- .../Kometa/KometaMetadataSettings.cs | 6 +- .../HealthCheck/Checks/MetadataCheck.cs | 34 ++++ src/NzbDrone.Core/Localization/Core/en.json | 2 + 35 files changed, 697 insertions(+), 740 deletions(-) create mode 100644 frontend/src/App/State/MetadataAppState.ts delete mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModal.js create mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx delete mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalConnector.js create mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css create mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css.d.ts delete mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.js create mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx delete mode 100644 frontend/src/Settings/Metadata/Metadata/EditMetadataModalContentConnector.js delete mode 100644 frontend/src/Settings/Metadata/Metadata/Metadata.js create mode 100644 frontend/src/Settings/Metadata/Metadata/Metadata.tsx delete mode 100644 frontend/src/Settings/Metadata/Metadata/Metadatas.js create mode 100644 frontend/src/Settings/Metadata/Metadata/Metadatas.tsx delete mode 100644 frontend/src/Settings/Metadata/Metadata/MetadatasConnector.js delete mode 100644 frontend/src/Store/Selectors/selectSettings.js create mode 100644 frontend/src/Store/Selectors/selectSettings.ts create mode 100644 frontend/src/typings/Field.ts create mode 100644 frontend/src/typings/Metadata.ts create mode 100644 frontend/src/typings/Provider.ts create mode 100644 src/NzbDrone.Core/HealthCheck/Checks/MetadataCheck.cs diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index ddc7300fd1..77b933a8f7 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -210,7 +210,6 @@ module.exports = { 'no-undef-init': 'off', 'no-undefined': 'off', 'no-unused-vars': ['error', { args: 'none', ignoreRestSiblings: true }], - 'no-use-before-define': 'error', // Node.js and CommonJS diff --git a/frontend/src/App/State/AppSectionState.ts b/frontend/src/App/State/AppSectionState.ts index 27dc78aa18..de6f4d90c7 100644 --- a/frontend/src/App/State/AppSectionState.ts +++ b/frontend/src/App/State/AppSectionState.ts @@ -1,11 +1,16 @@ import Column from 'Components/Table/Column'; import { SortDirection } from 'Helpers/Props/sortDirections'; +import { ValidationFailure } from 'typings/pending'; import { FilterBuilderProp, PropertyFilter } from './AppState'; export interface Error { - responseJSON: { - message: string; - }; + status?: number; + responseJSON: + | { + message: string | undefined; + } + | ValidationFailure[] + | undefined; } export interface AppSectionDeleteState { @@ -51,6 +56,16 @@ export interface AppSectionItemState { item: T; } +export interface AppSectionProviderState + extends AppSectionDeleteState, + AppSectionSaveState { + isFetching: boolean; + isPopulated: boolean; + error: Error; + items: T[]; + pendingChanges: Partial; +} + interface AppSectionState { isFetching: boolean; isPopulated: boolean; diff --git a/frontend/src/App/State/MetadataAppState.ts b/frontend/src/App/State/MetadataAppState.ts new file mode 100644 index 0000000000..60d5c434cb --- /dev/null +++ b/frontend/src/App/State/MetadataAppState.ts @@ -0,0 +1,6 @@ +import { AppSectionProviderState } from 'App/State/AppSectionState'; +import Metadata from 'typings/Metadata'; + +interface MetadataAppState extends AppSectionProviderState {} + +export default MetadataAppState; diff --git a/frontend/src/App/State/SettingsAppState.ts b/frontend/src/App/State/SettingsAppState.ts index 40dd2656d1..b9f8e64b48 100644 --- a/frontend/src/App/State/SettingsAppState.ts +++ b/frontend/src/App/State/SettingsAppState.ts @@ -20,6 +20,7 @@ import NamingConfig from 'typings/Settings/NamingConfig'; import NamingExample from 'typings/Settings/NamingExample'; import ReleaseProfile from 'typings/Settings/ReleaseProfile'; import UiSettings from 'typings/Settings/UiSettings'; +import MetadataAppState from './MetadataAppState'; export interface DownloadClientAppState extends AppSectionState, @@ -97,6 +98,7 @@ interface SettingsAppState { indexerFlags: IndexerFlagSettingsAppState; indexers: IndexerAppState; languages: LanguageSettingsAppState; + metadata: MetadataAppState; naming: NamingAppState; namingExamples: NamingExamplesAppState; notifications: NotificationAppState; diff --git a/frontend/src/Components/Form/ProviderFieldFormGroup.js b/frontend/src/Components/Form/ProviderFieldFormGroup.js index 0cd23298e5..72f4ccef84 100644 --- a/frontend/src/Components/Form/ProviderFieldFormGroup.js +++ b/frontend/src/Components/Form/ProviderFieldFormGroup.js @@ -139,6 +139,8 @@ ProviderFieldFormGroup.propTypes = { type: PropTypes.string.isRequired, advanced: PropTypes.bool.isRequired, hidden: PropTypes.string, + isDisabled: PropTypes.bool, + provider: PropTypes.string, pending: PropTypes.bool.isRequired, errors: PropTypes.arrayOf(PropTypes.object).isRequired, warnings: PropTypes.arrayOf(PropTypes.object).isRequired, diff --git a/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx b/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx index 766f883c93..8ff410c71f 100644 --- a/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx +++ b/frontend/src/Settings/ImportLists/ImportListExclusions/EditImportListExclusionModalContent.tsx @@ -40,7 +40,7 @@ function createImportListExclusionSelector(id?: number) { importListExclusions; const mapping = id - ? items.find((i) => i.id === id) + ? items.find((i) => i.id === id)! : newImportListExclusion; const settings = selectSettings(mapping, pendingChanges, saveError); diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.js b/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.js deleted file mode 100644 index 4b33df5286..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.js +++ /dev/null @@ -1,27 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import { sizes } from 'Helpers/Props'; -import EditMetadataModalContentConnector from './EditMetadataModalContentConnector'; - -function EditMetadataModal({ isOpen, onModalClose, ...otherProps }) { - return ( - - - - ); -} - -EditMetadataModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default EditMetadataModal; diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx b/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx new file mode 100644 index 0000000000..6dd30ca785 --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx @@ -0,0 +1,36 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import Modal from 'Components/Modal/Modal'; +import { sizes } from 'Helpers/Props'; +import { clearPendingChanges } from 'Store/Actions/baseActions'; +import EditMetadataModalContent, { + EditMetadataModalContentProps, +} from './EditMetadataModalContent'; + +interface EditMetadataModalProps extends EditMetadataModalContentProps { + isOpen: boolean; +} + +function EditMetadataModal({ + isOpen, + onModalClose, + ...otherProps +}: EditMetadataModalProps) { + const dispatch = useDispatch(); + + const handleModalClose = useCallback(() => { + dispatch(clearPendingChanges({ section: 'metadata' })); + onModalClose(); + }, [dispatch, onModalClose]); + + return ( + + + + ); +} + +export default EditMetadataModal; diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalConnector.js b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalConnector.js deleted file mode 100644 index 7513bb82c9..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalConnector.js +++ /dev/null @@ -1,44 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearPendingChanges } from 'Store/Actions/baseActions'; -import EditMetadataModal from './EditMetadataModal'; - -function createMapDispatchToProps(dispatch, props) { - const section = 'settings.metadata'; - - return { - dispatchClearPendingChanges() { - dispatch(clearPendingChanges({ section })); - } - }; -} - -class EditMetadataModalConnector extends Component { - // - // Listeners - - onModalClose = () => { - this.props.dispatchClearPendingChanges({ section: 'metadata' }); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditMetadataModalConnector.propTypes = { - onModalClose: PropTypes.func.isRequired, - dispatchClearPendingChanges: PropTypes.func.isRequired -}; - -export default connect(null, createMapDispatchToProps)(EditMetadataModalConnector); diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css new file mode 100644 index 0000000000..7393b9c355 --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css @@ -0,0 +1,5 @@ +.message { + composes: alert from '~Components/Alert.css'; + + margin-bottom: 30px; +} diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css.d.ts b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css.d.ts new file mode 100644 index 0000000000..65c237dff7 --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.css.d.ts @@ -0,0 +1,7 @@ +// This file is automatically generated. +// Please do not change this file! +interface CssExports { + 'message': string; +} +export const cssExports: CssExports; +export default cssExports; diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.js b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.js deleted file mode 100644 index 221c6bcaf1..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.js +++ /dev/null @@ -1,105 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Form from 'Components/Form/Form'; -import FormGroup from 'Components/Form/FormGroup'; -import FormInputGroup from 'Components/Form/FormInputGroup'; -import FormLabel from 'Components/Form/FormLabel'; -import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup'; -import Button from 'Components/Link/Button'; -import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import { inputTypes } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; - -function EditMetadataModalContent(props) { - const { - advancedSettings, - isSaving, - saveError, - item, - onInputChange, - onFieldChange, - onModalClose, - onSavePress, - ...otherProps - } = props; - - const { - name, - enable, - fields - } = item; - - return ( - - - {translate('EditMetadata', { metadataType: name.value })} - - - - - - {translate('Enable')} - - - - - { - fields.map((field) => { - return ( - - ); - }) - } - - - - - - - - - {translate('Save')} - - - - ); -} - -EditMetadataModalContent.propTypes = { - advancedSettings: PropTypes.bool.isRequired, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - item: PropTypes.object.isRequired, - onInputChange: PropTypes.func.isRequired, - onFieldChange: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onDeleteMetadataPress: PropTypes.func -}; - -export default EditMetadataModalContent; diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx new file mode 100644 index 0000000000..997a4c39cc --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx @@ -0,0 +1,128 @@ +import React, { useCallback, useMemo } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import Alert from 'Components/Alert'; +import Form from 'Components/Form/Form'; +import FormGroup from 'Components/Form/FormGroup'; +import FormInputGroup from 'Components/Form/FormInputGroup'; +import FormLabel from 'Components/Form/FormLabel'; +import ProviderFieldFormGroup from 'Components/Form/ProviderFieldFormGroup'; +import Button from 'Components/Link/Button'; +import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import { inputTypes } from 'Helpers/Props'; +import { + saveMetadata, + setMetadataFieldValue, + setMetadataValue, +} from 'Store/Actions/settingsActions'; +import selectSettings from 'Store/Selectors/selectSettings'; +import { InputChanged } from 'typings/inputs'; +import translate from 'Utilities/String/translate'; +import styles from './EditMetadataModalContent.css'; + +export interface EditMetadataModalContentProps { + id: number; + advancedSettings: boolean; + onModalClose: () => void; +} + +function EditMetadataModalContent({ + id, + advancedSettings, + onModalClose, +}: EditMetadataModalContentProps) { + const dispatch = useDispatch(); + + const { isSaving, saveError, pendingChanges, items } = useSelector( + (state: AppState) => state.settings.metadata + ); + + const { settings, ...otherSettings } = useMemo(() => { + const item = items.find((item) => item.id === id)!; + + return selectSettings(item, pendingChanges, saveError); + }, [id, items, pendingChanges, saveError]); + + const { name, enable, fields, message } = settings; + + const handleInputChange = useCallback( + ({ name, value }: InputChanged) => { + // @ts-expect-error not typed + dispatch(setMetadataValue({ name, value })); + }, + [dispatch] + ); + + const handleFieldChange = useCallback( + ({ name, value }: InputChanged) => { + // @ts-expect-error not typed + dispatch(setMetadataFieldValue({ name, value })); + }, + [dispatch] + ); + + const handleSavePress = useCallback(() => { + dispatch(saveMetadata({ id })); + }, [id, dispatch]); + + return ( + + + {translate('EditMetadata', { metadataType: name.value })} + + + +
+ {message ? ( + + {message.value.message} + + ) : null} + + + {translate('Enable')} + + + + + {fields.map((field) => { + return ( + + ); + })} + +
+ + + + + + {translate('Save')} + + +
+ ); +} + +export default EditMetadataModalContent; diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContentConnector.js b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContentConnector.js deleted file mode 100644 index 62dae94f6c..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContentConnector.js +++ /dev/null @@ -1,95 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { saveMetadata, setMetadataFieldValue, setMetadataValue } from 'Store/Actions/settingsActions'; -import selectSettings from 'Store/Selectors/selectSettings'; -import EditMetadataModalContent from './EditMetadataModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.settings.advancedSettings, - (state, { id }) => id, - (state) => state.settings.metadata, - (advancedSettings, id, metadata) => { - const { - isSaving, - saveError, - pendingChanges, - items - } = metadata; - - const settings = selectSettings(_.find(items, { id }), pendingChanges, saveError); - - return { - advancedSettings, - id, - isSaving, - saveError, - item: settings.settings, - ...settings - }; - } - ); -} - -const mapDispatchToProps = { - setMetadataValue, - setMetadataFieldValue, - saveMetadata -}; - -class EditMetadataModalContentConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps, prevState) { - if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) { - this.props.onModalClose(); - } - } - - // - // Listeners - - onInputChange = ({ name, value }) => { - this.props.setMetadataValue({ name, value }); - }; - - onFieldChange = ({ name, value }) => { - this.props.setMetadataFieldValue({ name, value }); - }; - - onSavePress = () => { - this.props.saveMetadata({ id: this.props.id }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditMetadataModalContentConnector.propTypes = { - id: PropTypes.number, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - item: PropTypes.object.isRequired, - setMetadataValue: PropTypes.func.isRequired, - setMetadataFieldValue: PropTypes.func.isRequired, - saveMetadata: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(EditMetadataModalContentConnector); diff --git a/frontend/src/Settings/Metadata/Metadata/Metadata.js b/frontend/src/Settings/Metadata/Metadata/Metadata.js deleted file mode 100644 index ffb0ab967f..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/Metadata.js +++ /dev/null @@ -1,150 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Card from 'Components/Card'; -import Label from 'Components/Label'; -import { kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import EditMetadataModalConnector from './EditMetadataModalConnector'; -import styles from './Metadata.css'; - -class Metadata extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isEditMetadataModalOpen: false - }; - } - - // - // Listeners - - onEditMetadataPress = () => { - this.setState({ isEditMetadataModalOpen: true }); - }; - - onEditMetadataModalClose = () => { - this.setState({ isEditMetadataModalOpen: false }); - }; - - // - // Render - - render() { - const { - id, - name, - enable, - fields - } = this.props; - - const metadataFields = []; - const imageFields = []; - - fields.forEach((field) => { - if (field.section === 'metadata') { - metadataFields.push(field); - } else { - imageFields.push(field); - } - }); - - return ( - -
- {name} -
- -
- { - enable ? - : - - } -
- - { - enable && !!metadataFields.length && -
-
- {translate('Metadata')} -
- - { - metadataFields.map((field) => { - if (!field.value) { - return null; - } - - return ( - - ); - }) - } -
- } - - { - enable && !!imageFields.length && -
-
- {translate('Images')} -
- - { - imageFields.map((field) => { - if (!field.value) { - return null; - } - - return ( - - ); - }) - } -
- } - - -
- ); - } -} - -Metadata.propTypes = { - id: PropTypes.number.isRequired, - name: PropTypes.string.isRequired, - enable: PropTypes.bool.isRequired, - fields: PropTypes.arrayOf(PropTypes.object).isRequired -}; - -export default Metadata; diff --git a/frontend/src/Settings/Metadata/Metadata/Metadata.tsx b/frontend/src/Settings/Metadata/Metadata/Metadata.tsx new file mode 100644 index 0000000000..52797218df --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/Metadata.tsx @@ -0,0 +1,107 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import Card from 'Components/Card'; +import Label from 'Components/Label'; +import { kinds } from 'Helpers/Props'; +import Field from 'typings/Field'; +import translate from 'Utilities/String/translate'; +import EditMetadataModal from './EditMetadataModal'; +import styles from './Metadata.css'; + +interface MetadataProps { + id: number; + name: string; + enable: boolean; + fields: Field[]; +} + +function Metadata({ id, name, enable, fields }: MetadataProps) { + const [isEditMetadataModalOpen, setIsEditMetadataModalOpen] = useState(false); + + const { metadataFields, imageFields } = useMemo(() => { + return fields.reduce<{ metadataFields: Field[]; imageFields: Field[] }>( + (acc, field) => { + if (field.section === 'metadata') { + acc.metadataFields.push(field); + } else { + acc.imageFields.push(field); + } + + return acc; + }, + { metadataFields: [], imageFields: [] } + ); + }, [fields]); + + const handleOpenPress = useCallback(() => { + setIsEditMetadataModalOpen(true); + }, []); + + const handleModalClose = useCallback(() => { + setIsEditMetadataModalOpen(false); + }, []); + + return ( + +
{name}
+ +
+ {enable ? ( + + ) : ( + + )} +
+ + {enable && metadataFields.length ? ( +
+
{translate('Metadata')}
+ + {metadataFields.map((field) => { + if (!field.value) { + return null; + } + + return ( + + ); + })} +
+ ) : null} + + {enable && imageFields.length ? ( +
+
{translate('Images')}
+ + {imageFields.map((field) => { + if (!field.value) { + return null; + } + + return ( + + ); + })} +
+ ) : null} + + +
+ ); +} + +export default Metadata; diff --git a/frontend/src/Settings/Metadata/Metadata/Metadatas.js b/frontend/src/Settings/Metadata/Metadata/Metadatas.js deleted file mode 100644 index a52275bcc3..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/Metadatas.js +++ /dev/null @@ -1,44 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import FieldSet from 'Components/FieldSet'; -import PageSectionContent from 'Components/Page/PageSectionContent'; -import translate from 'Utilities/String/translate'; -import Metadata from './Metadata'; -import styles from './Metadatas.css'; - -function Metadatas(props) { - const { - items, - ...otherProps - } = props; - - return ( -
- -
- { - items.map((item) => { - return ( - - ); - }) - } -
-
-
- ); -} - -Metadatas.propTypes = { - isFetching: PropTypes.bool.isRequired, - error: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired -}; - -export default Metadatas; diff --git a/frontend/src/Settings/Metadata/Metadata/Metadatas.tsx b/frontend/src/Settings/Metadata/Metadata/Metadatas.tsx new file mode 100644 index 0000000000..befe207d82 --- /dev/null +++ b/frontend/src/Settings/Metadata/Metadata/Metadatas.tsx @@ -0,0 +1,52 @@ +import React, { useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import MetadataAppState from 'App/State/MetadataAppState'; +import FieldSet from 'Components/FieldSet'; +import PageSectionContent from 'Components/Page/PageSectionContent'; +import { fetchMetadata } from 'Store/Actions/settingsActions'; +import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; +import MetadataType from 'typings/Metadata'; +import sortByProp from 'Utilities/Array/sortByProp'; +import translate from 'Utilities/String/translate'; +import Metadata from './Metadata'; +import styles from './Metadatas.css'; + +function createMetadatasSelector() { + return createSelector( + createSortedSectionSelector( + 'settings.metadata', + sortByProp('name') + ), + (metadata: MetadataAppState) => metadata + ); +} + +function Metadatas() { + const dispatch = useDispatch(); + const { isFetching, error, items, ...otherProps } = useSelector( + createMetadatasSelector() + ); + + useEffect(() => { + dispatch(fetchMetadata()); + }, [dispatch]); + + return ( +
+ +
+ {items.map((item) => { + return ; + })} +
+
+
+ ); +} + +export default Metadatas; diff --git a/frontend/src/Settings/Metadata/Metadata/MetadatasConnector.js b/frontend/src/Settings/Metadata/Metadata/MetadatasConnector.js deleted file mode 100644 index 8675f4742d..0000000000 --- a/frontend/src/Settings/Metadata/Metadata/MetadatasConnector.js +++ /dev/null @@ -1,47 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchMetadata } from 'Store/Actions/settingsActions'; -import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector'; -import sortByProp from 'Utilities/Array/sortByProp'; -import Metadatas from './Metadatas'; - -function createMapStateToProps() { - return createSelector( - createSortedSectionSelector('settings.metadata', sortByProp('name')), - (metadata) => metadata - ); -} - -const mapDispatchToProps = { - fetchMetadata -}; - -class MetadatasConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.fetchMetadata(); - } - - // - // Render - - render() { - return ( - - ); - } -} - -MetadatasConnector.propTypes = { - fetchMetadata: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MetadatasConnector); diff --git a/frontend/src/Settings/Metadata/MetadataSettings.js b/frontend/src/Settings/Metadata/MetadataSettings.js index e0a256cb19..5c92f0ace9 100644 --- a/frontend/src/Settings/Metadata/MetadataSettings.js +++ b/frontend/src/Settings/Metadata/MetadataSettings.js @@ -3,7 +3,7 @@ import PageContent from 'Components/Page/PageContent'; import PageContentBody from 'Components/Page/PageContentBody'; import SettingsToolbarConnector from 'Settings/SettingsToolbarConnector'; import translate from 'Utilities/String/translate'; -import MetadatasConnector from './Metadata/MetadatasConnector'; +import Metadatas from './Metadata/Metadatas'; import MetadataOptionsConnector from './Options/MetadataOptionsConnector'; class MetadataSettings extends Component { @@ -62,7 +62,7 @@ class MetadataSettings extends Component { onChildStateChange={this.onChildStateChange} /> - + ); diff --git a/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx b/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx index 5b2b4289cc..ceb1d6a43d 100644 --- a/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx +++ b/frontend/src/Settings/Profiles/Release/EditReleaseProfileModalContent.tsx @@ -19,14 +19,15 @@ import { setReleaseProfileValue, } from 'Store/Actions/Settings/releaseProfiles'; import selectSettings from 'Store/Selectors/selectSettings'; -import { PendingSection } from 'typings/pending'; import ReleaseProfile from 'typings/Settings/ReleaseProfile'; import translate from 'Utilities/String/translate'; import styles from './EditReleaseProfileModalContent.css'; const tagInputDelimiters = ['Tab', 'Enter']; -const newReleaseProfile = { +const newReleaseProfile: ReleaseProfile = { + id: 0, + name: '', enabled: true, required: [], ignored: [], @@ -41,8 +42,12 @@ function createReleaseProfileSelector(id?: number) { const { items, isFetching, error, isSaving, saveError, pendingChanges } = releaseProfiles; - const mapping = id ? items.find((i) => i.id === id) : newReleaseProfile; - const settings = selectSettings(mapping, pendingChanges, saveError); + const mapping = id ? items.find((i) => i.id === id)! : newReleaseProfile; + const settings = selectSettings( + mapping, + pendingChanges, + saveError + ); return { id, @@ -50,7 +55,7 @@ function createReleaseProfileSelector(id?: number) { error, isSaving, saveError, - item: settings.settings as PendingSection, + item: settings.settings, ...settings, }; } diff --git a/frontend/src/Store/Selectors/selectSettings.js b/frontend/src/Store/Selectors/selectSettings.js deleted file mode 100644 index 3e30478b7b..0000000000 --- a/frontend/src/Store/Selectors/selectSettings.js +++ /dev/null @@ -1,104 +0,0 @@ -import _ from 'lodash'; - -function getValidationFailures(saveError) { - if (!saveError || saveError.status !== 400) { - return []; - } - - return _.cloneDeep(saveError.responseJSON); -} - -function mapFailure(failure) { - return { - message: failure.errorMessage, - link: failure.infoLink, - detailedMessage: failure.detailedDescription - }; -} - -function selectSettings(item, pendingChanges, saveError) { - const validationFailures = getValidationFailures(saveError); - - // Merge all settings from the item along with pending - // changes to ensure any settings that were not included - // with the item are included. - const allSettings = Object.assign({}, item, pendingChanges); - - const settings = _.reduce(allSettings, (result, value, key) => { - if (key === 'fields') { - return result; - } - - // Return a flattened value - if (key === 'implementationName') { - result.implementationName = item[key]; - - return result; - } - - const setting = { - value: item[key], - errors: _.map(_.remove(validationFailures, (failure) => { - return failure.propertyName.toLowerCase() === key.toLowerCase() && !failure.isWarning; - }), mapFailure), - - warnings: _.map(_.remove(validationFailures, (failure) => { - return failure.propertyName.toLowerCase() === key.toLowerCase() && failure.isWarning; - }), mapFailure) - }; - - if (pendingChanges.hasOwnProperty(key)) { - setting.previousValue = setting.value; - setting.value = pendingChanges[key]; - setting.pending = true; - } - - result[key] = setting; - return result; - }, {}); - - const fields = _.reduce(item.fields, (result, f) => { - const field = Object.assign({ pending: false }, f); - const hasPendingFieldChange = pendingChanges.fields && pendingChanges.fields.hasOwnProperty(field.name); - - if (hasPendingFieldChange) { - field.previousValue = field.value; - field.value = pendingChanges.fields[field.name]; - field.pending = true; - } - - field.errors = _.map(_.remove(validationFailures, (failure) => { - return failure.propertyName.toLowerCase() === field.name.toLowerCase() && !failure.isWarning; - }), mapFailure); - - field.warnings = _.map(_.remove(validationFailures, (failure) => { - return failure.propertyName.toLowerCase() === field.name.toLowerCase() && failure.isWarning; - }), mapFailure); - - result.push(field); - return result; - }, []); - - if (fields.length) { - settings.fields = fields; - } - - const validationErrors = _.filter(validationFailures, (failure) => { - return !failure.isWarning; - }); - - const validationWarnings = _.filter(validationFailures, (failure) => { - return failure.isWarning; - }); - - return { - settings, - validationErrors, - validationWarnings, - hasPendingChanges: !_.isEmpty(pendingChanges), - hasSettings: !_.isEmpty(settings), - pendingChanges - }; -} - -export default selectSettings; diff --git a/frontend/src/Store/Selectors/selectSettings.ts b/frontend/src/Store/Selectors/selectSettings.ts new file mode 100644 index 0000000000..75665d73b1 --- /dev/null +++ b/frontend/src/Store/Selectors/selectSettings.ts @@ -0,0 +1,168 @@ +import { cloneDeep, isEmpty } from 'lodash'; +import { Error } from 'App/State/AppSectionState'; +import Field from 'typings/Field'; +import { + Failure, + Pending, + PendingField, + PendingSection, + ValidationError, + ValidationFailure, + ValidationWarning, +} from 'typings/pending'; + +interface ValidationFailures { + errors: ValidationError[]; + warnings: ValidationWarning[]; +} + +function getValidationFailures(saveError?: Error): ValidationFailures { + if (!saveError || saveError.status !== 400) { + return { + errors: [], + warnings: [], + }; + } + + return cloneDeep(saveError.responseJSON as ValidationFailure[]).reduce( + (acc: ValidationFailures, failure: ValidationFailure) => { + if (failure.isWarning) { + acc.warnings.push(failure as ValidationWarning); + } else { + acc.errors.push(failure as ValidationError); + } + + return acc; + }, + { + errors: [], + warnings: [], + } + ); +} + +function getFailures(failures: ValidationFailure[], key: string) { + const result = []; + + for (let i = failures.length - 1; i >= 0; i--) { + if (failures[i].propertyName.toLowerCase() === key.toLowerCase()) { + result.unshift(mapFailure(failures[i])); + + failures.splice(i, 1); + } + } + + return result; +} + +function mapFailure(failure: ValidationFailure): Failure { + return { + errorMessage: failure.errorMessage, + infoLink: failure.infoLink, + detailedDescription: failure.detailedDescription, + + // TODO: Remove these renamed properties + message: failure.errorMessage, + link: failure.infoLink, + detailedMessage: failure.detailedDescription, + }; +} + +interface ModelBaseSetting { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + [id: string]: any; +} + +function selectSettings( + item: T, + pendingChanges: Partial, + saveError?: Error +) { + const { errors, warnings } = getValidationFailures(saveError); + + // Merge all settings from the item along with pending + // changes to ensure any settings that were not included + // with the item are included. + const allSettings = Object.assign({}, item, pendingChanges); + + const settings = Object.keys(allSettings).reduce( + (acc: PendingSection, key) => { + if (key === 'fields') { + return acc; + } + + // Return a flattened value + if (key === 'implementationName') { + acc.implementationName = item[key]; + + return acc; + } + + const setting: Pending = { + value: item[key], + pending: false, + errors: getFailures(errors, key), + warnings: getFailures(warnings, key), + }; + + if (pendingChanges.hasOwnProperty(key)) { + setting.previousValue = setting.value; + setting.value = pendingChanges[key]; + setting.pending = true; + } + + // @ts-expect-error - This is a valid key + acc[key] = setting; + return acc; + }, + {} as PendingSection + ); + + if ('fields' in item) { + const fields = + (item.fields as Field[]).reduce((acc: PendingField[], f) => { + const field: PendingField = Object.assign( + { pending: false, errors: [], warnings: [] }, + f + ); + + if ('fields' in pendingChanges) { + const pendingChangesFields = pendingChanges.fields as Record< + string, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + any + >; + + if (pendingChangesFields.hasOwnProperty(field.name)) { + field.previousValue = field.value; + field.value = pendingChangesFields[field.name]; + field.pending = true; + } + } + + field.errors = getFailures(errors, field.name); + field.warnings = getFailures(warnings, field.name); + + acc.push(field); + return acc; + }, []) ?? []; + + if (fields.length) { + settings.fields = fields; + } + } + + const validationErrors = errors; + const validationWarnings = warnings; + + return { + settings, + validationErrors, + validationWarnings, + hasPendingChanges: !isEmpty(pendingChanges), + hasSettings: !isEmpty(settings), + pendingChanges, + }; +} + +export default selectSettings; diff --git a/frontend/src/typings/DownloadClient.ts b/frontend/src/typings/DownloadClient.ts index 2c032c22a8..417d74b0b4 100644 --- a/frontend/src/typings/DownloadClient.ts +++ b/frontend/src/typings/DownloadClient.ts @@ -1,27 +1,13 @@ -import ModelBase from 'App/ModelBase'; +import Provider from './Provider'; -export interface Field { - order: number; - name: string; - label: string; - value: boolean | number | string; - type: string; - advanced: boolean; - privacy: string; -} +export type Protocol = 'torrent' | 'usenet' | 'unknown'; -interface DownloadClient extends ModelBase { +interface DownloadClient extends Provider { enable: boolean; - protocol: string; + protocol: Protocol; priority: number; removeCompletedDownloads: boolean; removeFailedDownloads: boolean; - name: string; - fields: Field[]; - implementationName: string; - implementation: string; - configContract: string; - infoLink: string; tags: number[]; } diff --git a/frontend/src/typings/Field.ts b/frontend/src/typings/Field.ts new file mode 100644 index 0000000000..404c436ef4 --- /dev/null +++ b/frontend/src/typings/Field.ts @@ -0,0 +1,23 @@ +export interface FieldSelectOption { + value: T; + name: string; + order: number; + hint?: string; + parentValue?: T; + isDisabled?: boolean; + additionalProperties?: Record; +} + +interface Field { + order: number; + name: string; + label: string; + value: boolean | number | string | number[]; + section: string; + hidden: 'hidden' | 'hiddenIfNotSet' | 'visible'; + type: string; + advanced: boolean; + privacy: string; +} + +export default Field; diff --git a/frontend/src/typings/ImportList.ts b/frontend/src/typings/ImportList.ts index 849b20be01..be7b72b3d3 100644 --- a/frontend/src/typings/ImportList.ts +++ b/frontend/src/typings/ImportList.ts @@ -1,28 +1,12 @@ -import ModelBase from 'App/ModelBase'; +import Provider from './Provider'; -export interface Field { - order: number; - name: string; - label: string; - value: boolean | number | string; - type: string; - advanced: boolean; - privacy: string; -} - -interface ImportList extends ModelBase { +interface ImportList extends Provider { enable: boolean; enabled: boolean; enableAuto: boolean; qualityProfileId: number; minimumAvailability: string; rootFolderPath: string; - name: string; - fields: Field[]; - implementationName: string; - implementation: string; - configContract: string; - infoLink: string; tags: number[]; } diff --git a/frontend/src/typings/Indexer.ts b/frontend/src/typings/Indexer.ts index e6c23eda2e..ea38651f45 100644 --- a/frontend/src/typings/Indexer.ts +++ b/frontend/src/typings/Indexer.ts @@ -1,27 +1,11 @@ -import ModelBase from 'App/ModelBase'; +import Provider from './Provider'; -export interface Field { - order: number; - name: string; - label: string; - value: boolean | number | string; - type: string; - advanced: boolean; - privacy: string; -} - -interface Indexer extends ModelBase { +interface Indexer extends Provider { enableRss: boolean; enableAutomaticSearch: boolean; enableInteractiveSearch: boolean; protocol: string; priority: number; - name: string; - fields: Field[]; - implementationName: string; - implementation: string; - configContract: string; - infoLink: string; tags: number[]; } diff --git a/frontend/src/typings/Metadata.ts b/frontend/src/typings/Metadata.ts new file mode 100644 index 0000000000..b7d0cfb710 --- /dev/null +++ b/frontend/src/typings/Metadata.ts @@ -0,0 +1,7 @@ +import Provider from './Provider'; + +interface Metadata extends Provider { + enable: boolean; +} + +export default Metadata; diff --git a/frontend/src/typings/Notification.ts b/frontend/src/typings/Notification.ts index e2b5ad7eb1..12057015b4 100644 --- a/frontend/src/typings/Notification.ts +++ b/frontend/src/typings/Notification.ts @@ -1,23 +1,7 @@ -import ModelBase from 'App/ModelBase'; +import Provider from './Provider'; -export interface Field { - order: number; - name: string; - label: string; - value: boolean | number | string; - type: string; - advanced: boolean; - privacy: string; -} - -interface Notification extends ModelBase { +interface Notification extends Provider { enable: boolean; - name: string; - fields: Field[]; - implementationName: string; - implementation: string; - configContract: string; - infoLink: string; tags: number[]; } diff --git a/frontend/src/typings/Provider.ts b/frontend/src/typings/Provider.ts new file mode 100644 index 0000000000..e9eabba0b6 --- /dev/null +++ b/frontend/src/typings/Provider.ts @@ -0,0 +1,20 @@ +import ModelBase from 'App/ModelBase'; +import { Kind } from 'Helpers/Props/kinds'; +import Field from './Field'; + +export interface ProviderMessage { + message: string; + type: Extract; +} + +interface Provider extends ModelBase { + name: string; + fields: Field[]; + implementationName: string; + implementation: string; + configContract: string; + infoLink: string; + message: ProviderMessage; +} + +export default Provider; diff --git a/frontend/src/typings/pending.ts b/frontend/src/typings/pending.ts index 5cdcbc003d..480c356235 100644 --- a/frontend/src/typings/pending.ts +++ b/frontend/src/typings/pending.ts @@ -1,6 +1,11 @@ +import Field from './Field'; + export interface ValidationFailure { + isWarning: boolean; propertyName: string; errorMessage: string; + infoLink?: string; + detailedDescription?: string; severity: 'error' | 'warning'; } @@ -12,12 +17,47 @@ export interface ValidationWarning extends ValidationFailure { isWarning: true; } -export interface Pending { - value: T; - errors: ValidationError[]; - warnings: ValidationWarning[]; +export interface Failure { + errorMessage: ValidationFailure['errorMessage']; + infoLink: ValidationFailure['infoLink']; + detailedDescription: ValidationFailure['detailedDescription']; + + // TODO: Remove these renamed properties + + message: ValidationFailure['errorMessage']; + link: ValidationFailure['infoLink']; + detailedMessage: ValidationFailure['detailedDescription']; } -export type PendingSection = { - [K in keyof T]: Pending; +export interface Pending { + value: T; + errors: Failure[]; + warnings: Failure[]; + pending: boolean; + previousValue?: T; +} + +export interface PendingField + extends Field, + Omit, 'previousValue' | 'value'> { + previousValue?: Field['value']; +} + +// export type PendingSection = { +// [K in keyof T]: Pending; +// }; + +type Mapped = { + [Prop in keyof T]: { + value: T[Prop]; + errors: Failure[]; + warnings: Failure[]; + pending?: boolean; + previousValue?: T[Prop]; + }; +}; + +export type PendingSection = Mapped & { + implementationName?: string; + fields?: PendingField[]; }; diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs index 5749d45292..32b3c969c8 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadata.cs @@ -1,13 +1,12 @@ -using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Text.RegularExpressions; using NzbDrone.Common.Extensions; using NzbDrone.Core.Extras.Metadata.Files; -using NzbDrone.Core.MediaCover; +using NzbDrone.Core.Localization; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; +using NzbDrone.Core.ThingiProvider; namespace NzbDrone.Core.Extras.Metadata.Consumers.Kometa { @@ -15,13 +14,15 @@ public class KometaMetadata : MetadataBase { private static readonly Regex MovieImagesRegex = new (@"^(?:poster|background)\.(?:png|jpe?g)$", RegexOptions.Compiled | RegexOptions.IgnoreCase); - private readonly IMapCoversToLocal _mediaCoverService; + private readonly ILocalizationService _localizationService; public override string Name => "Kometa"; - public KometaMetadata(IMapCoversToLocal mediaCoverService) + public override ProviderMessage Message => new (_localizationService.GetLocalizedString("MetadataKometaDeprecated"), ProviderMessageType.Warning); + + public KometaMetadata(ILocalizationService localizationService) { - _mediaCoverService = mediaCoverService; + _localizationService = localizationService; } public override MetadataFile FindMetadataFile(Movie movie, string path) @@ -56,31 +57,7 @@ public override MetadataFileResult MovieMetadata(Movie movie, MovieFile movieFil public override List MovieImages(Movie movie) { - if (!Settings.MovieImages) - { - return new List(); - } - - return ProcessMovieImages(movie).ToList(); - } - - private IEnumerable ProcessMovieImages(Movie movie) - { - foreach (var image in movie.MovieMetadata.Value.Images.Where(i => i.CoverType is MediaCoverTypes.Poster or MediaCoverTypes.Fanart)) - { - var source = _mediaCoverService.GetCoverPath(movie.Id, image.CoverType); - - var filename = image.CoverType switch - { - MediaCoverTypes.Poster => "poster", - MediaCoverTypes.Fanart => "background", - _ => throw new ArgumentOutOfRangeException($"{image.CoverType} is not supported") - }; - - var destination = filename + Path.GetExtension(source); - - yield return new ImageFileResult(destination, source); - } + return new List(); } } } diff --git a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs index 6eae8c23a7..2ca2ee4fa3 100644 --- a/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs +++ b/src/NzbDrone.Core/Extras/Metadata/Consumers/Kometa/KometaMetadataSettings.cs @@ -15,11 +15,11 @@ public class KometaMetadataSettings : IProviderConfig public KometaMetadataSettings() { - MovieImages = true; + Deprecated = true; } - [FieldDefinition(0, Label = "MetadataSettingsMovieImages", Type = FieldType.Checkbox, Section = MetadataSectionType.Image, HelpText = "poster.jpg, background.jpg")] - public bool MovieImages { get; set; } + [FieldDefinition(0, Label = "MetadataKometaDeprecatedSetting", Type = FieldType.Checkbox, Section = MetadataSectionType.Image, Hidden = HiddenType.Hidden)] + public bool Deprecated { get; set; } public NzbDroneValidationResult Validate() { diff --git a/src/NzbDrone.Core/HealthCheck/Checks/MetadataCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/MetadataCheck.cs new file mode 100644 index 0000000000..48fa924d9f --- /dev/null +++ b/src/NzbDrone.Core/HealthCheck/Checks/MetadataCheck.cs @@ -0,0 +1,34 @@ +using System.Linq; +using NzbDrone.Core.Extras.Metadata; +using NzbDrone.Core.Extras.Metadata.Consumers.Kometa; +using NzbDrone.Core.Localization; +using NzbDrone.Core.ThingiProvider.Events; + +namespace NzbDrone.Core.HealthCheck.Checks +{ + [CheckOn(typeof(ProviderUpdatedEvent))] + public class MetadataCheck : HealthCheckBase + { + private readonly IMetadataFactory _metadataFactory; + + public MetadataCheck(IMetadataFactory metadataFactory, ILocalizationService localizationService) + : base(localizationService) + { + _metadataFactory = metadataFactory; + } + + public override HealthCheck Check() + { + var enabled = _metadataFactory.Enabled(); + + if (enabled.Any(m => m.Definition.Implementation == nameof(KometaMetadata))) + { + return new HealthCheck(GetType(), + HealthCheckResult.Warning, + $"{_localizationService.GetLocalizedString("MetadataKometaDeprecated")}"); + } + + return new HealthCheck(GetType()); + } + } +} diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 6732f48284..7b6c81d77b 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -919,6 +919,8 @@ "Menu": "Menu", "Message": "Message", "Metadata": "Metadata", + "MetadataKometaDeprecated": "Kometa files will no longer be created, support will be removed completely in v6", + "MetadataKometaDeprecatedSetting": "Deprecated", "MetadataLoadError": "Unable to load Metadata", "MetadataSettings": "Metadata Settings", "MetadataSettingsMovieImages": "Movie Images", From 9a107cc8d7bdff79fb6903dffb8aa2ab2bbad3e5 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Mon, 2 Dec 2024 01:16:36 +0100 Subject: [PATCH 115/579] New: Add Languages to Webhook Notifications (cherry picked from commit e039dc45e267cf717e00c0a49ba637012f37e3d7) Closes #10733 --- src/NzbDrone.Core/Notifications/Webhook/WebhookMovie.cs | 3 +++ src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs | 4 ++++ src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs | 3 +++ 3 files changed, 10 insertions(+) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovie.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovie.cs index 5bf3625739..de7e9925f0 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovie.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovie.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using NzbDrone.Core.Languages; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.Movies; @@ -20,6 +21,7 @@ public class WebhookMovie public List Genres { get; set; } public List Images { get; set; } public List Tags { get; set; } + public Language OriginalLanguage { get; set; } public WebhookMovie() { @@ -38,6 +40,7 @@ public WebhookMovie(Movie movie, List tags) Genres = movie.MovieMetadata.Value.Genres; Images = movie.MovieMetadata.Value.Images.Select(i => new WebhookImage(i)).ToList(); Tags = tags; + OriginalLanguage = movie.MovieMetadata.Value.OriginalLanguage; } public WebhookMovie(Movie movie, MovieFile movieFile, List tags) diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs index eff79d1d00..ec34b43fde 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookMovieFile.cs @@ -1,4 +1,6 @@ using System; +using System.Collections.Generic; +using NzbDrone.Core.Languages; using NzbDrone.Core.MediaFiles; namespace NzbDrone.Core.Notifications.Webhook @@ -21,6 +23,7 @@ public WebhookMovieFile(MovieFile movieFile) IndexerFlags = movieFile.IndexerFlags.ToString(); Size = movieFile.Size; DateAdded = movieFile.DateAdded; + Languages = movieFile.Languages; if (movieFile.MediaInfo != null) { @@ -38,6 +41,7 @@ public WebhookMovieFile(MovieFile movieFile) public string IndexerFlags { get; set; } public long Size { get; set; } public DateTime DateAdded { get; set; } + public List Languages { get; set; } public WebhookMovieFileMediaInfo MediaInfo { get; set; } public string SourcePath { get; set; } public string RecycleBinPath { get; set; } diff --git a/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs index 74e4fc9b93..656899c9ba 100755 --- a/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs +++ b/src/NzbDrone.Core/Notifications/Webhook/WebhookRelease.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using NzbDrone.Core.Languages; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; @@ -22,6 +23,7 @@ public WebhookRelease(QualityModel quality, RemoteMovie remoteMovie) Size = remoteMovie.Release.Size; CustomFormats = remoteMovie.CustomFormats?.Select(x => x.Name).ToList(); CustomFormatScore = remoteMovie.CustomFormatScore; + Languages = remoteMovie.Languages; IndexerFlags = Enum.GetValues(typeof(IndexerFlags)).Cast().Where(r => (remoteMovie.Release.IndexerFlags & r) == r).Select(r => r.ToString()).ToList(); } @@ -33,6 +35,7 @@ public WebhookRelease(QualityModel quality, RemoteMovie remoteMovie) public long Size { get; set; } public int CustomFormatScore { get; set; } public List CustomFormats { get; set; } + public List Languages { get; set; } public List IndexerFlags { get; set; } } } From 0caa793df4f3c500ea2ed819bae65a98cea03803 Mon Sep 17 00:00:00 2001 From: soup Date: Mon, 2 Dec 2024 01:20:08 +0100 Subject: [PATCH 116/579] New: Add config file setting for CGNAT authentication bypass (cherry picked from commit 4c41a4f368046f73f82306bbd73bec992392938b) --- .../IPAddressExtensionsFixture.cs | 19 +++++++++++++++++++ .../Extensions/IpAddressExtensions.cs | 6 ++++++ src/NzbDrone.Common/Options/AuthOptions.cs | 1 + .../Configuration/ConfigFileProvider.cs | 3 +++ .../Configuration/ConfigService.cs | 6 ++++++ .../Config/HostConfigResource.cs | 1 + .../Authentication/UiAuthorizationHandler.cs | 9 ++++++--- 7 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Common.Test/ExtensionTests/IPAddressExtensionsFixture.cs b/src/NzbDrone.Common.Test/ExtensionTests/IPAddressExtensionsFixture.cs index ff5d7383e7..0f7ad3004a 100644 --- a/src/NzbDrone.Common.Test/ExtensionTests/IPAddressExtensionsFixture.cs +++ b/src/NzbDrone.Common.Test/ExtensionTests/IPAddressExtensionsFixture.cs @@ -21,9 +21,28 @@ public void should_return_true_for_local_ip_address(string ipAddress) [TestCase("1.2.3.4")] [TestCase("172.55.0.1")] [TestCase("192.55.0.1")] + [TestCase("100.64.0.1")] + [TestCase("100.127.255.254")] public void should_return_false_for_public_ip_address(string ipAddress) { IPAddress.Parse(ipAddress).IsLocalAddress().Should().BeFalse(); } + + [TestCase("100.64.0.1")] + [TestCase("100.127.255.254")] + [TestCase("100.100.100.100")] + public void should_return_true_for_cgnat_ip_address(string ipAddress) + { + IPAddress.Parse(ipAddress).IsCgnatIpAddress().Should().BeTrue(); + } + + [TestCase("1.2.3.4")] + [TestCase("192.168.5.1")] + [TestCase("100.63.255.255")] + [TestCase("100.128.0.0")] + public void should_return_false_for_non_cgnat_ip_address(string ipAddress) + { + IPAddress.Parse(ipAddress).IsCgnatIpAddress().Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs b/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs index b60d4271ab..cbc1f5f831 100644 --- a/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs +++ b/src/NzbDrone.Common/Extensions/IpAddressExtensions.cs @@ -52,5 +52,11 @@ private static bool IsLocalIPv4(byte[] ipv4Bytes) return isLinkLocal || isClassA || isClassC || isClassB; } + + public static bool IsCgnatIpAddress(this IPAddress ipAddress) + { + var bytes = ipAddress.GetAddressBytes(); + return bytes.Length == 4 && bytes[0] == 100 && bytes[1] >= 64 && bytes[1] <= 127; + } } } diff --git a/src/NzbDrone.Common/Options/AuthOptions.cs b/src/NzbDrone.Common/Options/AuthOptions.cs index 2b63308d3b..64330b68b7 100644 --- a/src/NzbDrone.Common/Options/AuthOptions.cs +++ b/src/NzbDrone.Common/Options/AuthOptions.cs @@ -6,4 +6,5 @@ public class AuthOptions public bool? Enabled { get; set; } public string Method { get; set; } public string Required { get; set; } + public bool? TrustCgnatIpAddresses { get; set; } } diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index b4dee1b549..bb64875d78 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -66,6 +66,7 @@ public interface IConfigFileProvider : IHandleAsync, string PostgresMainDb { get; } string PostgresLogDb { get; } string Theme { get; } + bool TrustCgnatIpAddresses { get; } } public class ConfigFileProvider : IConfigFileProvider @@ -461,5 +462,7 @@ public void Execute(ResetApiKeyCommand message) { SetValue("ApiKey", GenerateApiKey()); } + + public bool TrustCgnatIpAddresses => _authOptions.TrustCgnatIpAddresses ?? GetValueBoolean("TrustCgnatIpAddresses", false, persist: false); } } diff --git a/src/NzbDrone.Core/Configuration/ConfigService.cs b/src/NzbDrone.Core/Configuration/ConfigService.cs index bd4df8c3d6..361d997eb0 100644 --- a/src/NzbDrone.Core/Configuration/ConfigService.cs +++ b/src/NzbDrone.Core/Configuration/ConfigService.cs @@ -444,6 +444,12 @@ public bool CleanupMetadataImages public string ApplicationUrl => GetValue("ApplicationUrl", string.Empty); + public bool TrustCgnatIpAddresses + { + get { return GetValueBoolean("TrustCgnatIpAddresses", false); } + set { SetValue("TrustCgnatIpAddresses", value); } + } + private string GetValue(string key) { return GetValue(key, string.Empty); diff --git a/src/Radarr.Api.V3/Config/HostConfigResource.cs b/src/Radarr.Api.V3/Config/HostConfigResource.cs index afdeebb95c..523e541a9c 100644 --- a/src/Radarr.Api.V3/Config/HostConfigResource.cs +++ b/src/Radarr.Api.V3/Config/HostConfigResource.cs @@ -45,6 +45,7 @@ public class HostConfigResource : RestResource public string BackupFolder { get; set; } public int BackupInterval { get; set; } public int BackupRetention { get; set; } + public bool TrustCgnatIpAddresses { get; set; } } public static class HostConfigResourceMapper diff --git a/src/Radarr.Http/Authentication/UiAuthorizationHandler.cs b/src/Radarr.Http/Authentication/UiAuthorizationHandler.cs index fa77127ab2..8924942016 100644 --- a/src/Radarr.Http/Authentication/UiAuthorizationHandler.cs +++ b/src/Radarr.Http/Authentication/UiAuthorizationHandler.cs @@ -27,10 +27,13 @@ protected override Task HandleRequirementAsync(AuthorizationHandlerContext conte if (_authenticationRequired == AuthenticationRequiredType.DisabledForLocalAddresses) { if (context.Resource is HttpContext httpContext && - IPAddress.TryParse(httpContext.GetRemoteIP(), out var ipAddress) && - ipAddress.IsLocalAddress()) + IPAddress.TryParse(httpContext.GetRemoteIP(), out var ipAddress)) { - context.Succeed(requirement); + if (ipAddress.IsLocalAddress() || + (_configService.TrustCgnatIpAddresses && ipAddress.IsCgnatIpAddress())) + { + context.Succeed(requirement); + } } } From 45aabce107c2f70d8040940253636fc1dbf99307 Mon Sep 17 00:00:00 2001 From: Servarr Date: Wed, 4 Dec 2024 11:37:34 +0000 Subject: [PATCH 117/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 4c29ccb060..fab0fcfd8f 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -9583,6 +9583,9 @@ "backupRetention": { "type": "integer", "format": "int32" + }, + "trustCgnatIpAddresses": { + "type": "boolean" } }, "additionalProperties": false From 6c85f166ffc8eb037eef58bdd1582358692d281b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 8 Dec 2024 11:22:50 +0200 Subject: [PATCH 118/579] Bump version to 5.16.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 8e988be842..874767e5e3 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.16.1' + majorVersion: '5.16.2' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 7ebd341cd6dfd8dc29be5b1e05e524ab7c55e61a Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 7 Dec 2024 20:45:39 -0800 Subject: [PATCH 119/579] Sync TimeSpanConverter with upstream (cherry picked from commit 1374240321f08d1400faf95e84217e4b7a2d116b) Closes #10756 --- .../Converters/TimeSpanConverterFixture.cs | 43 +++++++++++++++++++ .../Datastore/Converters/TimeSpanConverter.cs | 23 +++++----- src/NzbDrone.Core/Datastore/TableMapping.cs | 4 +- 3 files changed, 57 insertions(+), 13 deletions(-) create mode 100644 src/NzbDrone.Core.Test/Datastore/Converters/TimeSpanConverterFixture.cs diff --git a/src/NzbDrone.Core.Test/Datastore/Converters/TimeSpanConverterFixture.cs b/src/NzbDrone.Core.Test/Datastore/Converters/TimeSpanConverterFixture.cs new file mode 100644 index 0000000000..79d0adaee3 --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/Converters/TimeSpanConverterFixture.cs @@ -0,0 +1,43 @@ +using System; +using System.Data.SQLite; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Core.Datastore.Converters; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Datastore.Converters; + +[TestFixture] +public class TimeSpanConverterFixture : CoreTest +{ + private SQLiteParameter _param; + + [SetUp] + public void Setup() + { + _param = new SQLiteParameter(); + } + + [Test] + public void should_return_string_when_saving_timespan_to_db() + { + var span = TimeSpan.FromMilliseconds(10); + + Subject.SetValue(_param, span); + _param.Value.Should().Be(span.ToString()); + } + + [Test] + public void should_return_timespan_when_getting_string_from_db() + { + var span = TimeSpan.FromMilliseconds(10); + + Subject.Parse(span.ToString()).Should().Be(span); + } + + [Test] + public void should_return_zero_timespan_for_db_null_value_when_getting_from_db() + { + Subject.Parse(null).Should().Be(TimeSpan.Zero); + } +} diff --git a/src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs b/src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs index 902a26009b..fdcb227c6e 100644 --- a/src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs +++ b/src/NzbDrone.Core/Datastore/Converters/TimeSpanConverter.cs @@ -2,18 +2,17 @@ using System.Data; using Dapper; -namespace NzbDrone.Core.Datastore.Converters -{ - public class DapperTimeSpanConverter : SqlMapper.TypeHandler - { - public override void SetValue(IDbDataParameter parameter, TimeSpan value) - { - parameter.Value = value.ToString(); - } +namespace NzbDrone.Core.Datastore.Converters; - public override TimeSpan Parse(object value) - { - return TimeSpan.Parse((string)value); - } +public class TimeSpanConverter : SqlMapper.TypeHandler +{ + public override void SetValue(IDbDataParameter parameter, TimeSpan value) + { + parameter.Value = value.ToString(); + } + + public override TimeSpan Parse(object value) + { + return value is string str ? TimeSpan.Parse(str) : TimeSpan.Zero; } } diff --git a/src/NzbDrone.Core/Datastore/TableMapping.cs b/src/NzbDrone.Core/Datastore/TableMapping.cs index 4f179691bf..b0412ce210 100644 --- a/src/NzbDrone.Core/Datastore/TableMapping.cs +++ b/src/NzbDrone.Core/Datastore/TableMapping.cs @@ -188,7 +188,6 @@ private static void RegisterMappers() SqlMapper.RemoveTypeMap(typeof(DateTime)); SqlMapper.AddTypeHandler(new DapperUtcConverter()); - SqlMapper.AddTypeHandler(new DapperTimeSpanConverter()); SqlMapper.AddTypeHandler(new DapperQualityIntConverter()); SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter>(new QualityIntConverter())); SqlMapper.AddTypeHandler(new EmbeddedDocumentConverter>(new CustomFormatIntConverter())); @@ -213,6 +212,9 @@ private static void RegisterMappers() SqlMapper.RemoveTypeMap(typeof(Guid)); SqlMapper.RemoveTypeMap(typeof(Guid?)); SqlMapper.AddTypeHandler(new GuidConverter()); + SqlMapper.RemoveTypeMap(typeof(TimeSpan)); + SqlMapper.RemoveTypeMap(typeof(TimeSpan?)); + SqlMapper.AddTypeHandler(new TimeSpanConverter()); SqlMapper.AddTypeHandler(new CommandConverter()); SqlMapper.AddTypeHandler(new SystemVersionConverter()); } From 8b0b7c1cb0bc496a416236dd935a67e78f7d65e7 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Mon, 9 Dec 2024 04:36:10 +0100 Subject: [PATCH 120/579] New: Reactive search button on Wanted pages (cherry picked from commit e8c3aa20bd92701a16dcd97c5e103b79b3683105) Closes #10750 --- .../src/Wanted/CutoffUnmet/CutoffUnmet.js | 21 ++++++------------- .../CutoffUnmet/CutoffUnmetConnector.js | 5 +++-- frontend/src/Wanted/Missing/Missing.js | 19 ++++++----------- .../src/Wanted/Missing/MissingConnector.js | 5 +++-- 4 files changed, 18 insertions(+), 32 deletions(-) diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmet.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmet.js index 41bbb9a9e5..be913d7bc6 100644 --- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmet.js +++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmet.js @@ -153,12 +153,15 @@ class CutoffUnmet extends Component { + + - - - - - - diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js index ef3af7bf1c..410b1a9339 100644 --- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js +++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetConnector.js @@ -18,9 +18,10 @@ function createMapStateToProps() { return createSelector( (state) => state.wanted.cutoffUnmet, createCommandExecutingSelector(commandNames.CUTOFF_UNMET_MOVIES_SEARCH), - (cutoffUnmet, isSearchingForCutoffUnmetMovies) => { + createCommandExecutingSelector(commandNames.MOVIE_SEARCH), + (cutoffUnmet, isSearchingForCutoffUnmetMovies, isSearchingForSelectedCutoffUnmetMovies) => { return { - isSearchingForCutoffUnmetMovies, + isSearchingForCutoffUnmetMovies: isSearchingForCutoffUnmetMovies || isSearchingForSelectedCutoffUnmetMovies, isSaving: cutoffUnmet.items.filter((m) => m.isSaving).length > 1, ...cutoffUnmet }; diff --git a/frontend/src/Wanted/Missing/Missing.js b/frontend/src/Wanted/Missing/Missing.js index d88a120289..da243fb047 100644 --- a/frontend/src/Wanted/Missing/Missing.js +++ b/frontend/src/Wanted/Missing/Missing.js @@ -159,12 +159,15 @@ class Missing extends Component { + + - - - - state.wanted.missing, createCommandExecutingSelector(commandNames.MISSING_MOVIES_SEARCH), - (missing, isSearchingForMissingMovies) => { + createCommandExecutingSelector(commandNames.MOVIE_SEARCH), + (missing, isSearchingForMissingMovies, isSearchingForSelectedMissingMovies) => { return { - isSearchingForMissingMovies, + isSearchingForMissingMovies: isSearchingForMissingMovies || isSearchingForSelectedMissingMovies, isSaving: missing.items.filter((m) => m.isSaving).length > 1, ...missing }; From 7b9562bb38b7f642d4a5252e2a8bba1a2543c624 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 23 Nov 2024 20:20:36 -0800 Subject: [PATCH 121/579] Update React (cherry picked from commit 4491df3ae7530f2167beebc3548dd01fd2cc1a12) Towards #10703 --- frontend/src/bootstrap.tsx | 9 ++++---- frontend/src/index.ts | 25 +++++++++++++++++++++ package.json | 8 +++---- yarn.lock | 45 ++++++++++++++++++-------------------- 4 files changed, 54 insertions(+), 33 deletions(-) diff --git a/frontend/src/bootstrap.tsx b/frontend/src/bootstrap.tsx index 6a6d7fc670..9ecf27e0eb 100644 --- a/frontend/src/bootstrap.tsx +++ b/frontend/src/bootstrap.tsx @@ -1,6 +1,6 @@ import { createBrowserHistory } from 'history'; import React from 'react'; -import { render } from 'react-dom'; +import { createRoot } from 'react-dom/client'; import createAppStore from 'Store/createAppStore'; import App from './App/App'; @@ -9,9 +9,8 @@ import 'Diag/ConsoleApi'; export async function bootstrap() { const history = createBrowserHistory(); const store = createAppStore(history); + const container = document.getElementById('root'); - render( - , - document.getElementById('root') - ); + const root = createRoot(container!); // createRoot(container!) if you use TypeScript + root.render(); } diff --git a/frontend/src/index.ts b/frontend/src/index.ts index d2e70ad3c2..b9cb9ad848 100644 --- a/frontend/src/index.ts +++ b/frontend/src/index.ts @@ -14,6 +14,31 @@ window.Radarr = await response.json(); __webpack_public_path__ = `${window.Radarr.urlBase}/`; /* eslint-enable no-undef, @typescript-eslint/ban-ts-comment */ +const error = console.error; + +// Monkey patch console.error to filter out some warnings from React +// TODO: Remove this after the great TypeScript migration + +// eslint-disable-next-line @typescript-eslint/no-explicit-any +function logError(...parameters: any[]) { + const filter = parameters.find((parameter) => { + return ( + parameter.includes( + 'Support for defaultProps will be removed from function components in a future major release' + ) || + parameter.includes( + 'findDOMNode is deprecated and will be removed in the next major release' + ) + ); + }); + + if (!filter) { + error(...parameters); + } +} + +console.error = logError; + const { bootstrap } = await import('./bootstrap'); await bootstrap(); diff --git a/package.json b/package.json index 3003d67653..444ba323d8 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ "@sentry/browser": "7.119.1", "@sentry/integrations": "7.119.1", "@types/node": "20.16.11", - "@types/react": "18.2.79", - "@types/react-dom": "18.2.25", + "@types/react": "18.3.12", + "@types/react-dom": "18.3.1", "classnames": "2.5.1", "connected-react-router": "6.9.3", "copy-to-clipboard": "3.3.3", @@ -51,7 +51,7 @@ "normalize.css": "8.0.1", "prop-types": "15.8.1", "qs": "6.13.0", - "react": "17.0.2", + "react": "18.3.1", "react-addons-shallow-compare": "15.6.3", "react-async-script": "1.2.0", "react-autosuggest": "10.1.0", @@ -61,7 +61,7 @@ "react-dnd-multi-backend": "6.0.2", "react-dnd-touch-backend": "14.1.1", "react-document-title": "2.0.3", - "react-dom": "17.0.2", + "react-dom": "18.3.1", "react-focus-lock": "2.9.4", "react-google-recaptcha": "2.1.0", "react-lazyload": "3.2.0", diff --git a/yarn.lock b/yarn.lock index d99e3dc9a5..0dcc691d63 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1330,10 +1330,10 @@ dependencies: "@types/react" "*" -"@types/react-dom@18.2.25": - version "18.2.25" - resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.2.25.tgz#2946a30081f53e7c8d585eb138277245caedc521" - integrity sha512-o/V48vf4MQh7juIKZU2QGDfli6p1+OOi5oXx36Hffpc9adsHeXjVp8rHuPkjd8VT8sOJ2Zp05HR7CdpGTIUFUA== +"@types/react-dom@18.3.1": + version "18.3.1" + resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.3.1.tgz#1e4654c08a9cdcfb6594c780ac59b55aad42fe07" + integrity sha512-qW1Mfv8taImTthu4KoXgDfLuk4bydU6Q/TkADnDWWHwi4NX4BR+LWfTp2sVmTqRrsHvyDDTelgelxJ+SsejKKQ== dependencies: "@types/react" "*" @@ -1393,10 +1393,10 @@ "@types/prop-types" "*" csstype "^3.0.2" -"@types/react@18.2.79": - version "18.2.79" - resolved "https://registry.yarnpkg.com/@types/react/-/react-18.2.79.tgz#c40efb4f255711f554d47b449f796d1c7756d865" - integrity sha512-RwGAGXPl9kSXwdNTafkOEuFrTBD5SA2B3iEB96xi8+xu5ddUa/cpvyVCSNn+asgLCTHkb5ZxN8gbuibYJi4s1w== +"@types/react@18.3.12": + version "18.3.12" + resolved "https://registry.yarnpkg.com/@types/react/-/react-18.3.12.tgz#99419f182ccd69151813b7ee24b792fe08774f60" + integrity sha512-D2wOSq/d6Agt28q7rSI3jhU7G6aiuzljDGZ2hTZHIkrTLUI+AF3WMeKkEZ9nN2fkBAlcktT6vcZjDFiIhMYEQw== dependencies: "@types/prop-types" "*" csstype "^3.0.2" @@ -5417,14 +5417,13 @@ react-document-title@2.0.3: prop-types "^15.5.6" react-side-effect "^1.0.2" -react-dom@17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-17.0.2.tgz#ecffb6845e3ad8dbfcdc498f0d0a939736502c23" - integrity sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA== +react-dom@18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.3.1.tgz#c2265d79511b57d479b3dd3fdfa51536494c5cb4" + integrity sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" - scheduler "^0.20.2" + scheduler "^0.23.2" react-focus-lock@2.9.4: version "2.9.4" @@ -5586,13 +5585,12 @@ react-window@1.8.10: "@babel/runtime" "^7.0.0" memoize-one ">=3.1.1 <6" -react@17.0.2: - version "17.0.2" - resolved "https://registry.yarnpkg.com/react/-/react-17.0.2.tgz#d0b5cc516d29eb3eee383f75b62864cfb6800037" - integrity sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA== +react@18.3.1: + version "18.3.1" + resolved "https://registry.yarnpkg.com/react/-/react-18.3.1.tgz#49ab892009c53933625bd16b2533fc754cab2891" + integrity sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" read-pkg-up@^7.0.1: version "7.0.1" @@ -5959,13 +5957,12 @@ sax@~1.2.4: resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== -scheduler@^0.20.2: - version "0.20.2" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.20.2.tgz#4baee39436e34aa93b4874bddcbf0fe8b8b50e91" - integrity sha512-2eWfGgAqqWFGqtdMmcL5zCMK1U8KlXv8SQFGglL3CEtd0aDVDWgeF/YoCmvln55m5zSk3J/20hTaSBeSObsQDQ== +scheduler@^0.23.2: + version "0.23.2" + resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.2.tgz#414ba64a3b282892e944cf2108ecc078d115cdc3" + integrity sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ== dependencies: loose-envify "^1.1.0" - object-assign "^4.1.1" schema-utils@>1.0.0, schema-utils@^4.0.0: version "4.2.0" From 6c47ede76b7203188f8dc34bcecb9a18102c2aba Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 12 Dec 2024 21:58:54 +0200 Subject: [PATCH 122/579] Fixed: Refreshing movie genres --- src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs | 1 - src/NzbDrone.Core/Movies/RefreshMovieService.cs | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs index 23adbfe6a8..88a2da9c29 100644 --- a/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs +++ b/src/NzbDrone.Core/MetadataSource/SkyHook/SkyHookProxy.cs @@ -275,7 +275,6 @@ public MovieMetadata MapMovie(MovieResource resource) movie.Genres = resource.Genres; movie.Images = resource.Images.Select(MapImage).ToList(); - // movie.Genres = resource.Genres; movie.Recommendations = resource.Recommendations?.Select(r => r.TmdbId).ToList() ?? new List(); // Workaround due to metadata change until cache cleans up diff --git a/src/NzbDrone.Core/Movies/RefreshMovieService.cs b/src/NzbDrone.Core/Movies/RefreshMovieService.cs index f3630c0a39..5db3ae0080 100644 --- a/src/NzbDrone.Core/Movies/RefreshMovieService.cs +++ b/src/NzbDrone.Core/Movies/RefreshMovieService.cs @@ -117,8 +117,7 @@ private Movie RefreshMovieInfo(int movieId) movieMetadata.LastInfoSync = DateTime.UtcNow; movieMetadata.Runtime = movieInfo.Runtime; movieMetadata.Ratings = movieInfo.Ratings; - - // movie.Genres = movieInfo.Genres; + movieMetadata.Genres = movieInfo.Genres; movieMetadata.Certification = movieInfo.Certification; movieMetadata.InCinemas = movieInfo.InCinemas; movieMetadata.Website = movieInfo.Website; From 27dd8e8cd5af6c13800d5e9c6acb43298df1ca2f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 12 Dec 2024 21:59:19 +0200 Subject: [PATCH 123/579] New: Tooltip with extra genres on movie details page --- frontend/src/Movie/Details/MovieDetails.js | 5 ++- frontend/src/Movie/Details/MovieGenres.tsx | 39 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 frontend/src/Movie/Details/MovieGenres.tsx diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 8aadf60fd3..ecae574dd4 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -42,6 +42,7 @@ import translate from 'Utilities/String/translate'; import MovieCastPosters from './Credits/Cast/MovieCastPosters'; import MovieCrewPosters from './Credits/Crew/MovieCrewPosters'; import MovieDetailsLinks from './MovieDetailsLinks'; +import MovieGenres from './MovieGenres'; import MovieReleaseDates from './MovieReleaseDates'; import MovieStatusLabel from './MovieStatusLabel'; import MovieTagsConnector from './MovieTagsConnector'; @@ -651,9 +652,7 @@ class MovieDetails extends Component { name={translate('Genres')} size={sizes.LARGE} > - - {genres.join(', ')} - + : null } diff --git a/frontend/src/Movie/Details/MovieGenres.tsx b/frontend/src/Movie/Details/MovieGenres.tsx new file mode 100644 index 0000000000..77dc0c3cf3 --- /dev/null +++ b/frontend/src/Movie/Details/MovieGenres.tsx @@ -0,0 +1,39 @@ +import React from 'react'; +import Label from 'Components/Label'; +import Tooltip from 'Components/Tooltip/Tooltip'; +import { kinds, sizes, tooltipPositions } from 'Helpers/Props'; + +interface MovieGenresProps { + className?: string; + genres: string[]; +} + +function MovieGenres({ className, genres }: MovieGenresProps) { + const firstGenres = genres.slice(0, 3); + const otherGenres = genres.slice(3); + + if (otherGenres.length) { + return ( + {firstGenres.join(', ')}} + tooltip={ +
+ {otherGenres.map((tag) => { + return ( + + ); + })} +
+ } + kind={kinds.INVERSE} + position={tooltipPositions.TOP} + /> + ); + } + + return {firstGenres.join(', ')}; +} + +export default MovieGenres; From 62722d45b0b7b9c358407481155da44ede0df6c1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 13 Dec 2024 19:13:55 +0200 Subject: [PATCH 124/579] Fixed: Using all movie genres for collection filters --- .../src/Store/Actions/movieCollectionActions.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/frontend/src/Store/Actions/movieCollectionActions.js b/frontend/src/Store/Actions/movieCollectionActions.js index c335a936df..be9be6ad5c 100644 --- a/frontend/src/Store/Actions/movieCollectionActions.js +++ b/frontend/src/Store/Actions/movieCollectionActions.js @@ -91,12 +91,8 @@ export const defaultState = { genres: function(item, filterValue, type) { const predicate = filterTypePredicates[type]; - let allGenres = []; - item.movies.forEach((movie) => { - allGenres = allGenres.concat(movie.genres); - }); - - const genres = Array.from(new Set(allGenres)).slice(0, 3); + const allGenres = item.movies.flatMap(({ genres }) => genres); + const genres = Array.from(new Set(allGenres)); return predicate(genres, filterValue); }, @@ -138,12 +134,8 @@ export const defaultState = { type: filterBuilderTypes.ARRAY, optionsSelector: function(items) { const genreList = items.reduce((acc, collection) => { - let collectionGenres = []; - collection.movies.forEach((movie) => { - collectionGenres = collectionGenres.concat(movie.genres); - }); - - const genres = Array.from(new Set(collectionGenres)).slice(0, 3); + const collectionGenres = collection.movies.flatMap(({ genres }) => genres); + const genres = Array.from(new Set(collectionGenres)); genres.forEach((genre) => { acc.push({ From 9780d20f8aedbe45c225c44ee9262327fbad5e3e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 13 Dec 2024 19:14:41 +0200 Subject: [PATCH 125/579] Improve is visible property check for discover movies --- .../src/DiscoverMovie/Overview/DiscoverMovieOverviewInfo.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverviewInfo.js b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverviewInfo.js index ccf653f188..0117cf94ef 100644 --- a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverviewInfo.js +++ b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverviewInfo.js @@ -49,7 +49,7 @@ function isVisible(row, props) { valueProp } = row; - return _.has(props, valueProp) && (_.get(props, showProp) || props.sortKey === name); + return _.has(props, valueProp) && _.get(props, valueProp) !== null && (props[showProp] || props.sortKey === name); } function getInfoRowProps(row, props) { From bea943adf8ee3544b8d82dce56dd596f3f37d48d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 13 Dec 2024 19:16:44 +0200 Subject: [PATCH 126/579] New: Tooltip with extra genres on search and collections --- .../src/AddMovie/AddNewMovie/AddNewMovieSearchResult.css | 4 ++++ .../src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js | 7 +++---- frontend/src/Collection/CollectionItemConnector.js | 2 +- frontend/src/Collection/Overview/CollectionOverview.js | 7 +++---- frontend/src/Movie/Details/MovieDetails.js | 2 +- frontend/src/Movie/{Details => }/MovieGenres.tsx | 0 6 files changed, 12 insertions(+), 10 deletions(-) rename frontend/src/Movie/{Details => }/MovieGenres.tsx (100%) diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.css b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.css index 63edbd4471..7884dfd54e 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.css +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.css @@ -91,6 +91,10 @@ margin-left: 5px; } +.genres { + pointer-events: all; +} + .links { margin-left: 5px; pointer-events: all; diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js index a17a9b9f62..5a97ad0eb9 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js @@ -10,6 +10,7 @@ import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks'; import MovieStatusLabel from 'Movie/Details/MovieStatusLabel'; import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar'; +import MovieGenres from 'Movie/MovieGenres'; import MoviePoster from 'Movie/MoviePoster'; import formatRuntime from 'Utilities/Date/formatRuntime'; import translate from 'Utilities/String/translate'; @@ -249,9 +250,7 @@ class AddNewMovieSearchResult extends Component { name={icons.GENRE} size={13} /> - - {genres.slice(0, 3).join(', ')} - + : null } @@ -280,7 +279,7 @@ class AddNewMovieSearchResult extends Component { } canFlip={true} kind={kinds.INVERSE} - position={tooltipPositions.BOTTOM} + position={tooltipPositions.TOP} /> { diff --git a/frontend/src/Collection/CollectionItemConnector.js b/frontend/src/Collection/CollectionItemConnector.js index 64c8ca40a6..715982a9df 100644 --- a/frontend/src/Collection/CollectionItemConnector.js +++ b/frontend/src/Collection/CollectionItemConnector.js @@ -22,7 +22,7 @@ function createMapStateToProps() { return { ...collection, movies: [...collection.movies].sort((a, b) => b.year - a.year), - genres: Array.from(new Set(allGenres)).slice(0, 3) + genres: Array.from(new Set(allGenres)) }; } ); diff --git a/frontend/src/Collection/Overview/CollectionOverview.js b/frontend/src/Collection/Overview/CollectionOverview.js index cdba580801..18b1f7004c 100644 --- a/frontend/src/Collection/Overview/CollectionOverview.js +++ b/frontend/src/Collection/Overview/CollectionOverview.js @@ -10,6 +10,7 @@ import Label from 'Components/Label'; import IconButton from 'Components/Link/IconButton'; import MonitorToggleButton from 'Components/MonitorToggleButton'; import { icons, sizes } from 'Helpers/Props'; +import MovieGenres from 'Movie/MovieGenres'; import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; import dimensions from 'Styles/Variables/dimensions'; import fonts from 'Styles/Variables/fonts'; @@ -242,12 +243,10 @@ class CollectionOverview extends Component { size={sizes.MEDIUM} > - - {genres.join(', ')} - + } diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index ecae574dd4..4ba7dda043 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -28,6 +28,7 @@ import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; import getMovieStatusDetails from 'Movie/getMovieStatusDetails'; import MovieHistoryModal from 'Movie/History/MovieHistoryModal'; import MovieCollectionLabelConnector from 'Movie/MovieCollectionLabelConnector'; +import MovieGenres from 'Movie/MovieGenres'; import MoviePoster from 'Movie/MoviePoster'; import MovieInteractiveSearchModal from 'Movie/Search/MovieInteractiveSearchModal'; import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable'; @@ -42,7 +43,6 @@ import translate from 'Utilities/String/translate'; import MovieCastPosters from './Credits/Cast/MovieCastPosters'; import MovieCrewPosters from './Credits/Crew/MovieCrewPosters'; import MovieDetailsLinks from './MovieDetailsLinks'; -import MovieGenres from './MovieGenres'; import MovieReleaseDates from './MovieReleaseDates'; import MovieStatusLabel from './MovieStatusLabel'; import MovieTagsConnector from './MovieTagsConnector'; diff --git a/frontend/src/Movie/Details/MovieGenres.tsx b/frontend/src/Movie/MovieGenres.tsx similarity index 100% rename from frontend/src/Movie/Details/MovieGenres.tsx rename to frontend/src/Movie/MovieGenres.tsx From e016410c1014892d726b600042bd13ea49c027d6 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 13 Dec 2024 08:21:39 +0000 Subject: [PATCH 127/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Fixer Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Rodion Co-authored-by: Tomer Horowitz Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: farebyting Co-authored-by: fordas Co-authored-by: hhjuhl Co-authored-by: kaisernet Co-authored-by: keysuck Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/da.json | 153 +++++------ src/NzbDrone.Core/Localization/Core/de.json | 3 +- src/NzbDrone.Core/Localization/Core/es.json | 5 +- src/NzbDrone.Core/Localization/Core/he.json | 9 +- src/NzbDrone.Core/Localization/Core/id.json | 6 +- src/NzbDrone.Core/Localization/Core/ko.json | 54 ++-- .../Localization/Core/pt_BR.json | 4 +- src/NzbDrone.Core/Localization/Core/tr.json | 255 +++++++++--------- src/NzbDrone.Core/Localization/Core/uk.json | 7 +- .../Localization/Core/zh_CN.json | 3 +- 10 files changed, 267 insertions(+), 232 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index e5269bd7bc..4f095dd3c2 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -16,7 +16,7 @@ "InCinemas": "I Biografen", "ImportTipsMessage": "Nogle tips for at sikre importeringen går glat:", "ImportMechanismHealthCheckMessage": "Aktiver Fuldendt Download Håndtering", - "ImportHeader": "Importer film du allerede har", + "ImportHeader": "Importer et allerede organiseret filmbibliotek for at føje film til {appName}", "ImportExistingMovies": "Importer Eksisterende Film", "Imported": "Importeret", "Import": "Importer", @@ -49,7 +49,7 @@ "DownloadClientStatusCheckAllClientMessage": "Alle download klienter er utilgængelige på grund af fejl", "DownloadClientsSettingsSummary": "Download klienter, download håndtering og remote path mappings", "DownloadClients": "Download Klienter", - "DownloadClientCheckUnableToCommunicateMessage": "Ude af stand til at kommunikere med {downloadClientName}.", + "DownloadClientCheckUnableToCommunicateMessage": "Ude af stand til at kommunikere med {downloadClientName}. »{errorMessage}«", "DownloadClientCheckNoneAvailableMessage": "Ingen download klient tilgængelig", "DownloadClient": "Download Klient", "DiskSpace": "Disk Plads", @@ -63,13 +63,13 @@ "Dates": "Datoer", "Date": "Dato", "CustomFormatsSettingsSummary": "Bruger Tilpassede Formater og Indstillinger", - "CustomFormatScore": "Bruger Tilpasset Format score", + "CustomFormatScore": "Brugerdefineret formats resultat", "CustomFormats": "Bruger Tilpasset Formater", "CustomFilters": "Bruger Tilpassede Filtere", "Crew": "Besætning", - "ConnectSettingsSummary": "Notifikationer, forbindelser til media servere/afspillere og custom scripts", + "ConnectSettingsSummary": "Notifikationer, forbindelser til medieservere/-afspillere og brugerdefinerede scripts", "Connections": "Forbindelser", - "ConnectionLost": "Forbindelse Mistet", + "ConnectionLost": "Forbindelse mistet", "Connect": "Tilslut", "Component": "Komponent", "CompletedDownloadHandling": "Færdig Download Håndtering", @@ -130,9 +130,9 @@ "EnableInteractiveSearch": "Aktivér interaktiv søgning", "IgnoreDeletedMovies": "Fjern overvågning af slettede film", "Images": "Billeder", - "IndexerPriorityHelpText": "Indekseringsprioritet fra 1 (højest) til 50 (lavest). Standard: 25.", + "IndexerPriorityHelpText": "Indeksatorprioritet fra 1 (højest) til 50 (lavest). Standard: 25. Anvendes til at vælge mellem udgivelser med ellers lige mange point. {appName} vil stadig bruge alle aktiverede indeksatorer til RSS-synkronisering og søgning", "LogLevelTraceHelpTextWarning": "Sporlogning bør kun aktiveres midlertidigt", - "MappedNetworkDrivesWindowsService": "Tilsluttede netværksdrev er ikke tilgængelige, når programmet kører som en Windows-tjeneste. Se FAQ'en for mere information", + "MappedNetworkDrivesWindowsService": "Tilsluttede netværksdrev er ikke tilgængelige, når programmet kører som en Windows-tjeneste. Se FAQ'en ({url}) for mere information.", "MassMovieSearch": "Massefilmsøgning", "MIA": "MIA", "MonitoredOnly": "Kun overvåget", @@ -170,15 +170,15 @@ "AddRemotePathMapping": "Tilføj kortlægning af fjernsti", "AddDelayProfile": "Tilføj forsinkelsesprofil", "AddDownloadClient": "Tilføj downloadklient", - "AddedToDownloadQueue": "Tilføjet til download kø", + "AddedToDownloadQueue": "Føjet til downloadkø", "AddQualityProfile": "Tilføj kvalitetsprofil", "AddRootFolder": "Tilføj rodmappe", "AllFiles": "Alle filer", - "AllMoviesInPathHaveBeenImported": "Alle film i {0} er blevet importeret", + "AllMoviesInPathHaveBeenImported": "Alle film i {path} er blevet importeret", "AllResultsHiddenFilter": "Alle resultater skjules af det anvendte filter", "Always": "Altid", "AnalyticsEnabledHelpText": "Send anonym brugs- og fejlinformation til {appName}s servere. Dette inkluderer information i din browser, hvilke {appName} WebUI-sider du bruger, fejlrapportering samt OS og runtime-version. Vi bruger disse oplysninger til at prioritere funktioner og fejlrettelser.", - "AppDataDirectory": "AppData-bibliotek", + "AppDataDirectory": "AppData-mappe", "AuthBasic": "Grundlæggende (pop op-browser)", "Authentication": "Godkendelse", "ApplyTags": "Anvend tags", @@ -206,7 +206,7 @@ "ChownGroupHelpText": "Gruppens navn eller gid. Brug gid til eksterne filsystemer.", "Add": "Tilføj", "AddCustomFormat": "Tilføj tilpasset format", - "AddToDownloadQueue": "Tilføjet til downloadkø", + "AddToDownloadQueue": "Føj til downloadkø", "AfterManualRefresh": "Efter manuel opdatering", "ApiKey": "API-nøgle", "AptUpdater": "Brug apt til at installere opdateringen", @@ -219,10 +219,10 @@ "CancelProcessing": "Annuller behandling", "CantFindMovie": "Hvorfor kan jeg ikke finde min film?", "CertificateValidation": "Validering af certifikat", - "CertificateValidationHelpText": "Skift, hvor streng HTTPS-certificering er", + "CertificateValidationHelpText": "Skift, hvor streng HTTPS-certificering er. Ændr kun dette hvis du forstå risiciene.", "CertValidationNoLocal": "Deaktiveret for lokale adresser", "ChangeFileDate": "Skift fildato", - "CustomFormatUnknownCondition": "Ukendt tilstand for tilpasset format '{0}'", + "CustomFormatUnknownCondition": "Ukendt betingelse for tilpasset format »{implementation}«", "DatabaseMigration": "DB Migration", "ChownGroupHelpTextWarning": "Dette fungerer kun, hvis den bruger, der kører {appName}, er ejeren af filen. Det er bedre at sikre, at downloadklienten bruger den samme gruppe som {appName}.", "ExcludeMovie": "Ekskluder film", @@ -232,8 +232,8 @@ "CertificationCountryHelpText": "Vælg land for filmcertificeringer", "ImportErrors": "Importfejl", "ImportExtraFiles": "Importer ekstra filer", - "ImportExtraFilesMovieHelpText": "Importer matchende ekstra filer (undertekster, nfo osv.) Efter import af en filmfil", - "ImportFailed": "Import mislykkedes: {0}", + "ImportExtraFilesMovieHelpText": "Importer matchende ekstra filer (undertekster, nfo osv.) efter import af en filmfil", + "ImportFailed": "Import mislykkedes: »{sourceTitle}«", "ImportLibrary": "Biblioteksimport", "ImportListStatusCheckAllClientMessage": "Alle lister er utilgængelige på grund af fejl", "DeleteBackup": "Slet sikkerhedskopi", @@ -310,7 +310,7 @@ "RecyclingBinCleanup": "Oprydning af papirkurven", "Refresh": "Opdater", "RefreshMovie": "Opdater film", - "RegularExpressionsCanBeTested": "Regulære udtryk kan testes ", + "RegularExpressionsCanBeTested": "Regulære udtryk kan testes [her](http://regexstorm.net/tester).", "RejectionCount": "Afvisningstal", "RelativePath": "Relativ sti", "Released": "Udgivet", @@ -358,7 +358,7 @@ "MediaManagementSettings": "Indstillinger for mediestyring", "MediaManagementSettingsSummary": "Navngivning og filhåndteringsindstillinger", "Hostname": "Værtsnavn", - "MinutesSixty": "60 minutter: {0}", + "MinutesSixty": "60 minutter: {sixty}", "Missing": "Mangler", "Month": "Måned", "MoreDetails": "Flere detaljer", @@ -399,7 +399,7 @@ "AllowHardcodedSubs": "Tillad hardcodede subs", "PhysicalRelease": "Fysisk frigivelse", "Port": "Havn", - "ProfilesSettingsSummary": "Kvalitets-, sprog- og forsinkelsesprofiler", + "ProfilesSettingsSummary": "Kvalitets-, sprog-, forsinkelses-, og udgivelsesprofiler", "Progress": "Fremskridt", "Proper": "Passende", "Protocol": "Protokol", @@ -408,7 +408,7 @@ "QualityProfile": "Kvalitetsprofil", "QualityProfiles": "Kvalitetsprofiler", "PreferredSize": "Foretrukken størrelse", - "QuickImport": "Hurtig import", + "QuickImport": "Flyt automatisk", "SupportedListsMovie": "{appName} understøtter alle RSS-filmlister såvel som nedenstående.", "AlreadyInYourLibrary": "Allerede i dit bibliotek", "RecyclingBinCleanupHelpTextWarning": "Filer i papirkurven, der er ældre end det valgte antal dage, renses automatisk", @@ -416,7 +416,7 @@ "AddingTag": "Tilføjer tag", "AgeWhenGrabbed": "Alder (når grebet)", "RefreshAndScan": "Opdater & Scan", - "RequiredHelpText": "Denne {0} betingelse skal matche for at det tilpassede format kan anvendes. Ellers er en enkelt {1} match tilstrækkelig.", + "RequiredHelpText": "Denne {implementationName}-betingelse skal matche for at det tilpassede format kan anvendes. Ellers er et enkelt {implementationName}-match tilstrækkeligt.", "AddNewRestriction": "Tilføj ny begrænsning", "RestartRequiredHelpTextWarning": "Kræver genstart for at træde i kraft", "RestoreBackup": "Gendan sikkerhedskopi", @@ -425,7 +425,7 @@ "Level": "Niveau", "FileBrowserPlaceholderText": "Start med at skrive, eller vælg en sti nedenfor", "StartupDirectory": "Startmappe", - "MoviesSelectedInterp": "{0} Film (er) valgt", + "MoviesSelectedInterp": "{count} film er valgt", "MovieTitle": "Filmtitel", "EditDelayProfile": "Rediger forsinkelsesprofil", "Name": "Navn", @@ -435,7 +435,7 @@ "MustContain": "Skal indeholde", "MustNotContain": "Må ikke indeholde", "NamingSettings": "Navngivningsindstillinger", - "NegateHelpText": "Hvis dette er markeret, gælder det tilpassede format ikke, hvis denne {0} betingelse stemmer overens.", + "NegateHelpText": "Hvis dette er markeret, gælder det tilpassede format ikke, hvis denne {implementationName}-betingelse stemmer overens.", "SystemTimeHealthCheckMessage": "Systemtiden er slukket mere end 1 dag. Planlagte opgaver kører muligvis ikke korrekt, før tiden er rettet", "Posters": "Plakater", "PosterSize": "Plakatstørrelse", @@ -466,53 +466,53 @@ "CloneIndexer": "Klonindekser", "CloneProfile": "Klonprofil", "CloseCurrentModal": "Luk Nuværende Modal", - "ColonReplacement": "Udskiftning af tyktarm", + "ColonReplacement": "Udskiftning af kolon", "ColonReplacementFormatHelpText": "Skift hvordan {appName} håndterer kolonudskiftning", "Conditions": "Betingelser", "Connection": "Forbindelser", "ConnectSettings": "Forbind indstillinger", "ConsideredAvailable": "Anses for tilgængelig", "CopyToClipboard": "Kopier til udklipsholder", - "CopyUsingHardlinksMovieHelpText": "Brug hardlinks, når du prøver at kopiere filer fra torrents, der stadig udsås", + "CopyUsingHardlinksMovieHelpText": "Hardlinks tillader {appName} at importere torrent-filer der stadig seedes, uden at optage ekstra diskplads eller at kopiere the fulde fil. Hardlinks virker kun, hvis kildefilen og destinationsfilen er på samme volumen", "CopyUsingHardlinksHelpTextWarning": "Lejlighedsvis kan fillåse forhindre omdøbning af filer, der bliver seedet. Du kan midlertidigt deaktivere såning og bruge {appName}s omdøbningsfunktion som et arbejde rundt.", - "CouldNotFindResults": "Kunne ikke finde nogen resultater for '{0}'", + "CouldNotFindResults": "Kunne ikke finde nogen resultater for »{term}«", "CreateEmptyMovieFolders": "Opret tomme filmmapper", "CreateGroup": "Opret gruppe", "CurrentlyInstalled": "Aktuelt installeret", "CustomFormat": "Bruger Tilpasset Formater", "CustomFormatHelpText": "{appName} scorer hver udgivelse ved hjælp af summen af scores for matchende tilpassede formater. Hvis en ny udgivelse ville forbedre scoren i samme eller bedre kvalitet, vil {appName} gribe den.", "CustomFormatsSettings": "Indstillinger for brugerdefinerede formater", - "CustomFormatUnknownConditionOption": "Ukendt valgmulighed '{0}' for betingelse '{1}'", + "CustomFormatUnknownConditionOption": "Ukendt valgmulighed »{key}« for betingelsen »{implementation}«", "Cutoff": "Skære af", "UpgradeUntilCustomFormatScoreMovieHelpText": "Når denne score til brugerdefineret format er nået, downloader {appName} ikke længere film", "UpgradeUntilMovieHelpText": "Når denne kvalitet er nået, downloader {appName} ikke længere film", - "CutoffUnmet": "Afskåret ude", + "CutoffUnmet": "Grænse ikke opnået", "Days": "Dage", "Debug": "Fejlfinde", "EditCustomFormat": "Rediger brugerdefineret format", "DefaultCase": "Standard sag", "DefaultDelayProfileMovie": "Dette er standardprofilen. Det gælder for alle film, der ikke har en eksplicit profil.", "DelayProfile": "Udskyd Profiler", - "DeleteBackupMessageText": "Er du sikker på, at du vil slette sikkerhedskopien '{0}'?", + "DeleteBackupMessageText": "Er du sikker på, at du vil slette sikkerhedskopien »{name}«?", "DeleteDelayProfile": "Slet forsinkelsesprofil", - "DeleteDownloadClientMessageText": "Er du sikker på, at du vil slette downloadklienten '{0}'?", + "DeleteDownloadClientMessageText": "Er du sikker på, at du vil fjerne downloadklienten »{name}«?", "DeleteEmptyFolders": "Slet tomme mapper", "DeleteEmptyFoldersHelpText": "Slet tomme filmmapper under diskscanning, og når filmfiler slettes", "DeleteMovieFilesHelpText": "Slet filmfilerne og filmmappen", - "DeleteMovieFiles": "Slet {0} filmfiler", + "DeleteMovieFiles": "Fjern {movieFileCount} filmfiler", "DeleteHeader": "Slet - {0}", "DeleteImportListExclusion": "Slet udelukkelse af importliste", "DeleteIndexer": "Slet Indexer", - "DeleteIndexerMessageText": "Er du sikker på, at du vil slette indeksøren '{0}'?", + "DeleteIndexerMessageText": "Er du sikker på, at du vil slette indeksøren »{name}«?", "DeleteNotification": "Slet underretning", - "DeleteNotificationMessageText": "Er du sikker på, at du vil slette underretningen '{0}'?", + "DeleteNotificationMessageText": "Er du sikker på, at du vil slette notifikationen »{name}«?", "DeleteQualityProfile": "Slet kvalitetsprofil", "DeleteRestriction": "Slet begrænsning", "DeleteRestrictionHelpText": "Er du sikker på, at du vil slette denne begrænsning?", "DeleteSelectedMovie": "Slet valgte film", "DeleteSelectedMovieFiles": "Slet valgte filmfiler", - "DeleteTagMessageText": "Er du sikker på, at du vil slette tagget '{0}'?", - "DeleteMovieFolderConfirmation": "Filmmappen '{0}' og alt dens indhold slettes.", + "DeleteTagMessageText": "Er du sikker på, at du vil slette etiketten »{label}«?", + "DeleteMovieFolderConfirmation": "Filmmappen »{path}« og alt dens indhold slettes.", "DestinationPath": "Destinationssti", "DestinationRelativePath": "Destinationsrelateret sti", "DetailedProgressBar": "Detaljeret statuslinje", @@ -527,7 +527,7 @@ "Downloading": "Downloader", "DownloadPropersAndRepacks": "Propers og Repacks", "DownloadPropersAndRepacksHelpTextCustomFormat": "Brug 'Foretrækkes ikke' til at sortere efter brugerdefineret format score over Propers / Repacks", - "DownloadWarning": "Downloadadvarsel: {0}", + "DownloadWarning": "Downloadadvarsel: »{warningMessage}«", "Edition": "Udgave", "EditImportListExclusion": "Rediger ekskludering af lister", "EditMovieFile": "Rediger filmfil", @@ -580,12 +580,12 @@ "Global": "Global", "GoToInterp": "Gå til {0}", "Grab": "Tag fat", - "GrabRelease": "Grab Release", + "GrabRelease": "Hent udgivelse", "GrabReleaseMessageText": "{appName} var ikke i stand til at bestemme, hvilken film denne udgivelse var til. {appName} kan muligvis ikke automatisk importere denne udgivelse. Vil du hente '{0}'?", "Group": "Gruppe", "HiddenClickToShow": "Skjult, klik for at vise", "Host": "Vært", - "ICalLink": "iCal Link", + "ICalLink": "iCal-link", "IconForCutoffUnmet": "Ikon til Cutoff Unmet", "IgnoredAddresses": "Ignorerede adresser", "IgnoredHelpText": "Frigivelsen afvises, hvis den indeholder et eller flere af vilkårene (store og små bogstaver)", @@ -614,7 +614,7 @@ "Links": "Links", "ImportLists": "Lister", "ImportListSettings": "Listeindstillinger", - "ImportListsSettingsSummary": "Importlister, listeekskluderinger", + "ImportListsSettingsSummary": "Importér fra en anden {appName}-instans eller fra Trakt-lister og håndter listeekskluderinger", "ListSyncLevelHelpText": "Film i biblioteket fjernes eller overvåges, hvis de ikke er på din liste", "LogFiles": "Logfiler", "Logging": "Logning", @@ -640,8 +640,8 @@ "MinimumAvailability": "Minimum tilgængelighed", "MinimumCustomFormatScore": "Minimum tilpasset format score", "MinimumFreeSpaceHelpText": "Forhindre import, hvis den efterlader mindre end denne mængde diskplads tilgængelig", - "MinutesHundredTwenty": "120 minutter: {0}", - "MinutesNinety": "90 minutter: {0}", + "MinutesHundredTwenty": "120 minutter: {hundredTwenty}", + "MinutesNinety": "90 minutter: {ninety}", "Mode": "Mode", "Monitor": "Overvåge", "Monitored": "Overvåget", @@ -666,7 +666,7 @@ "NoTagsHaveBeenAddedYet": "Der er ikke tilføjet nogen tags endnu", "Options": "Muligheder", "Organize": "Organisere", - "OrganizeConfirm": "Er du sikker på, at du vil organisere alle filer i de {0} valgte film?", + "OrganizeConfirm": "Er du sikker på, at du vil organisere alle filer i de {count} valgte film?", "OrganizeSelectedMovies": "Organiser valgte film", "Original": "Original", "OutputPath": "Outputsti", @@ -678,7 +678,7 @@ "Preferred": "Foretrukket", "PreviewRename": "Vis eksempel Omdøb", "PreviewRenameHelpText": "Tip: For at få vist et omdøbning ... vælg 'Annuller', klik derefter på en filmtitel og brug", - "PrioritySettings": "Prioritet: {0}", + "PrioritySettings": "Prioritet: {priority}", "ProxyCheckBadRequestMessage": "Kunne ikke teste proxy. Statuskode: {statusCode}", "ProxyCheckFailedToTestMessage": "Kunne ikke teste proxy: {url}", "ProxyCheckResolveIpMessage": "Mislykkedes at løse IP-adressen til den konfigurerede proxyhost {proxyHostName}", @@ -702,7 +702,7 @@ "ReleaseStatus": "Frigør status", "ReleaseTitle": "Udgiv titel", "Reload": "Genindlæs", - "RemotePathMappings": "Remote Path Mappings", + "RemotePathMappings": "Sammenkædning med fjernsti", "Remove": "Fjerne", "RemovedFromTaskQueue": "Fjernet fra opgavekøen", "RemovedMovieCheckMultipleMessage": "Film {movies} blev fjernet fra TMDb", @@ -756,7 +756,7 @@ "SearchForMovie": "Søg efter film", "SearchMissing": "Søgning mangler", "SearchOnAdd": "Søg på Tilføj", - "ListSearchOnAddMovieHelpText": "Søg efter film på denne liste, når du føjes til {appName}", + "ListSearchOnAddMovieHelpText": "Søg efter film på denne liste, når de føjes til biblioteket", "SearchSelected": "Søgning valgt", "Seconds": "Sekunder", "Security": "Sikkerhed", @@ -805,7 +805,7 @@ "SkipFreeSpaceCheck": "Spring fri pladscheck over", "Small": "Lille", "Socks4": "Strømper 4", - "Socks5": "Socks5 (Support TOR)", + "Socks5": "Socks5 (Understøtter TOR)", "SomeResultsHiddenFilter": "Nogle resultater skjules af det anvendte filter", "SorryThatMovieCannotBeFound": "Beklager, den film kan ikke findes.", "Sort": "Sortere", @@ -830,23 +830,23 @@ "Table": "Tabel", "TableOptions": "Tabelindstillinger", "TableOptionsColumnsMessage": "Vælg hvilke kolonner der er synlige og hvilken rækkefølge de vises i", - "TagDetails": "Tagdetaljer - {0}", + "TagDetails": "Etiketdetaljer - {label}", "TagIsNotUsedAndCanBeDeleted": "Tag bruges ikke og kan slettes", "Tags": "Mærker", "ICalTagsMoviesHelpText": "Gælder film med mindst et matchende tag", "Tasks": "Opgaver", "Test": "Afprøv", "TestAll": "Afprøv alle", - "TheLogLevelDefault": "Logniveauet er som standard 'Info' og kan ændres i", - "ThisCannotBeCancelled": "Dette kan ikke annulleres en gang startet uden genstart af {appName}.", + "TheLogLevelDefault": "Logniveauet er som standard 'Info' og kan ændres under [Generelle indstillinger](/settings/general)", + "ThisCannotBeCancelled": "Dette kan ikke annulleres når først det er startet uden at du deaktiverer alle dine indeksører.", "Title": "Titel", "Titles": "Titler", - "TMDBId": "TMDb Id", + "TMDBId": "TMDb-ID", "TmdbIdExcludeHelpText": "TMDb-id for filmen, der skal ekskluderes", "Today": "I dag", "TorrentDelay": "Torrentforsinkelse", "TorrentDelayHelpText": "Forsink i minutter, før du tager fat i en torrent", - "TorrentDelayTime": "Torrentforsinkelse: {0}", + "TorrentDelayTime": "Torrentforsinkelse: {torrentDelay}", "Torrents": "Torrenter", "TorrentsDisabled": "Torrenter deaktiveret", "Trace": "Spor", @@ -904,7 +904,7 @@ "UpdateAutomaticallyHelpText": "Download og installer opdateringer automatisk. Du kan stadig installere fra System: Updates", "UpdateCheckStartupTranslocationMessage": "Kan ikke installere opdatering, fordi startmappen '{startupFolder}' er i en App Translocation-mappe.", "UpdateCheckUINotWritableMessage": "Kan ikke installere opdatering, fordi '{userName}' ikke kan skrive til mappen for brugergrænseflade '{uiFolder}'.", - "UpdateMechanismHelpText": "Brug {appName}s indbyggede opdatering eller et script", + "UpdateMechanismHelpText": "Brug {appName}s indbyggede opdateringsfunktion eller et script", "UpdateScriptPathHelpText": "Sti til et brugerdefineret script, der tager en udpakket opdateringspakke og håndterer resten af opdateringsprocessen", "UpdateSelected": "Opdatering valgt", "UpgradeUntilCustomFormatScore": "Opgrader indtil brugerdefineret format score", @@ -917,7 +917,7 @@ "Usenet": "Usenet", "UsenetDelay": "Usenet-forsinkelse", "UsenetDelayHelpText": "Forsink i minutter, før du tager fat i en frigivelse fra Usenet", - "UsenetDelayTime": "Usenetforsinkelse: {0}", + "UsenetDelayTime": "Usenet-forsinkelse: {usenetDelay}", "UsenetDisabled": "Usenet deaktiveret", "UseProxy": "Brug proxy", "Version": "Version", @@ -930,7 +930,7 @@ "WhitelistedHardcodedSubsHelpText": "Undertekstmærker, der er angivet her, betragtes ikke som hardkodede", "WhitelistedSubtitleTags": "Hvidlistede undertekstmærker", "Wiki": "Wiki", - "WouldYouLikeToRestoreBackup": "Vil du gendanne sikkerhedskopien {0}?", + "WouldYouLikeToRestoreBackup": "Vil du gendanne sikkerhedskopien »{name}«?", "Year": "År", "YesCancel": "Ja, Annuller", "YesMoveFiles": "Ja, flyt filerne", @@ -966,7 +966,7 @@ "Rating": "Bedømmelser", "RssSyncIntervalHelpText": "Interval på få minutter. Sæt til nul for at deaktivere (dette stopper al automatisk frigivelse)", "MonitorMovies": "Overvåg film", - "NoCollections": "Ingen film fundet. For at komme i gang vil du tilføje en ny film eller importere nogle eksisterende.", + "NoCollections": "Ingen samlinger fundet. For at komme i gang skal du tilføje en ny film eller importere nogle eksisterende", "AllCollectionsHiddenDueToFilter": "Alle film er gemt på grund af aktivt filter.", "Collections": "Samling", "File": "Filer", @@ -979,10 +979,10 @@ "DeleteDelayProfileMessageText": "Er du sikker på, at du vil slette denne forsinkelsesprofil?", "DeleteImportListExclusionMessageText": "Er du sikker på, at du vil slette denne undtagelse fra importlisten?", "DeleteFormatMessageText": "Er du sikker på, at du vil slette formattag {0}?", - "DeleteConditionMessageText": "Er du sikker på, at du vil slette listen '{0}'?", + "DeleteConditionMessageText": "Er du sikker på, at du vil slette betingelsen »{name}«?", "DeleteCustomFormatMessageText": "Er du sikker på, at du vil slette indeksøren '{name}'?", - "RemoveSelectedItemQueueMessageText": "Er du sikker på, at du vil fjerne {0} element {1} fra køen?", - "RemoveSelectedItemsQueueMessageText": "Er du sikker på, at du vil fjerne {0} element {1} fra køen?", + "RemoveSelectedItemQueueMessageText": "Er du sikker på, at du vil fjerne 1 element fra køen?", + "RemoveSelectedItemsQueueMessageText": "Er du sikker på, at du vil fjerne {selectedCount} elementer fra køen?", "ResetAPIKeyMessageText": "Er du sikker på, at du vil nulstille din API-nøgle?", "ApplyTagsHelpTextAdd": "Tilføj: Føj tags til den eksisterende liste over tags", "ApplyTagsHelpTextHowToApplyIndexers": "Sådan anvendes tags på de valgte film", @@ -1006,16 +1006,16 @@ "DownloadClientsLoadError": "Kunne ikke indlæse downloadklienter", "NotificationStatusSingleClientHealthCheckMessage": "Lister utilgængelige på grund af fejl: {notificationNames}", "NotificationsSimplepushSettingsEvent": "Begivenhed", - "RemoveQueueItemConfirmation": "Er du sikker på, at du vil fjerne {0} element {1} fra køen?", + "RemoveQueueItemConfirmation": "Er du sikker på, at du vil fjerne »{sourceTitle}« fra køen?", "AutoRedownloadFailed": "Download fejlede", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimum tilpasset format score", "EditImportListImplementation": "Tilføj importliste - {implementationName}", "FormatAgeMinute": "Protokoller", "InteractiveImportLoadError": "Kunne ikke indlæse manuelle importvarer", - "ConditionUsingRegularExpressions": "Denne betingelse stemmer overens med brug af regulære udtryk. Bemærk, at tegnene {0} har en særlig betydning og skal undslippe med en {1}", - "ConnectionLostReconnect": "Radarr vil prøve at tilslutte automatisk, eller du kan klikke genindlæs forneden.", + "ConditionUsingRegularExpressions": "Denne betingelse stemmer overens ved brug af regulære udtryk. Bemærk, at tegnene »\\^$.|?*+()[{« har en særlig betydning og skal indledes med indkodningstegnet »\\«", + "ConnectionLostReconnect": "{appName} vil prøve at tilslutte automatisk. Ellers du kan klikke genindlæs forneden.", "DeleteSpecification": "Slet underretning", - "DeleteSpecificationHelpText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", + "DeleteSpecificationHelpText": "Er du sikker på, at du vil slette specifikationen »{name}«?", "DeletedReasonUpgrade": "Filen blev slettet for at importere en opgradering", "Directory": "Mappe", "Lists": "Lister", @@ -1023,15 +1023,15 @@ "PreferredProtocol": "Foretrukken protokol", "RestartLater": "Jeg genstarter senere", "SelectDropdown": "'Vælg...", - "AddIndexerImplementation": "Tilføj betingelse - {implementationName}", + "AddIndexerImplementation": "Tilføj indeksør - {implementationName}", "EditDownloadClientImplementation": "Tilføj downloadklient - {implementationName}", - "DelayingDownloadUntil": "Forsinker download indtil {0} kl. {1}", - "AddAutoTag": "Tilføj automatisk Tag", - "DeleteAutoTagHelpText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", + "DelayingDownloadUntil": "Forsinker download indtil {date} kl. {time}", + "AddAutoTag": "Tilføj automatisk etiket", + "DeleteAutoTagHelpText": "Er du sikker på, at du vil slette den automatiske etiket »{name}«?", "BlocklistLoadError": "Kunne ikke indlæse sortliste", "NotificationStatusAllClientHealthCheckMessage": "Alle lister er utilgængelige på grund af fejl", "InteractiveSearchModalHeader": "Interaktiv søgning", - "RetryingDownloadOn": "Prøver igen at downloade {0} kl. {1}", + "RetryingDownloadOn": "Prøver igen at downloade d. {date} kl. {time}", "OrganizeLoadError": "Fejl ved indlæsning af forhåndsvisning", "QueueLoadError": "Kunne kunne ikke indlæses", "EditIndexerImplementation": "Tilføj betingelse - {implementationName}", @@ -1050,39 +1050,39 @@ "CustomFilter": "Bruger Tilpassede Filtere", "ReleaseProfiles": "udgivelsesprofil", "EditConditionImplementation": "Tilføj forbindelse - {implementationName}", - "GrabId": "Grab ID", + "GrabId": "Hent ID", "FormatAgeMinutes": "Protokoller", "Label": "Etiket", "RemoveSelectedBlocklistMessageText": "Er du sikker på, at du vil fjerne de valgte emner fra sortlisten?", - "AddAutoTagError": "Kan ikke tilføje en ny liste, prøv igen.", + "AddAutoTagError": "Kan ikke tilføje en ny automatisk etiket. Prøv igen.", "Release": "udgivelse", "DelayProfileMovieTagsHelpText": "Gælder film med mindst et matchende tag", "OrganizeNothingToRename": "Succes! Mit arbejde er udført, ingen filer at omdøbe.", "MovieFileDeleted": "Slet på filmfil", "ApplyTagsHelpTextHowToApplyMovies": "Sådan anvendes tags på de valgte film", "DownloadClientSettingsRecentPriority": "Kundens prioritet", - "DeleteQualityProfileMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", + "DeleteQualityProfileMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen »{name}«?", "DeleteSelectedMovieFilesHelpText": "Er du sikker på, at du vil slette de valgte filmfiler?", "MovieIsNotMonitored": "Film overvåges", - "DeleteReleaseProfile": "Slet forsinkelsesprofil", - "DeleteReleaseProfileMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", + "DeleteReleaseProfile": "Slet udgivelsesprofil", + "DeleteReleaseProfileMessageText": "Er du sikker på, at du vil slette udgivelsesprofilen »{name}«?", "DeletedReasonMovieMissingFromDisk": "{appName} kunne ikke finde filen på disken, så den blev fjernet", "ReleaseProfilesLoadError": "Kunne ikke indlæse forsinkelsesprofiler", - "SearchOnAddCollectionHelpText": "Søg efter film på denne liste, når du føjes til {appName}", + "SearchOnAddCollectionHelpText": "Søg efter film i denne samling, når de føjes til biblioteket", "EditConnectionImplementation": "Tilføj forbindelse - {implementationName}", "MovieSearchResultsLoadError": "Kunne ikke indlæse resultater for denne filmsøgning. Prøv igen senere", "FormatAgeHour": "Timer", "IndexerSettingsMultiLanguageRelease": "Multi-sprog", - "DeleteImportListMessageText": "Er du sikker på, at du vil slette kvalitetsprofilen {0}", + "DeleteImportListMessageText": "Er du sikker på, at du vil slette listen »{name}«?", "ReleaseGroups": "Slip gruppe", "IMDbId": "TMDb Id", - "AddDelayProfileError": "Kan ikke tilføje en ny forsinkelsesprofil. Prøv venligst igen.", + "AddDelayProfileError": "Kan ikke tilføje en ny forsinkelsesprofil. Prøv igen.", "ShowUnknownMovieItemsHelpText": "Vis emner uden en film i køen. Dette kan omfatte fjernede film eller andet i {appName}s kategori", "MovieFileDeletedTooltip": "Slet på filmfil", "DeleteMovieFolders": "Slet filmmappe", "DeleteMovieFoldersHelpText": "Slet filmmappen og dens indhold", "DeleteSelectedMovies": "Slet valgte filmfiler", - "AutoTaggingNegateHelpText": "Hvis dette er markeret, gælder det tilpassede format ikke, hvis denne {0} betingelse stemmer overens.", + "AutoTaggingNegateHelpText": "Hvis dette er markeret, vil reglen for automatisk etiket ikke blive anvendt, hvis denne {implementationName}-betingelse stemmer overens.", "DeleteSelectedImportListExclusionsMessageText": "Er du sikker på, at du vil slette denne undtagelse fra importlisten?", "DeleteSelectedCustomFormats": "Slet brugerdefineret format", "ReleaseDate": "Slip datoer", @@ -1095,5 +1095,6 @@ "Delay": "Forsinkelse", "EditReleaseProfile": "Rediger forsinkelsesprofil", "DownloadClientUnavailable": "Downloadklienten er ikke tilgængelig", - "AddReleaseProfile": "Rediger forsinkelsesprofil" + "AddReleaseProfile": "Rediger forsinkelsesprofil", + "ApiKeyValidationHealthCheckMessage": "Opdater din API-nøgle til at være på mindste {length} karakterer. Dette kan gøres i indstillingerne eller i konfigurationsfilen" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 8bbfc4db94..0abe90621a 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1787,5 +1787,6 @@ "UnableToImportAutomatically": "Kann nicht automatisch importiert werden", "UnknownEventTooltip": "Unbekanntes Ereignis", "Warning": "Warnung", - "YesterdayAt": "Gestern um {time}" + "YesterdayAt": "Gestern um {time}", + "RemotePathMappingsInfo": "Remote-Pfadzuordnungen sind sehr selten erforderlich. Wenn {appName} und dein Download-Client auf demselben System sind, ist es besser, deine Pfade abzugleichen. Weitere Informationen findest du im [Wiki]({wikiLink})." } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index ad47985eb1..4c660c5318 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1863,5 +1863,8 @@ "Warning": "Aviso", "FavoriteFolderRemove": "Eliminar carpeta favorita", "DownloadClientUnavailable": "Cliente de descarga no disponible", - "NotificationsSettingsWebhookHeaders": "Cabeceras" + "NotificationsSettingsWebhookHeaders": "Cabeceras", + "MetadataKometaDeprecated": "Los archivos de Kometa no seguirán siendo creados, el soporte se eliminará completamente en la v6", + "MetadataKometaDeprecatedSetting": "Obsoleto", + "Fallback": "Retirada" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 5748e0a368..3d03220f43 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -865,7 +865,7 @@ "BrowserReloadRequired": "חובה לטעון דפדפן", "UiSettings": "הגדרות ממשק המשתמש", "UiSettingsSummary": "אפשרויות לקויות לוח שנה, תאריך וצבע", - "AddConditionError": "לא ניתן להוסיף תנאי חדש, נסה שוב.", + "AddConditionError": "לא ניתן להוסיף תנאי חדש, נסה שנית.", "AddCustomFormatError": "לא ניתן להוסיף פורמט מותאם אישית חדש, נסה שוב.", "AddDownloadClientError": "לא ניתן להוסיף לקוח הורדות חדש, נסה שוב.", "AddIndexerError": "לא ניתן להוסיף אינדקס חדש, נסה שוב.", @@ -1048,7 +1048,7 @@ "ReleaseProfilesLoadError": "לא ניתן לטעון פרופילי עיכוב", "RemoveQueueItemConfirmation": "האם אתה בטוח שברצונך להסיר את {0} פריט {1} מהתור?", "Yes": "כן", - "AddAutoTag": "הוסף טגית אוטומטית", + "AddAutoTag": "הוסף תג אוטומטית", "DeleteQualityProfileMessageText": "האם אתה בטוח שברצונך למחוק את פרופיל האיכות {0}", "ApplyTagsHelpTextHowToApplyDownloadClients": "כיצד להחיל תגים על הסרטים שנבחרו", "DisabledForLocalAddresses": "מושבת לכתובות מקומיות", @@ -1084,7 +1084,7 @@ "DeleteReleaseProfile": "מחק פרופיל עיכוב", "InteractiveSearchModalHeader": "חיפוש אינטראקטיבי", "InteractiveImportLoadError": "לא ניתן לטעון פריטי ייבוא ידניים", - "AddAutoTagError": "לא ניתן להוסיף רשימה חדשה, אנא נסה שוב.", + "AddAutoTagError": "לא ניתן להוסיף תג חדש, נסה שנית.", "No": "לא", "MustNotContainHelpText": "המהדורה תידחה אם היא מכילה אחד או יותר מהתנאים (חסר רישיות)", "ApplyTagsHelpTextHowToApplyMovies": "כיצד להחיל תגים על הסרטים שנבחרו", @@ -1118,5 +1118,6 @@ "Clone": "סגור", "EditReleaseProfile": "ערוך פרופיל עיכוב", "AddReleaseProfile": "ערוך פרופיל עיכוב", - "DownloadClientUnavailable": "לקוח ההורדות אינו זמין" + "DownloadClientUnavailable": "לקוח ההורדות אינו זמין", + "AddCondition": "הוסף תנאי" } diff --git a/src/NzbDrone.Core/Localization/Core/id.json b/src/NzbDrone.Core/Localization/Core/id.json index 232b2abad5..aee3dcd4be 100644 --- a/src/NzbDrone.Core/Localization/Core/id.json +++ b/src/NzbDrone.Core/Localization/Core/id.json @@ -7,7 +7,7 @@ "Activity": "Aktivitas", "Add": "Tambah", "AddCustomFormat": "Tambahkan Format Khusus", - "AddDownloadClient": "Tambahkan Klien Pengunduhan", + "AddDownloadClient": "Tambahkan Download Client", "AddIndexer": "Tambahkan Pengindeks", "Age": "Usia", "All": "Semua", @@ -174,5 +174,7 @@ "ToggleMonitoredToUnmonitored": "Dimonitor, klik untuk berhenti monitor", "ToggleUnmonitoredToMonitored": "Tidak dimonitor, klik untuk monitor", "Clone": "Tutup", - "EnableSsl": "Aktifkan RSS" + "EnableSsl": "Aktifkan RSS", + "AddCustomFormatError": "Tidak dapat menambahkan format khusus baru, coba lagi.", + "AddDelayProfile": "Tambah Delay Profile" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 4830357263..edd38a3d8a 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -85,7 +85,7 @@ "UpdateScriptPathHelpText": "추출 된 업데이트 패키지를 사용하고 나머지 업데이트 프로세스를 처리하는 사용자 지정 스크립트에 대한 경로", "UpgradeUntil": "품질까지 업그레이드", "Usenet": "유즈넷", - "VisitTheWikiForMoreDetails": "자세한 내용은 위키를 방문하십시오. ", + "VisitTheWikiForMoreDetails": "자세한 내용은 위키를 방문하세요: ", "YouCanAlsoSearch": "영화의 TMDb ID 또는 IMDb ID를 사용하여 검색 할 수도 있습니다. 예 : `tmdb : 71663`", "OverviewOptions": "개요 옵션", "PackageVersion": "패키지 버전", @@ -404,7 +404,7 @@ "ImportListStatusCheckAllClientMessage": "실패로 인해 모든 목록을 사용할 수 없습니다.", "ImportListStatusCheckSingleClientMessage": "실패로 인해 사용할 수없는 목록 : {importListNames}", "TotalSpace": "총 공간", - "UpdateCheckStartupNotWritableMessage": "'{1}'사용자가 '{0}'시작 폴더에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.", + "UpdateCheckStartupNotWritableMessage": "'{userName}' 사용자가 시작 폴더 '{startupFolder}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.", "UpgradesAllowedHelpText": "비활성화 된 자질은 업그레이드되지 않습니다.", "Backup": "백업", "Username": "사용자 이름", @@ -413,9 +413,9 @@ "Disabled": "비활성화됨", "Peers": "동료", "UiSettingsLoadError": "UI 설정을 불러올 수 없습니다.", - "Unavailable": "없는", + "Unavailable": "사용 불가능", "VideoCodec": "비디오 코덱", - "View": "표시 변경", + "View": "화면", "Importing": "가져오기", "NoLeaveIt": "아니, 놔둬", "NoLimitForAnyRuntime": "런타임 제한 없음", @@ -853,10 +853,10 @@ "TMDBId": "TMDb ID", "TmdbIdExcludeHelpText": "제외 할 영화의 TMDb ID", "Today": "오늘", - "TorrentDelay": "급류 지연", - "TorrentDelayHelpText": "급류를 잡기 전에 대기하는 데 몇 분이 걸립니다.", - "TorrentDelayTime": "급류 지연 : {0}", - "Torrents": "급류", + "TorrentDelay": "토렌트 지연", + "TorrentDelayHelpText": "토렌트를 잡기 전에 대기까지 소요되는 지연 (분)", + "TorrentDelayTime": "토렌트 지연: {0torrentDelay}", + "Torrents": "토렌트", "TorrentsDisabled": "토렌트 비활성화", "Trace": "자취", "Trailer": "트레일러", @@ -869,10 +869,10 @@ "BrowserReloadRequired": "브라우저 새로 고침 필요", "UiSettings": "UI 설정", "UiSettingsSummary": "달력, 날짜 및 색상 장애 옵션", - "AddConditionError": "새 조건을 추가 할 수 없습니다. 다시 시도하십시오.", + "AddConditionError": "새 조건을 추가 할 수 없습니다. 다시 시도해주세요.", "AddCustomFormatError": "새 사용자 정의 형식을 추가 할 수 없습니다. 다시 시도하십시오.", "AddDownloadClientError": "새 다운로드 클라이언트를 추가 할 수 없습니다. 다시 시도하십시오.", - "AddIndexerError": "새 인덱서를 추가 할 수 없습니다. 다시 시도하십시오.", + "AddIndexerError": "새 인덱서를 추가 할 수 없습니다. 다시 시도해주세요.", "AddImportListExclusionError": "새 목록 제외를 추가 할 수 없습니다. 다시 시도하십시오.", "AddListError": "새 목록을 추가 할 수 없습니다. 다시 시도하십시오.", "AddQualityProfileError": "새 품질 프로필을 추가 할 수 없습니다. 다시 시도하십시오.", @@ -908,12 +908,12 @@ "UpdateAll": "모두 업데이트", "UpdateAutomaticallyHelpText": "업데이트를 자동으로 다운로드하고 설치합니다. 시스템 : 업데이트에서 계속 설치할 수 있습니다.", "UpdateCheckStartupTranslocationMessage": "시작 폴더 '{startupFolder}'이 (가) App Translocation 폴더에 있으므로 업데이트를 설치할 수 없습니다.", - "UpdateMechanismHelpText": "{appName}의 내장 업데이트 프로그램 또는 스크립트 사용", + "UpdateMechanismHelpText": "{appName}의 내장 업데이트 도구 또는 스크립트 사용", "UpdateSelected": "선택한 항목 업데이트", "UpgradeUntilCustomFormatScore": "사용자 지정 형식 점수까지 업그레이드", "UpgradeUntilThisQualityIsMetOrExceeded": "이 품질이 충족되거나 초과 될 때까지 업그레이드", "Uppercase": "대문자", - "UrlBase": "URL베이스", + "UrlBase": "URL 기반", "UrlBaseHelpText": "역방향 프록시 지원의 경우 기본값은 비어 있습니다.", "UseHardlinksInsteadOfCopy": "복사 대신 하드 링크 사용", "UsenetDelay": "유즈넷 지연", @@ -928,12 +928,12 @@ "Week": "주", "Weeks": "주", "WhitelistedHardcodedSubsHelpText": "여기에 설정된 자막 태그는 하드 코딩 된 것으로 간주되지 않습니다.", - "WhitelistedSubtitleTags": "허용 된 자막 태그", + "WhitelistedSubtitleTags": "허용된 자막 태그", "Wiki": "위키", - "WouldYouLikeToRestoreBackup": "{0} 백업을 복원 하시겠습니까?", + "WouldYouLikeToRestoreBackup": "'{name}' 백업을 복원하시겠습니까?", "Year": "년", "YesCancel": "예, 취소합니다", - "YesMoveFiles": "예, 파일 이동", + "YesMoveFiles": "예, 파일을 이동합니다", "Yesterday": "어제", "MaintenanceRelease": "유지 관리 출시 : 버그 수정 및 기타 개선. 자세한 내용은 Github 커밋 내역을 참조하십시오.", "MissingMonitoredAndConsideredAvailable": "누락 (모니터링 됨)", @@ -1024,7 +1024,7 @@ "ReleaseProfilesLoadError": "지연 프로필을로드 할 수 없습니다.", "QualitiesLoadError": "품질을로드 할 수 없습니다.", "TablePageSize": "페이지 크기", - "AddAutoTagError": "새 목록을 추가 할 수 없습니다. 다시 시도하십시오.", + "AddAutoTagError": "새 자동 태그을 추가 할 수 없습니다. 다시 시도해주세요.", "AddRootFolderError": "루트 폴더를로드 할 수 없습니다.", "ApplyTagsHelpTextHowToApplyImportLists": "선택한 동영상에 태그를 적용하는 방법", "MustNotContainHelpText": "하나 이상의 용어가 포함 된 경우 릴리스가 거부됩니다 (대소 문자 구분 안 함).", @@ -1045,7 +1045,7 @@ "MovieSearchResultsLoadError": "이 영화 검색 결과를 불러올 수 없습니다. 나중에 다시 시도", "NotificationsSimplepushSettingsEvent": "이벤트", "SearchOnAddCollectionHelpText": "{appName}에 추가되면이 목록에서 영화 검색", - "AddDelayProfileError": "새 품질 프로필을 추가 할 수 없습니다. 다시 시도하십시오.", + "AddDelayProfileError": "새 지연 프로필을 추가할 수 없습니다. 다시 시도해주세요.", "DeleteMovieFolders": "영화 폴더 삭제", "DeleteMovieFoldersHelpText": "동영상 폴더 및 내용 삭제", "DeleteSelectedMovies": "선택한 동영상 파일 삭제", @@ -1073,5 +1073,23 @@ "EditConditionImplementation": "연결 추가 - {implementationName}", "EditConnectionImplementation": "애플리케이션 추가 - {implementationName}", "EditDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", - "AddConditionImplementation": "연결 추가 - {implementationName}" + "AddConditionImplementation": "조건 추가 - {implementationName}", + "UnknownEventTooltip": "알 수 없는 이벤트", + "Waiting": "기다리는 중", + "TraktRating": "Trakt 평점", + "AddAutoTag": "자동 태그 추가", + "AddCondition": "조건 추가", + "TotalMovies": "총 영화", + "UseSsl": "SSL 사용", + "UsenetBlackhole": "유즈넷 블랙홀", + "TypeOfList": "{typeOfList} 목록", + "AddImportList": "가져오기 목록 추가", + "AddImportListImplementation": "가져오기 목록 추가 - {implementationName}", + "TorrentBlackholeTorrentFolder": "토렌트 폴더", + "UsenetBlackholeNzbFolder": "Nzb 폴더", + "UpdateAvailableHealthCheckMessage": "새 업데이트 사용 가능: {version}", + "Warning": "경고", + "VideoDynamicRange": "동영상 다이나믹 레인지", + "XmlRpcPath": "XML RPC 경로", + "YesterdayAt": "어제 {time}" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index d5e1611a49..ca7d685fc6 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1864,5 +1864,7 @@ "FavoriteFolders": "Pastas Favoritas", "Warning": "Cuidado", "DownloadClientUnavailable": "Cliente de download indisponível", - "NotificationsSettingsWebhookHeaders": "Cabeçalhos" + "NotificationsSettingsWebhookHeaders": "Cabeçalhos", + "MetadataKometaDeprecatedSetting": "Deprecado", + "MetadataKometaDeprecated": "Os arquivos Kometa não serão mais criados, o suporte será completamente removido na v6" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index b999c29303..6be032e0fb 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -19,7 +19,7 @@ "Sort": "Sınıflandır", "SetTags": "Etiketleri Ayarla", "Scheduled": "Planlı", - "RootFolders": "Kök klasörler", + "RootFolders": "Kök Klasörler", "RootFolderCheckSingleMessage": "Eksik kök klasör: {rootFolderPath}", "RootFolderCheckMultipleMessage": "Birden fazla kök klasörler eksik: {rootFolderPaths}", "RootFolder": "Kök Klasör", @@ -29,20 +29,20 @@ "ProxyCheckBadRequestMessage": "Proxy ile test edilemedi. DurumKodu: {statusCode}", "Proxy": "Proxy", "PreviewRename": "Yeniden Adlandır ve Önizle", - "ImportListStatusCheckSingleClientMessage": "Hatalar nedeniyle kullanılamayan listeler: {importListNames}", - "ImportListStatusCheckAllClientMessage": "Hatalar nedeniyle tüm listeler kullanılamıyor", + "ImportListStatusCheckSingleClientMessage": "Hatalar nedeniyle kullanılamayan dizinleyiciler: {importListNames}", + "ImportListStatusCheckAllClientMessage": "Hatalar nedeniyle tüm dizinleyiciler kullanılamıyor", "MonitoredOnly": "Sadece Takip Edilen", "MetadataSettingsMovieSummary": "Filmler içe aktarıldığında veya yenilenince meta veri dosyaları oluştur", "Metadata": "Meta veri", - "MediaManagement": "Medya işletme", + "MediaManagement": "Medya Yönetimi", "Logging": "Loglama", - "LogFiles": "Log dosyaları", + "LogFiles": "Log Kayıtları", "ImportListsSettingsSummary": "Başka bir {appName} örneğinden veya Trakt listelerinden içe aktarın ve liste hariç tutma işlemlerini yönetin", "ImportTipsMessage": "İçe aktarmanın sorunsuz geçmesini sağlamak için bazı ipuçları:", "ImportHeader": "{appName} uygulamasına film eklemek için mevcut kitaplığı içe aktarın", - "Host": "Ana bilgisayar", - "GrabSelected": "Seçilenleri Kap", - "GeneralSettingsSummary": "Port, SSL, kullanıcı adı/şifre, proxy, analitikler ve güncellemeler", + "Host": "Sunucu", + "GrabSelected": "Seçilenleri Al", + "GeneralSettingsSummary": "Port, SSL, kullanıcı adı/şifre, proxy, analizler ve güncellemeler", "Folder": "Klasör", "Files": "Dosyalar", "Filename": "Dosya adı", @@ -51,7 +51,7 @@ "CustomFormats": "Özel Formatlar", "Crew": "Ekip", "AppDataLocationHealthCheckMessage": "Güncelleme sırasında AppData'nın silinmesini önlemek için güncelleme yapılmayacaktır", - "AddNewTmdbIdMessage": "Ayrıca bir filmin TMDb kimliğini kullanarak da arama yapabilirsiniz. Örneğin. tmdb:71663", + "AddNewTmdbIdMessage": "Ayrıca bir filmin TMDb kimliğini kullanarak da arama yapabilirsiniz. Örneğin. tmdb:50737", "AddNewMessage": "Yeni film eklemek çok kolay, eklemek istediğiniz filmin adını yazmanız yeterli", "AddExclusion": "Dışlananlara Ekle", "Actions": "Eylemler", @@ -68,7 +68,7 @@ "UpdateAll": "Tümünü Güncelle", "UnselectAll": "Tüm Seçimleri Kaldır", "UnmappedFolders": "Eşlenmemiş Klasörler", - "UiSettingsSummary": "Takvim, tarih ve renk engelli seçenekler", + "UiSettingsSummary": "Takvim, tarih ve renk körlüğü seçenekleri", "Ui": "Arayüz", "Titles": "Başlıklar", "Timeleft": "Kalan Zaman", @@ -123,7 +123,7 @@ "MovieNaming": "Film Adlandırma", "MovieEditor": "Film Editörü", "Movie": "Film", - "MoreInfo": "Daha fazla bilgi", + "MoreInfo": "Daha Fazla Bilgi", "Month": "Ay", "Monitor": "Takip", "Missing": "Eksik", @@ -145,7 +145,7 @@ "Formats": "Formatlar", "Forecast": "Tahmin", "Filter": "Filtre", - "FileManagement": "Dosya idare", + "FileManagement": "Dosya Yönetimi", "Failed": "Başarısız oldu", "Edit": "Düzenle", "Downloaded": "İndirildi", @@ -156,19 +156,19 @@ "ConnectSettingsSummary": "Bildirimler, medya sunucularına/oynatıcılara bağlantılar ve özel komut dosyaları", "CompletedDownloadHandling": "Tamamlanan İndirme İşlemleri", "ChooseAnotherFolder": "Başka bir dosya seç", - "Analytics": "Analitik", + "Analytics": "Analiz", "All": "Hepsi", "Agenda": "Ajanda", - "Added": "Eklendi", + "Added": "Eklenme", "Activity": "Etkinlik", - "MinimumCustomFormatScoreHelpText": "İndirmeye izin verilen minimum özel biçim puanı", + "MinimumCustomFormatScoreHelpText": "İndirmeye izin verilen minimum özel format puanı", "MovieIsRecommend": "Son eklenenlere göre film önerilir", "NoEventsFound": "Etkinlik bulunamadı", "NoMinimumForAnyRuntime": "Herhangi bir çalışma süresi için minimum değer yok", "NoMoviesExist": "Film bulunamadı, başlamak için yeni bir film eklemek veya mevcut filmlerden bazılarını içe aktarmak isteyeceksiniz.", - "CancelPendingTask": "Bu bekleyen görevi iptal etmek istediğinizden emin misiniz?", + "CancelPendingTask": "Bekleyen görevi iptal etmek istediğinizden emin misiniz?", "OnHealthIssue": "Sağlık Sorunu Hakkında", - "OnLatestVersion": "{appName}'ın en son sürümü zaten kurulu", + "OnLatestVersion": "{appName}'ın en son sürümü kurulu", "OnlyTorrent": "Sadece Torrent", "OnRename": "Yeniden Adlandırıldığında", "OpenBrowserOnStart": "Başlangıçta tarayıcıyı aç", @@ -190,7 +190,7 @@ "RemotePath": "Uzak Yol", "ShowCertification": "Sertifikayı Göster", "TestAllClients": "Tüm İstemcileri Test Et", - "TestAllIndexers": "Tüm Dizinleyicileri Test Et", + "TestAllIndexers": "Dizinleyicileri Test Et", "TestAllLists": "Tüm Listeleri Test Et", "TMDb": "TMDb", "Name": "İsim", @@ -204,13 +204,13 @@ "LoadingMovieCreditsFailed": "Film jeneriği yüklenemedi", "LoadingMovieFilesFailed": "Film dosyaları yüklenemedi", "Local": "Yerel", - "Location": "yer", + "Location": "Klasör Yolu", "MarkAsFailed": "Başarısız olarak işaretle", "MaximumSizeHelpText": "MB cinsinden alınacak bir sürüm için maksimum boyut. Sınırsız olarak ayarlamak için sıfıra ayarlayın", "MediaManagementSettings": "Medya Yönetimi Ayarları", "MountMovieHealthCheckMessage": "Bir film yolu içeren bağlama, salt okunur olarak bağlanır: ", "RadarrTags": "{appName} Etiketleri", - "VideoCodec": "Video Codec", + "VideoCodec": "Video Kodek", "NoLimitForAnyRuntime": "Herhangi bir çalışma zamanı için sınır yok", "CloneCustomFormat": "Özel Formatı Klonla", "Columns": "Sütunlar", @@ -219,19 +219,19 @@ "DeleteIndexerMessageText": "'{name}' dizinleyicisini silmek istediğinizden emin misiniz?", "DeleteRestrictionHelpText": "Bu kısıtlamayı silmek istediğinizden emin misiniz?", "DoneEditingGroups": "Grupları Düzenleme Bitti", - "EditCustomFormat": "Özel Biçimi Düzenle", + "EditCustomFormat": "Özel Formatı Düzenle", "EditPerson": "Kişiyi Düzenle", "EditQualityProfile": "Kalite Profilini Düzenle", "EnableAutomaticSearchHelpText": "Kullanıcı arayüzü veya {appName} tarafından otomatik aramalar yapıldığında kullanılacaktır", - "EnableColorImpairedModeHelpText": "Renk bozukluğu olan kullanıcıların renk kodlu bilgileri daha iyi ayırt etmesine olanak tanıyan değiştirilmiş stil", + "EnableColorImpairedModeHelpText": "Renk engelli kullanıcıların renkleri daha iyi ayırt edebilmelerini sağlamak için değiştirilmiş stil", "EnableInteractiveSearch": "Etkileşimli Aramayı Etkinleştir", "ExtraFileExtensionsHelpTextsExamples": "Örnekler: \".sub, .nfo\" veya \"sub, nfo\"", "FocusSearchBox": "Arama Kutusuna Odaklan", "Folders": "Klasörler", "FollowPerson": "Kişiyi Takip Et", - "GrabReleaseMessageText": "{appName}, bu yayının hangi film için olduğunu belirleyemedi. {appName} bu yayını otomatik olarak içe aktaramayabilir. '{0}'ı yakalamak istiyor musunuz?", + "GrabReleaseMessageText": "{appName}, bu yayının hangi film için olduğunu belirleyemedi. {appName} bu yayını otomatik olarak içe aktaramayabilir. '{0}'ı almak istiyor musunuz?", "IndexerPriority": "Dizinleyici Önceliği", - "IndexerSearchCheckNoAvailableIndexersMessage": "Son indeksleyici hataları nedeniyle arama özellikli indeksleyicilerin tümü geçici olarak kullanılamıyor", + "IndexerSearchCheckNoAvailableIndexersMessage": "Son zamanlardaki dizinleyici hataları nedeniyle tüm arama yeteneğine sahip dizinleyiciler geçici olarak kullanılamıyor", "InstallLatest": "En Sonu Yükle", "InteractiveSearch": "Etkileşimli Arama", "MovieInvalidFormat": "Film: Geçersiz Format", @@ -290,11 +290,11 @@ "SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' alt klasörü otomatik olarak oluşturulacak", "Sunday": "Pazar", "Table": "Tablo", - "TableOptions": "Masa Seçenekleri", + "TableOptions": "Tablo Seçenekleri", "TableOptionsColumnsMessage": "Hangi sütunların görünür olduğunu ve hangi sırada görüneceklerini seçin", "TagIsNotUsedAndCanBeDeleted": "Etiket kullanılmaz ve silinebilir", "TestAll": "Tümünü Test Et", - "TheLogLevelDefault": "Günlük düzeyi varsayılan olarak 'Bilgi' şeklindedir ve [Genel Ayarlar](/settings/general) bölümünden değiştirilebilir", + "TheLogLevelDefault": "Log seviyesi varsayılan olarak 'Bilgi' şeklindedir ve [Genel Ayarlar](/ayarlar/genel) bölümünden değiştirilebilir", "ThisCannotBeCancelled": "Bu, {appName} yeniden başlatılmadan başlatıldıktan sonra iptal edilemez.", "Title": "Başlık", "TMDBId": "TMDb Kimliği", @@ -313,7 +313,7 @@ "BrowserReloadRequired": "Tarayıcının Yeniden Yüklenmesi Gerekiyor", "UiSettings": "Arayüz Ayarları", "AddConditionError": "Yeni bir koşul eklenemiyor, lütfen tekrar deneyin.", - "AddCustomFormatError": "Yeni bir özel biçim eklenemiyor, lütfen tekrar deneyin.", + "AddCustomFormatError": "Yeni bir özel format eklenemiyor, lütfen tekrar deneyin.", "AddDownloadClientError": "Yeni bir indirme istemcisi eklenemiyor, lütfen tekrar deneyin.", "AddIndexerError": "Yeni dizinleyici eklenemiyor, lütfen tekrar deneyin.", "AddListError": "Yeni bir liste eklenemiyor, lütfen tekrar deneyin.", @@ -347,7 +347,7 @@ "UnsavedChanges": "Kaydedilmemiş Değişiklikler", "UpdateMechanismHelpText": "{appName}'ın yerleşik güncelleyicisini veya bir komut dosyasını kullanın", "UpdateScriptPathHelpText": "Çıkarılan bir güncelleme paketini alan ve güncelleme işleminin geri kalanını işleyen özel bir komut dosyasına giden yol", - "UpgradeUntilCustomFormatScore": "Özel Biçim Puanına Kadar Yükseltme", + "UpgradeUntilCustomFormatScore": "Özel Format Puanına Kadar Yükseltme", "UpgradeUntil": "Kaliteye Kadar Yükseltme", "UpgradeUntilThisQualityIsMetOrExceeded": "Bu kalite karşılanana veya aşılana kadar yükseltin", "UrlBaseHelpText": "Ters proxy desteği için varsayılan boştur", @@ -367,7 +367,7 @@ "YesCancel": "Evet İptal", "YesMoveFiles": "Evet, Dosyaları Taşı", "Yesterday": "Dün", - "YouCanAlsoSearch": "Filmin TMDb kimliğini veya IMDb kimliğini kullanarak da arama yapabilirsiniz. Örneğin. \"tmdb: 71663\"", + "YouCanAlsoSearch": "Filmin TMDb kimliğini veya IMDb kimliğini kullanarak da arama yapabilirsiniz. Örneğin. \"tmdb: 50737\"", "MaintenanceRelease": "Bakım Sürümü: hata düzeltmeleri ve diğer iyileştirmeler. Daha fazla ayrıntı için Github İşlem Geçmişine bakın", "MovieDetailsPreviousMovie": "Film Detayları: Önceki Film", "MovieExcludedFromAutomaticAdd": "Otomatik Eklemeden Hariç Tutulan Film", @@ -382,12 +382,12 @@ "AlternativeTitle": "Alternatif Başlık", "Always": "Her zaman", "AptUpdater": "Güncellemeyi yüklemek için apt'ı kullanın", - "CancelProcessing": "İşlemeyi İptal Et", + "CancelProcessing": "İşlemi İptal Et", "CantFindMovie": "Filmimi neden bulamıyorum?", "CertValidationNoLocal": "Yerel Adresler için Devre Dışı Bırak", - "ChmodFolderHelpTextWarning": "Bu, yalnızca {appName}'ı çalıştıran kullanıcı dosyanın sahibi ise çalışır. İndirme istemcisinin izinleri doğru şekilde ayarladığından emin olmak daha iyidir.", + "ChmodFolderHelpTextWarning": "Bu yalnızca {appName} uygulamasını çalıştıran kullanıcı, dosyanın sahibiyse işe yarar. İndirme istemci izinlerinin doğruluğundan emin olmak önerilir.", "ChownGroupHelpText": "Grup adı veya gid. Uzak dosya sistemleri için gid kullanın.", - "ChownGroupHelpTextWarning": "Bu, yalnızca {appName}'ı çalıştıran kullanıcı dosyanın sahibi ise çalışır. İndirme istemcisinin {appName} ile aynı grubu kullanmasını sağlamak daha iyidir.", + "ChownGroupHelpTextWarning": "Bu yalnızca {appName} uygulamasını çalıştıran kullanıcı, dosyanın sahibiyse işe yarar. İndirme istemcisinin {appName} ile aynı grubu kullandığından emin olmak önerilir.", "DeleteMovieFilesHelpText": "Film dosyalarını ve film klasörünü silin", "DeleteMovieFiles": "{movieFileCount} Film Dosyasını Sil", "DeleteHeader": "Sil - {0}", @@ -407,10 +407,10 @@ "QualityProfileInUseMovieListCollection": "Bir filme eklenmiş kaliteli bir profili silemezsiniz", "QueueIsEmpty": "Kuyruk boş", "CalendarFeed": "{appName} Takvim Beslemesi", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Propers / Repacks üzerinden özel format puanına göre sıralamak için \"Tercih Etme\" seçeneğini kullanın", + "DownloadPropersAndRepacksHelpTextCustomFormat": "Uygunluk ve Yeniden Paketlemeler üzerinden özel format puanına göre sıralamak için \"Tercih Etme\" seçeneğini kullanın", "Tomorrow": "Yarın", "DotNetVersion": ".NET", - "NoHistory": "Geçmiş yok", + "NoHistory": "Geçmiş bulunamadı", "AddQualityProfile": "Kalite Profili Ekle", "NoBackupsAreAvailable": "Kullanılabilir yedek yok", "AddRootFolder": "Kök Klasör Ekle", @@ -420,11 +420,11 @@ "AcceptConfirmationModal": "Onay Modunu Kabul Et", "AddIndexer": "Dizinleyici Ekle", "AllResultsHiddenFilter": "Tüm sonuçlar, uygulanan filtre tarafından gizlenir", - "AnalyseVideoFiles": "Video dosyalarını analiz edin", + "AnalyseVideoFiles": "Video Dosyalarını Analiz Et", "AppDataDirectory": "Uygulama Veri Dizini", - "CustomFormatUnknownCondition": "Bilinmeyen Özel Biçim koşulu '{implementation}'", + "CustomFormatUnknownCondition": "Bilinmeyen Özel Format koşulu '{implementation}'", "AuthBasic": "Temel (Tarayıcı Açılır Penceresi)", - "AuthForm": "Formlar (Giriş Sayfası)", + "AuthForm": "Form (Giriş Sayfası)", "Branch": "Şube", "BuiltIn": "Dahili", "CalendarOptions": "Takvim Seçenekleri", @@ -474,13 +474,13 @@ "None": "Yok", "NoResultsFound": "Sonuç bulunamadı", "MovieFilesTotaling": "Film Dosyaları Toplamı", - "OnGrab": "Yakalandığında", + "OnGrab": "Alındığında", "OnlyUsenet": "Sadece Usenet", "PendingChangesMessage": "Kaydedilmemiş değişiklikleriniz var, bu sayfadan ayrılmak istediğinizden emin misiniz?", "ProxyType": "Proxy Türü", - "RegularExpressionsCanBeTested": "Normal ifadeler [burada](http://regexstorm.net/tester) test edilebilir.", + "RegularExpressionsCanBeTested": "Düzenli ifadeler [burada]({url}) test edilebilir.", "ShowGenres": "Türleri Göster", - "UpgradesAllowed": "Yükseltmelere İzin Verildi", + "UpgradesAllowed": "Yükseltmelere İzin Ver", "Pending": "Bekliyor", "EnableSsl": "SSL'yi etkinleştir", "Indexer": "Dizinleyici", @@ -489,7 +489,7 @@ "LoadingMovieExtraFilesFailed": "İlave film dosyaları yüklenemedi", "Manual": "Manuel", "ManualImport": "Manuel İçe Aktar", - "Mechanism": "İşleyiş", + "Mechanism": "Teknik", "MediaInfo": "Medya bilgisi", "Hostname": "Hostname", "MinutesSixty": "60 Dakika: {sixty}", @@ -505,43 +505,43 @@ "AddImportListExclusion": "İçe Aktarma Listesi Hariç Tutma Ekle", "ApiKey": "API Anahtarı", "NamingSettings": "Adlandırma Ayarları", - "NoLogFiles": "Günlük dosyası yok", + "NoLogFiles": "Log kayıt dosyası henüz yok", "NoMatchFound": "Eşleşme bulunamadı!", "NotMonitored": "Takip Edilmeyen", - "MinimumAge": "Asgari yaş", + "MinimumAge": "Minimum Geçen Süre", "NoUpdatesAreAvailable": "Güncelleme yok", "AddingTag": "Etiket ekleniyor", "Age": "Yıl", - "AgeWhenGrabbed": "Yıl (yakalandığında)", + "AgeWhenGrabbed": "Yıl (alındığında)", "AnalyticsEnabledHelpText": "Anonim kullanım ve hata bilgilerini {appName} sunucularına gönderin. Buna, tarayıcınız, hangi {appName} WebUI sayfalarını kullandığınız, hata raporlamanın yanı sıra işletim sistemi ve çalışma zamanı sürümü hakkındaki bilgiler de dahildir. Bu bilgiyi özelliklere ve hata düzeltmelerine öncelik vermek için kullanacağız.", "Apply": "Uygula", "ICalShowAsAllDayEventsHelpText": "Etkinlikler, takviminizde tüm gün süren etkinlikler olarak görünecek", "Authentication": "Doğrulama", "ApplyTags": "Etiketleri Uygula", - "AuthenticationMethodHelpText": "{appName}'a erişmek için Kullanıcı Adı ve Şifre gerektir", + "AuthenticationMethodHelpText": "{appName}'e erişmek için Kullanıcı Adı ve Parola gereklidir", "Automatic": "Otomatik", "AutoRedownloadFailedHelpText": "Otomatik olarak farklı bir Yayın arayın ve indirmeye çalışın", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Diskten silinen filmler otomatik olarak {appName}'da takip edilmez", "AvailabilityDelay": "Kullanılabilirlik Gecikmesi", "AvailabilityDelayHelpText": "Film aramak için mevcut tarihten önceki veya sonraki zaman miktarı", "BackupIntervalHelpText": "Otomatik yedeklemeler arasındaki zaman aralığı", - "BackupNow": "Şimdi yedekle", - "BackupRetentionHelpText": "Saklama süresinden daha eski olan otomatik yedeklemeler otomatik olarak temizlenecektir", + "BackupNow": "Şimdi Yedekle", + "BackupRetentionHelpText": "Saklama süresinden daha eski otomatik yedeklemeler otomatik olarak temizlenecektir", "Backups": "Yedeklemeler", "BeforeUpdate": "Güncellemeden önce", "BindAddress": "Bind Adresi", "BindAddressHelpText": "Tüm arayüzler için geçerli IP adresi, localhost veya '*'", - "CertificateValidation": "Sertifika Doğrulama", + "CertificateValidation": "Sertifika Doğrulaması", "CertificateValidationHelpText": "HTTPS sertifika doğrulamasının sıkılığını değiştirin. Riskleri anlamadığınız sürece değişmeyin.", - "Certification": "Sertifikasyon", - "BranchUpdate": "{appName}'ı güncellemek için kullanılacak dal", - "BranchUpdateMechanism": "Harici güncelleme mekanizması tarafından kullanılan dal", - "BypassProxyForLocalAddresses": "Yerel Adresler için Proxy'yi Atla", + "Certification": "Sertifika", + "BranchUpdate": "{appName} uygulamasını güncellemek için kullanılacak şube", + "BranchUpdateMechanism": "Harici güncelleme mekanizması tarafından kullanılan şube", + "BypassProxyForLocalAddresses": "Yerel Adresler için Proxy'yi Kullanma", "ChangeFileDate": "Dosya Tarihini Değiştir", "ChangeHasNotBeenSavedYet": "Değişiklik henüz kaydedilmedi", "CheckDownloadClientForDetails": "daha fazla ayrıntı için indirme istemcisini kontrol edin", "CheckForFinishedDownloadsInterval": "Tamamlanan İndirmeler Aralığını Kontrol Et", - "CleanLibraryLevel": "Kitaplık Düzeyini Temizle", + "CleanLibraryLevel": "Kütüphane Seviyesini Temizle", "ClientPriority": "Müşteri Önceliği", "CertificationCountry": "Sertifikasyon Ülkesi", "CertificationCountryHelpText": "Film Sertifikaları için Ülke Seçin", @@ -555,9 +555,9 @@ "Edition": "Baskı", "EnableCompletedDownloadHandlingHelpText": "Tamamlanan indirmeleri indirme istemcisinden otomatik olarak içe aktarın", "ListEnabledHelpText": "Bu listeyi {appName}'da kullanmak üzere etkinleştirin", - "Ended": "Bitti", - "Events": "Etkinlikler", - "IncludeCustomFormatWhenRenamingHelpText": "{Custom Formats} yeniden adlandırma formatına dahil et", + "Ended": "Biten", + "Events": "Olaylar", + "IncludeCustomFormatWhenRenamingHelpText": "Özel formatları yeniden adlandırma formatına dahil et", "Overview": "Genel Bakış", "OverviewOptions": "Genel Bakış Seçenekler", "MinimumFreeSpace": "Minimum Boş Alan", @@ -572,12 +572,12 @@ "MovieTitleToExcludeHelpText": "Hariç tutulacak filmin başlığı (anlamlı herhangi bir şey olabilir)", "MovieYear": "Film Yılı", "MovieYearToExcludeHelpText": "Hariç tutulacak film yılı", - "PendingChangesDiscardChanges": "Değişiklikleri atın ve ayrıl", + "PendingChangesDiscardChanges": "Değişiklikleri at ve ayrıl", "PreferredSize": "Tercih Edilen Boyut", "Proper": "Uygun", "PtpOldSettingsCheckMessage": "Aşağıdaki PassThePopcorn dizinleyicilerinin ayarları kullanımdan kaldırıldı ve güncellenmeleri gerekiyor: {0}", "Queued": "Kuyruğa alındı", - "RecyclingBinCleanup": "Geri Dönüşüm Kutusu Temizleme", + "RecyclingBinCleanup": "Geri Dönüşüm Kutusu Temizle", "RefreshMovie": "Filmi yenile", "RejectionCount": "Reddetme Sayısı", "RelativePath": "Göreceli yol", @@ -595,7 +595,7 @@ "AudioInfo": "Ses Bilgisi", "Cancel": "Vazgeç", "PhysicalRelease": "Fiziksel Salınım", - "Port": "Liman", + "Port": "Port No", "Close": "Kapat", "PortNumber": "Port numarası", "ProtocolHelpText": "Hangi protokol (ler) in kullanılacağını ve başka türlü eşit sürümler arasında seçim yaparken hangisinin tercih edileceğini seçin", @@ -607,7 +607,7 @@ "SupportedListsMovie": "{appName}, aşağıda belirtilenlerin yanı sıra tüm RSS film listelerini destekler.", "AlreadyInYourLibrary": "Kütüphanenizde mevcut", "RecyclingBinHelpText": "Film dosyaları, kalıcı olarak silinmek yerine silindiğinde buraya gider", - "RequiredHelpText": "Özel biçimin uygulanabilmesi için bu {implementationName} koşulunun eşleşmesi gerekir. Aksi takdirde tek bir {implementationName} eşleşmesi yeterlidir.", + "RequiredHelpText": "Özel formatın uygulanabilmesi için bu {implementationName} koşulunun eşleşmesi gerekir. Aksi takdirde tek bir {implementationName} eşleşmesi yeterlidir.", "AddNewRestriction": "Yeni kısıtlama ekle", "RestartRequiredHelpTextWarning": "Etkili olması için yeniden başlatma gerektirir", "Restore": "Onarmak", @@ -625,12 +625,12 @@ "Backup": "Yedekler", "Username": "Kullanıcı adı", "WaitingToImport": "İçe Aktarma Bekleniyor", - "BackupFolderHelpText": "Göreli yollar {appName}'ın AppData dizini altında olacaktır", + "BackupFolderHelpText": "Bağıl yollar {appName}'ın AppData dizini altında olacak", "Disabled": "Devre dışı", - "Peers": "Akranlar", + "Peers": "Eşler", "UiSettingsLoadError": "Arayüz ayarları yüklenemiyor", "Unavailable": "Kullanım dışı", - "Importing": "İçe aktarılıyor", + "Importing": "İçe Aktarma", "NoLeaveIt": "Hayır, Bırak", "NotAvailable": "Müsait değil", "NotificationTriggers": "Bildirim Tetikleyicileri", @@ -652,11 +652,11 @@ "CouldNotFindResults": "'{term}' için herhangi bir sonuç bulunamadı", "CreateEmptyMovieFolders": "Boş film klasörleri oluşturun", "CreateGroup": "Grup oluştur", - "CurrentlyInstalled": "Şu anda Yüklü", + "CurrentlyInstalled": "Şuan Kurulu", "Custom": "Özel", "CustomFormat": "Özel Format", "CustomFormatHelpText": "{appName}, özel formatlarla eşleşen puanların toplamını kullanarak her yayını puanlar. Yeni bir yayının, puanı aynı veya daha iyi kalitede iyileştirecekse, {appName} onu alacaktır.", - "CustomFormatScore": "Özel Biçim Puanı", + "CustomFormatScore": "Özel Format Puanı", "CustomFormatsSettings": "Özel Format Ayarları", "CustomFormatUnknownConditionOption": "'{implementation}' koşulu için bilinmeyen seçenek '{key}'", "Cutoff": "Kesinti", @@ -684,21 +684,21 @@ "DeleteTagMessageText": "'{label}' etiketini silmek istediğinizden emin misiniz?", "DeleteMovieFolderConfirmation": "'{path}' film klasörü ve tüm içeriği silinecek.", "Discord": "Uyuşmazlık", - "Docker": "Liman işçisi", - "Donations": "Bağışlar", + "Docker": "Docker", + "Donations": "Bağış", "DoNotPrefer": "Tercih etmeme", "DoNotUpgradeAutomatically": "Otomatik Olarak Yükseltme", - "DownloadClient": "İstemciyi İndir", + "DownloadClient": "İndirme İstemcisi", "DownloadClientCheckNoneAvailableMessage": "İndirme istemcisi yok", "DownloadClients": "İndirme İstemcileri", - "DownloadClientSettings": "İstemci Ayarlarını İndir", + "DownloadClientSettings": "İndirme İstemcisi Ayarlarını", "DownloadClientsSettingsSummary": "İndirme İstemcileri, indirme işlemleri ve uzaktan yol eşlemeleri", "DownloadClientStatusCheckSingleClientMessage": "Hatalar nedeniyle indirilemeyen istemciler: {downloadClientNames}", "DownloadedAndMonitored": "İndirildi (Takip Ediliyor)", "DownloadedButNotMonitored": "İndirildi (Takip Edilmiyor)", "DownloadFailed": "Yükleme başarısız", "Downloading": "İndiriliyor", - "DownloadPropersAndRepacks": "Propers ve Repacks", + "DownloadPropersAndRepacks": "Uygunluj ve Yeniden Paketlemeler", "DownloadPropersAndRepacksHelpText": "Propers / Repacks'e otomatik olarak yükseltme yapılıp yapılmayacağı", "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks'e otomatik yükseltmeler için özel formatlar kullanın", "DownloadWarning": "Uyarıyı indir: {warningMessage}", @@ -734,11 +734,11 @@ "FailedLoadingSearchResults": "Arama sonuçları yüklenemedi, lütfen tekrar deneyin.", "FailedToLoadMovieFromAPI": "API'den film yüklenemedi", "FeatureRequests": "Özellik talepleri", - "ChangeFileDateHelpText": "İçe aktarmada / yeniden taramada dosya tarihini değiştirin", + "ChangeFileDateHelpText": "İçe aktarma/yeniden tarama sırasında dosya tarihini değiştir", "FileNames": "Dosya Adları", "FilterPlaceHolder": "Film ara", "FirstDayOfWeek": "Haftanın ilk günü", - "Fixed": "Sabit", + "Fixed": "Düzeltilen", "FolderMoveRenameWarning": "Bu aynı zamanda ayarlarda film klasörü formatına göre film klasörünü yeniden adlandıracaktır.", "SupportedDownloadClientsMoreInfo": "Bireysel indirme istemcileri hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", "SupportedListsMoreInfo": "Ayrı ayrı içe aktarma listeleri hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", @@ -747,8 +747,8 @@ "Genres": "Türler", "Global": "Küresel", "GoToInterp": "{0} adresine gidin", - "Grabbed": "Yakalandı", - "GrabRelease": "Yayın Yakalama", + "Grabbed": "Alındı", + "GrabRelease": "Yayın Alma", "Group": "Grup", "HardlinkCopyFiles": "Hardlink / Dosyaları Kopyala", "NoIssuesWithYourConfiguration": "Yapılandırmanızla ilgili sorun yok", @@ -761,7 +761,7 @@ "Images": "Görüntüler", "IMDb": "IMDb", "Import": "İçe aktar", - "ImportCustomFormat": "Özel Biçimi İçe Aktar", + "ImportCustomFormat": "Özel Formatı İçe Aktar", "ImportedTo": "İçeri Aktarıldı", "ImportRootPath": "{appName}'ı belirli bir filmi değil, tüm filmlerinizi içeren klasöre yöneltin. Örneğin. {1} değil {0}. Ek olarak, her film kök / kitaplık klasöründe kendi klasöründe olmalıdır.", "InCinemasDate": "Vizyon Tarihi", @@ -771,11 +771,11 @@ "IncludeUnmonitored": "Takip Edilmeyenleri Dahil Et", "ImportMovies": "Filmleri İçe Aktar", "IndexerPriorityHelpText": "Dizinleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek", - "IndexerRssHealthCheckNoAvailableIndexers": "Son indeksleyici hataları nedeniyle tüm rss özellikli indeksleyiciler geçici olarak kullanılamıyor", + "IndexerRssHealthCheckNoAvailableIndexers": "Son zamanlardaki dizinleyici hataları nedeniyle tüm rss uyumlu dizinleyiciler geçici olarak kullanılamıyor", "IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonunun etkin olduğu dizinleyici yok, {appName} yeni yayınlar otomatik olarak almayacak", "Indexers": "Dizinleyiciler", - "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinken indeksleyici yok, {appName} herhangi bir otomatik arama sonucu sağlamayacak", - "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirilmiş fakat dizinleyici mevcut değil; {appName} herhangi bir etkileşimli arama sonucu sağlayamayacaktır", + "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır", + "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır", "IndexerSettings": "Dizinleyici Ayarları", "IndexerStatusCheckSingleClientMessage": "Hatalar nedeniyle dizinleyiciler kullanılamıyor: {indexerNames}", "InteractiveImport": "Etkileşimli İçe Aktarma", @@ -790,26 +790,26 @@ "Links": "Bağlantılar", "ImportListSettings": "Liste Ayarları", "ListSyncLevelHelpText": "Kitaplıktaki filmlerin listenizde/listelerinizde görünmemesi durumunda seçiminize göre işlem yapılacaktır", - "LogLevel": "Günlük Düzeyi", - "LogLevelTraceHelpTextWarning": "İzleme günlük kaydı yalnızca geçici olarak etkinleştirilmelidir", + "LogLevel": "Log Seviyesi", + "LogLevelTraceHelpTextWarning": "İzleme kaydı yalnızca geçici olarak etkinleştirilmelidir", "LogOnly": "Sadece hesap aç", - "Logs": "Kütükler", + "Logs": "Kayıtlar", "LookingForReleaseProfiles1": "Yayımlama Profilleri mi arıyorsunuz? Deneyin", "LookingForReleaseProfiles2": "yerine.", "Lowercase": "Küçük Harf", "ManualImportSelectLanguage": "Manuel İçe Aktar - Dil Seçin", "ManualImportSelectMovie": "Manuel İçe Aktar - Film Seçin", "ManualImportSelectQuality": " Manuel İçe Aktar - Kaliteyi Seçin", - "MappedNetworkDrivesWindowsService": "Eşlenen ağ sürücüleri, bir Windows Hizmeti olarak çalışırken kullanılamaz. Daha fazla bilgi için lütfen SSS bölümüne bakın", + "MappedNetworkDrivesWindowsService": "Windows Hizmeti olarak çalıştırıldığında eşlenen ağ sürücüleri kullanılamaz, daha fazla bilgi için [SSS]({url}) bölümüne bakın.", "MarkAsFailedMessageText": "'{0}' başarısız olarak işaretlemek istediğinizden emin misiniz?", "MaximumLimits": "Maksimum Sınırlar", - "MaximumSize": "En büyük boy", + "MaximumSize": "Maksimum Boyut", "MegabytesPerMinute": "Dakika Başına Megabayt", - "Message": "İleti", + "Message": "Mesaj", "MetadataSettings": "Meta Veri Ayarları", "MIA": "MIA", "Min": "Min", - "MinimumAgeHelpText": "Yalnızca Usenet: NZB'lerin alınmadan önceki dakika cinsinden minimum yaşı. Yeni yayınların usenet sağlayıcınıza yayılması için zaman tanımak için bunu kullanın.", + "MinimumAgeHelpText": "Yalnızca Usenet: NZB'lerin almadan önceki minimum geçen süre (dakika cinsinden). Bunu, yeni sürümlerin usenet sağlayıcınıza yayılması için zaman vermek amacıyla kullanın.", "MinimumAvailability": "Minimum Kullanılabilirlik", "MinimumCustomFormatScore": "Minimum Özel Format Puanı", "MinimumFreeSpaceHelpText": "Bu miktardan daha az kullanılabilir disk alanı bırakacaksa içe aktarmayı önleyin", @@ -874,7 +874,7 @@ "RemovingTag": "Etiket kaldırılıyor", "RenameMovies": "Filmleri Yeniden Adlandır", "RenameMoviesHelpText": "Yeniden adlandırma devre dışı bırakılırsa, {appName} mevcut dosya adını kullanacaktır", - "ReplaceIllegalCharacters": "Yasadışı Karakterleri Değiştirin", + "ReplaceIllegalCharacters": "Geçersiz Karakterleri Değiştirin", "ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse bunun yerine {appName} bunları kaldıracak", "ReplaceWithSpaceDash": "Space Dash ile değiştirin", "Required": "Gerekli", @@ -894,7 +894,7 @@ "Save": "Kaydet", "SaveSettings": "Ayarları kaydet", "Score": "Puan", - "Script": "Hazır Metin", + "Script": "Komut Dosyası", "ScriptPath": "Komut Dosyası Yolu", "SearchCutoffUnmet": "Arama Kesintisi Karşılanmadı", "SearchForMovie": "Film ara", @@ -925,7 +925,7 @@ "StartProcessing": "İşlemeye Başla", "TagDetails": "Etiket Ayrıntıları - {label}", "ICalTagsMoviesHelpText": "En az bir eşleşen etikete sahip filmler için geçerlidir", - "Test": "Sına", + "Test": "Test Et", "Time": "Zaman", "Trigger": "Tetik", "UiLanguage": "Arayüz Dili", @@ -955,7 +955,7 @@ "More": "Daha", "Download": "İndir", "DownloadClientRootFolderHealthCheckMessage": "İndirme istemcisi {downloadClientName}, indirmeleri kök klasöre yerleştirir {rootFolderPath}. Bir kök klasöre indirmemelisiniz.", - "Blocklist": "Kara liste", + "Blocklist": "Engellenenler listesi", "BlocklistRelease": "Kara Liste Sürümü", "RemoveFromBlocklist": "Kara listeden kaldır", "Blocklisted": "Kara liste", @@ -964,7 +964,7 @@ "Filters": "Filtreler", "Rating": "Puan", "SelectLanguages": "Dil Seçin", - "RssSyncIntervalHelpText": "Dakika cinsinden periyot. Devre dışı bırakmak için sıfıra ayarlayın (tüm otomatik yayın yakalamayı durduracaktır)", + "RssSyncIntervalHelpText": "Dakika cinsinden aralık. Devre dışı bırakmak için sıfıra ayarlayın (tüm otomatik yayın almayı durduracaktır)", "AllCollectionsHiddenDueToFilter": "Uygulanan filtre nedeniyle tüm koleksiyonlar gizlendi.", "Collections": "Koleksiyon", "MonitorMovies": "Film Takip Edilebilirliği", @@ -978,7 +978,7 @@ "AddCondition": "Koşul Ekle", "AddConditionImplementation": "Koşul Ekle - {implementationName}", "AddConnection": "Bağlantı Ekle", - "AddIndexerImplementation": "Yeni Dizin Ekle - {implementationName}", + "AddIndexerImplementation": "Yeni Dizinleyici Ekle - {implementationName}", "AddConnectionImplementation": "Bağlantı Ekle - {implementationName}", "EditIndexerImplementation": "Koşul Ekle - {implementationName}", "AllTitles": "Tüm Başlıklar", @@ -995,7 +995,7 @@ "AutomaticUpdatesDisabledDocker": "Docker güncelleme mekanizması kullanıldığında otomatik güncellemeler doğrudan desteklenmez. Konteyner görüntüsünü {appName} dışında güncellemeniz veya bir komut dosyası kullanmanız gerekecek", "BypassDelayIfHighestQuality": "En Yüksek Kalitedeyse Atla", "AppUpdated": "{appName} Güncellendi", - "AppUpdatedVersion": "{appName}, `{version}` sürümüne güncellendi; en son değişikliklerin etkin olabilmesi için {appName} uygulamasını yeniden başlatmanız gerekli", + "AppUpdatedVersion": "{appName}, `{version}` sürümüne güncellendi; değişikliklerin etkin olabilmesi için {appName} uygulamasını yeniden başlatmanız gerekli", "ApplyTagsHelpTextHowToApplyIndexers": "Seçilen indeksleyicilere etiketler nasıl uygulanır", "ApplyTagsHelpTextHowToApplyMovies": "Seçilen filmlere etiketler nasıl uygulanır", "ApplyTagsHelpTextRemove": "Kaldır: Girilen etiketleri kaldırın", @@ -1081,13 +1081,13 @@ "DeletedReasonUpgrade": "Bir yükseltmeyi içe aktarmak için dosya silindi", "AutoTaggingSpecificationTag": "Etiket", "CustomFormatsSettingsTriggerInfo": "Bir yayına veya dosyaya, seçilen farklı koşul türlerinden en az biriyle eşleştiğinde Özel Format uygulanacaktır.", - "CutoffNotMet": "Kesinti Noktasına Ulaşılmadı", + "CutoffNotMet": "Kesinti Karşılanmadı", "Default": "Varsayılan", "Dash": "Çizgi", "DefaultNameCopiedSpecification": "{name} - Kopyala", "DeleteAutoTag": "Etiketi Otomatik Sil", "DeleteCondition": "Koşulu Sil", - "Directory": "Rehber", + "Directory": "Dizin", "Donate": "Bağış yap", "DeleteImportListExclusionMessageText": "Bu içe aktarma listesi hariç tutma işlemini silmek istediğinizden emin misiniz?", "DoNotBlocklist": "Engelleme Listesine Eklemeyin", @@ -1105,7 +1105,7 @@ "DownloadClientFreeboxApiError": "Freebox API'si şu hatayı döndürdü: {errorDescription}", "DownloadClientFreeboxSettingsPortHelpText": "Freebox arayüzüne erişim için kullanılan bağlantı noktası, varsayılan olarak '{port}' şeklindedir", "DeleteAutoTagHelpText": "'{name}' etiketini otomatik silmek istediğinizden emin misiniz?", - "DeleteCustomFormatMessageText": "'{name}' özel biçimini silmek istediğinizden emin misiniz?", + "DeleteCustomFormatMessageText": "'{name}' özel formatı silmek istediğinizden emin misiniz?", "DeleteImportList": "İçe Aktarma Listesini Sil", "DeleteRootFolder": "Kök Klasörü Sil", "DeleteSelectedIndexers": "Dizinleyicileri Sil", @@ -1152,7 +1152,7 @@ "DownloadClientFreeboxSettingsAppId": "Uygulama kimliği", "DownloadClientFreeboxSettingsApiUrl": "API URL'si", "DownloadClientFreeboxSettingsAppToken": "Uygulama Jetonu", - "DownloadClientFreeboxSettingsHostHelpText": "Freebox'un ana bilgisayar adı veya ana bilgisayar IP adresi, varsayılan olarak '{url}' şeklindedir (yalnızca aynı ağdaysa çalışır)", + "DownloadClientFreeboxSettingsHostHelpText": "Freebox'un istemci adı veya istemci IP adresi, varsayılan olarak '{url}' şeklindedir (yalnızca aynı ağda çalışır)", "DownloadClientFreeboxAuthenticationError": "Freebox API'sinde kimlik doğrulama başarısız oldu. Sebep: {errorDescription}", "DownloadClientFreeboxNotLoggedIn": "Giriş yapmadınız", "DownloadClientFreeboxSettingsApiUrlHelpText": "Freebox API temel URL'sini API sürümüyle tanımlayın, örneğin '{url}', varsayılan olarak '{defaultApiUrl}' olur", @@ -1170,7 +1170,7 @@ "DownloadClientSettingsCategoryHelpText": "{appName}'e özel bir kategori eklemek, {appName} dışındaki ilgisiz indirmelerle çakışmaları önler. Kategori kullanmak isteğe bağlıdır ancak önemle tavsiye edilir.", "DownloadClientSettingsCategorySubFolderHelpText": "{appName}'e özel bir kategori eklemek, {appName} dışındaki ilgisiz indirmelerle çakışmaları önler. Kategori kullanmak isteğe bağlıdır ancak önemle tavsiye edilir. Çıkış dizininde bir [kategori] alt dizini oluşturur.", "DownloadClientSettingsDestinationHelpText": "İndirme hedefini manuel olarak belirtir, varsayılanı kullanmak için boş bırakın", - "DownloadClientSettingsRecentPriority": "Yeni Öncelik", + "DownloadClientSettingsRecentPriority": "Yeni Önceliği", "DownloadClientSettingsUseSslHelpText": "{clientName} ile bağlantı kurulurken güvenli bağlantıyı kullan", "DownloadClientUTorrentTorrentStateError": "uTorrent bir hata bildirdi", "DownloadClientValidationVerifySsl": "SSL Doğrulama ayarı", @@ -1181,7 +1181,7 @@ "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "NzbGet KeepHistory ayarı çok yüksek ayarlanmış.", "DownloadClientPneumaticSettingsNzbFolder": "Nzb Klasörü", "DownloadClientPneumaticSettingsStrmFolderHelpText": "Bu klasördeki .strm dosyaları drone ile içe aktarılacak", - "DownloadClientQbittorrentSettingsFirstAndLastFirst": "İlk ve Son İlk", + "DownloadClientQbittorrentSettingsFirstAndLastFirst": "İlk ve Son", "DownloadClientQbittorrentSettingsInitialStateHelpText": "Torrentlerin başlangıç durumu qBittorrent'e eklendi. Zorunlu Torrentlerin seed kısıtlamalarına uymadığını unutmayın", "DownloadClientQbittorrentSettingsSequentialOrder": "Sıralı Sıra", "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Sıralı olarak indirin (qBittorrent 4.1.0+)", @@ -1194,7 +1194,7 @@ "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "Torrent Kuyruğa Alma, qBittorrent ayarlarınızda etkin değil. qBittorrent'te etkinleştirin veya öncelik olarak 'Son'u seçin.", "DownloadClientQbittorrentValidationQueueingNotEnabled": "kuyruğa Alma Etkin Değil", "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent, Torrentleri Paylaşım Oranı Sınırına ulaştıklarında kaldıracak şekilde yapılandırılmıştır", - "DownloadClientRTorrentSettingsAddStopped": "Ekleme Durduruldu", + "DownloadClientRTorrentSettingsAddStopped": "Durdurulana Ekle", "DownloadClientRTorrentSettingsUrlPathHelpText": "XMLRPC uç noktasının yolu, bkz. {url}. RuTorrent kullanılırken bu genellikle RPC2 veya [ruTorrent yolu]{url2} olur.", "DownloadClientRTorrentSettingsUrlPath": "URL Yolu", "DownloadClientSabnzbdValidationCheckBeforeDownload": "Sabnbzd'de 'İndirmeden önce kontrol et' seçeneğini devre dışı bırakın", @@ -1203,7 +1203,7 @@ "DownloadClientSabnzbdValidationEnableDisableTvSorting": "TV Sıralamasını Devre Dışı Bırak", "DownloadClientSabnzbdValidationEnableJobFolders": "İş klasörlerini etkinleştir", "DownloadClientSabnzbdValidationUnknownVersion": "Bilinmeyen Sürüm: {rawVersion}", - "DownloadClientSettingsAddPaused": "Ekleme Durduruldu", + "DownloadClientSettingsAddPaused": "Duraklatılana Ekle", "DownloadClientSettingsInitialState": "Başlangıç Durumu", "DownloadClientSettingsInitialStateHelpText": "{clientName} dosyasına eklenen torrentler için başlangıç durumu", "DownloadClientSettingsOlderPriority": "Eski Önceliği", @@ -1301,7 +1301,7 @@ "ManageClients": "İstemcileri Yönet", "FormatRuntimeHours": "{hours}s", "IgnoreDownloadHint": "{appName}'in bu indirmeyi daha fazla işlemesini durdurur", - "LogFilesLocation": "Günlük dosyaları şu konumda bulunur: {location}", + "LogFilesLocation": "Log kayıtlarının bulunduğu konum: {location}", "ManageIndexers": "Dizinleyicileri Yönet", "MovieFileDeletedTooltip": "Film dosyası silindi", "NotificationsCustomScriptSettingsArgumentsHelpText": "Komut dosyasına aktarılacak argümanlar", @@ -1330,20 +1330,20 @@ "FullColorEventsHelpText": "Etkinliğin tamamını yalnızca sol kenar yerine durum rengiyle renklendirecek şekilde stil değiştirildi. Gündem için geçerli değildir", "IMDbId": "IMDb Id", "EnableProfile": "Profili Etkinleştir", - "IndexerDownloadClientHelpText": "Bu dizinleyiciden yakalamak için hangi indirme istemcisinin kullanılacağını belirtin", + "IndexerDownloadClientHelpText": "Bu dizinleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin", "InstanceNameHelpText": "Sekmedeki örnek adı ve Syslog uygulaması adı için", "InstanceName": "Örnek isim", "InteractiveImportNoFilesFound": "Seçilen klasörde video dosyası bulunamadı", "InteractiveImportNoQuality": "Seçilen her dosya için kalite seçilmelidir", "InvalidUILanguage": "Kullanıcı arayüzünüz geçersiz bir dile ayarlanmış, düzeltin ve ayarlarınızı kaydedin", - "ManualGrab": "Manuel Yakalama", + "ManualGrab": "Manuel Alımlarda", "IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip dizinleyiciler: {indexerNames}.", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Film koleksiyonu için eksik kök klasör: {rootFolderInfo}", "NoImportListsFound": "İçe aktarma listesi bulunamadı", "MovieGrabbedTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", "NotificationStatusAllClientHealthCheckMessage": "Arızalar nedeniyle tüm bildirimler kullanılamıyor", "FormatAgeHour": "saat", - "GrabId": "ID'den Yakala", + "GrabId": "ID'den Al", "ImportListMissingRoot": "İçe aktarma listeleri için kök klasör eksik: {rootFolderInfo}", "MonitoredCollectionHelpText": "Bu koleksiyondaki filmlerin otomatik olarak kitaplığa eklenmesini sağlamak için takip edin", "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "Film koleksiyonları için birden fazla kök klasör eksik: {rootFoldersInfo}", @@ -1379,7 +1379,7 @@ "NotificationsAppriseSettingsNotificationType": "Apprise Bildirim Türü", "NotificationsAppriseSettingsTagsHelpText": "İsteğe bağlı olarak yalnızca uygun şekilde etiketlenenleri bilgilendirin.", "NotificationsDiscordSettingsAvatarHelpText": "Bu entegrasyondaki mesajlar için kullanılan avatarı değiştirin", - "NotificationsDiscordSettingsOnGrabFields": "Yakalamalarda", + "NotificationsDiscordSettingsOnGrabFields": "Alımlarda", "ImportScriptPath": "Komut Dosyası Yolunu İçe Aktar", "MovieIsPopular": "TMDb'de Popüler Film", "NotificationStatusSingleClientHealthCheckMessage": "Arızalar nedeniyle bildirimler kullanılamıyor: {notificationNames}", @@ -1392,7 +1392,7 @@ "IncludeHealthWarnings": "Sağlık Uyarılarını Dahil Et", "IgnoreDownload": "İndirmeyi Yoksay", "IgnoreDownloads": "İndirilenleri Yoksay", - "ListQualityProfileHelpText": "Kalite Profili listesi öğeleri şu şekilde eklenecektir:", + "ListQualityProfileHelpText": "Kalite Profili liste öğeleri eklenecektir", "ListRootFolderHelpText": "Kök Klasör listesi öğeleri eklenecek", "MustContainHelpText": "Yayın, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarsız)", "NewNonExcluded": "Yeni Hariç Tutulmayanlar", @@ -1405,8 +1405,8 @@ "NotificationsKodiSettingsCleanLibraryHelpText": "Güncellemeden sonra kitaplığı temizle", "NotificationsMailgunSettingsUseEuEndpointHelpText": "AB MailGun uç noktasını kullanmayı etkinleştirin", "IndexerJackettAll": "Desteklenmeyen Jackett 'hepsi' uç noktasını kullanan dizinleyiciler: {indexerNames}", - "IndexerSettingsRejectBlocklistedTorrentHashes": "Yakalarken Engellenen Torrent Karmalarını Reddet", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı dizinleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent yakalandıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.", + "IndexerSettingsRejectBlocklistedTorrentHashes": "Alırken Engellenen Torrent Karmalarını Reddet", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı dizinleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent alındıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.", "MovieFileRenamedTooltip": "Film dosyası yeniden adlandırıldı", "MovieFileRenamed": "Film Dosyası Yeniden Adlandırıldı", "NotificationsCustomScriptValidationFileDoesNotExist": "Dosya bulunmuyor", @@ -1421,8 +1421,8 @@ "NotificationsKodiSettingsDisplayTime": "Gösterim Süresi", "NotificationsMailgunSettingsSenderDomain": "Gönderen Alanı", "IndexerSettingsMultiLanguageReleaseHelpText": "Bu indeksleyicideki çoklu sürümde normalde hangi diller bulunur?", - "IndexerSettingsMultiLanguageRelease": "Çok dil", - "ListWillRefreshEveryInterval": "Liste her {refreshInterval} yenilenecektir", + "IndexerSettingsMultiLanguageRelease": "Çoklu Dil", + "ListWillRefreshEveryInterval": "Liste yenileme periyodu {refreshInterval}dır", "NotificationsNotifiarrSettingsApiKeyHelpText": "Profilinizdeki API anahtarınız", "Menu": "Menü", "MovieSearchResultsLoadError": "Bu film aramasına ilişkin sonuçlar yüklenemiyor. Daha sonra tekrar deneyin", @@ -1461,7 +1461,7 @@ "FailedToUpdateSettings": "Ayarlar güncellenemedi", "FormatShortTimeSpanSeconds": "{seconds} saniye", "ExistsInLibrary": "Kütüphanede Mevcut", - "HealthMessagesInfoBox": "Satırın sonundaki wiki bağlantısını (kitap simgesi) tıklayarak veya [günlüklerinizi]({link}) kontrol ederek bu durum kontrolü mesajlarının nedeni hakkında daha fazla bilgi bulabilirsiniz. Bu mesajları yorumlamakta zorluk yaşıyorsanız aşağıdaki bağlantılardan destek ekibimize ulaşabilirsiniz.", + "HealthMessagesInfoBox": "Satırın sonundaki wiki bağlantısını (kitap simgesi) tıklayarak veya [log kayıtlarınızı]({link}) kontrol ederek bu durum kontrolü mesajlarının nedeni hakkında daha fazla bilgi bulabilirsiniz. Bu mesajları yorumlamakta zorluk yaşıyorsanız aşağıdaki bağlantılardan destek ekibimize ulaşabilirsiniz.", "HourShorthand": "s", "ImportScriptPathHelpText": "İçe aktarma için kullanılacak komut dosyasının yolu", "ImportUsingScriptHelpText": "Bir komut dosyası kullanarak içe aktarmak için dosyaları kopyalayın (ör. kod dönüştürme için)", @@ -1473,17 +1473,17 @@ "Letterboxd": "Letterboxd", "MediaInfoFootNote": "Full/AudioLanguages/SubtitleLanguages, dosya adında yer alan dilleri filtrelemenize olanak tanıyan bir `:EN+DE` son ekini destekler. Belirli dilleri hariç tutmak için '-DE'yi kullanın. `+` (örneğin `:EN+`) eklenmesi, hariç tutulan dillere bağlı olarak `[EN]`/`[EN+--]`/`[--]` sonucunu verecektir. Örneğin `{MediaInfo Full:EN+DE}`.", "NoIndexersFound": "Dizinleyici bulunamadı", - "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Bu 'yakalandı' bildirimi için iletilen alanları değiştirin", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Bu 'alındı' bildirimi için iletilen alanları değiştirin", "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "'Manuel Etkileşimlerde' bildirimi için iletilen alanları değiştirin", "Popularity": "Popülerlik", "PopularityIndex": "Güncel Popülerlik Endeksi", "ReleaseProfilesLoadError": "Yayımlama Profilleri yüklenemiyor", - "RemotePathMappingCheckImportFailed": "{appName} filmi içe aktaramadı. Ayrıntılar için günlüklerinizi kontrol edin.", + "RemotePathMappingCheckImportFailed": "{appName} filmi içe aktaramadı. Ayrıntılar için log kayıtlarınızı kontrol edin.", "OnManualInteractionRequired": "Manuel Etkileşim Gerektiğinde", "OnHealthRestored": "Sağlığın İyileştirilmesi Hakkında", - "OrganizeNamingPattern": "Adlandırma düzeni: `{standardMovieFormat}`", + "OrganizeNamingPattern": "Adlandırma düzeni: `{episodeFormat}`", "OrganizeNothingToRename": "Başarılı! İşim bitti, yeniden adlandırılacak dosya yok.", - "OverrideGrabModalTitle": "Geçersiz Kıl ve Yakala - {title}", + "OverrideGrabModalTitle": "Geçersiz Kıl ve Al - {title}", "QueueLoadError": "Kuyruk yüklenemedi", "RefreshMonitoredIntervalHelpText": "İndirme istemcilerinden takip edilen indirmelerin ne sıklıkta yenileneceği, minimum 1 dakika", "Rejections": "Reddedilenler", @@ -1605,7 +1605,7 @@ "NotificationsValidationUnableToConnectToApi": "{service} API'sine bağlanılamıyor. Sunucu bağlantısı başarısız oldu: ({responseCode}) {exceptionMessage}", "Recommendation": "Öneri", "Recommended": "Önerilen", - "RegularExpressionsTutorialLink": "Normal ifadelerle ilgili daha fazla ayrıntıyı [burada](https://www.regular-expressions.info/tutorial.html) bulabilirsiniz.", + "RegularExpressionsTutorialLink": "Düzenli ifadeler hakkında daha fazla ayrıntı [burada]({url}) bulunabilir.", "NotificationsTwitterSettingsDirectMessageHelpText": "Herkese açık mesaj yerine doğrudan mesaj gönderin", "NzbgetHistoryItemMessage": "PAR Durumu: {parStatus} - Paketten Çıkarma Durumu: {unpackStatus} - Taşıma Durumu: {moveStatus} - Komut Dosyası Durumu: {scriptStatus} - Silme Durumu: {deleteStatus} - İşaretleme Durumu: {markStatus}", "OneMinute": "1 dakika", @@ -1637,7 +1637,7 @@ "Popular": "Popüler", "PostImportCategory": "İçe Aktarma Sonrası Kategorisi", "PreferProtocol": "{preferredProtocol}'u tercih edin", - "PreviouslyInstalled": "Önceden Yüklenmiş", + "PreviouslyInstalled": "Daha Önce Kurulmuş", "Release": "Yayın", "ReleaseProfileTagMovieHelpText": "Yayımlama profilleri, en az bir eşleşen etikete sahip filmlere uygulanacaktır. Tüm filmlere uygulamak için boş bırakın", "RestartLater": "Daha sonra yeniden başlayacağım", @@ -1664,7 +1664,7 @@ "RemoveSelectedItemsQueueMessageText": "{selectedCount} öğeyi kuyruktan kaldırmak istediğinizden emin misiniz?", "RemoveSelectedBlocklistMessageText": "Seçilen öğeleri engellenenler listesinden kaldırmak istediğinizden emin misiniz?", "RemoveTagsAutomatically": "Otomatik Etiketlemeyi Kaldır", - "RemotePathMappingsInfo": "Uzak Yol Eşlemeleri çok nadiren gereklidir; {appName} ve indirme istemciniz aynı sistemdeyse yollarınızı eşleştirmek daha iyidir. Daha fazla bilgi için [wiki]({wikiLink}) sayfasına bakın.", + "RemotePathMappingsInfo": "Uzak Yol Eşlemeleri çok nadiren gereklidir, {appName} ve indirme istemciniz aynı sistemdeyse yollarınızı eşleştirmeniz daha iyidir. Daha fazla bilgi için [wiki]({wikiLink}) adresini ziyaret edin", "ResetDefinitions": "Tanımları Sıfırla", "UpdateFiltered": "Filtrelenenleri Güncelle", "RemoveFailedDownloads": "Başarısız İndirmeleri Kaldır", @@ -1709,7 +1709,7 @@ "ThereWasAnErrorLoadingThisItem": "Bu öğe yüklenirken bir hata oluştu", "ResetTitles": "Başlıkları Sıfırla", "SkipRedownloadHelpText": "{appName} uygulamasının bu öğe için alternatif bir yayın indirmeye çalışmasını engeller", - "UpdaterLogFiles": "Güncelleme Günlük Dosyaları", + "UpdaterLogFiles": "Log Kayıt Güncelleyici", "Unknown": "Bilinmeyen", "RottenTomatoesRating": "Tomato Derecelendirmesi", "RootFolderPath": "Kök Klasör Yolu", @@ -1758,19 +1758,19 @@ "BlocklistFilterHasNoItems": "Seçilen engelleme listesi filtresi hiçbir öğe içermiyor", "IndexerSettingsSeedTime": "Seed Süresi", "IndexerSettingsSeedRatio": "Seed Oranı", - "IndexerSettingsSeedTimeHelpText": "Bir torrentin durmadan önce seed edilmesi gereken süre. Boş bırakılırsa indirme istemcisinin varsayılan ayarını kullanır", - "IndexerSettingsSeedRatioHelpText": "Bir torrentin durmadan önce ulaşması gereken oran. Boş bırakılırsa indirme istemcisinin varsayılan değerini kullanır. Oran en az 1,0 olmalı ve indeksleyici kurallarına uygun olmalıdır", + "IndexerSettingsSeedTimeHelpText": "Bir torrentin durdurulmadan önce ulaşması gereken oran, boş bırakıldığında uygulamanın varsayılanı kullanılır", + "IndexerSettingsSeedRatioHelpText": "Bir torrentin durdurulmadan önce ulaşması gereken oran. Boş bırakılırsa indirme istemcisinin varsayılan değerini kullanır. Oran en az 1,0 olmalı ve indeksleyici kurallarına uygun olmalıdır", "MissingLoadError": "Eksik öğeler yüklenirken hata oluştu", "MissingNoItems": "Eksik öğe yok", "MovieDownloaded": "Film İndirildi", "MovieIsNotAvailable": "Film kullanılamıyor", "MovieMissingFromDisk": "Film diskte eksik", - "CutoffUnmetLoadError": "Karşılanmamış kesinti öğeleri yüklenirken hata oluştu", + "CutoffUnmetLoadError": "Kesinti karşılanmayan öğeleri yükleme hatası", "CutoffUnmetNoItems": "Karşılanmayan son öğe yok", "External": "Harici", "InteractiveSearchModalHeaderTitle": "İnteraktif Arama - {title}", "MassSearchCancelWarning": "Bu işlem, {appName} yeniden başlatılmadan veya tüm dizin oluşturucularınız devre dışı bırakılmadan başlatılır ise iptal edilemez.", - "MonitorSelected": "Takip Edilen Seçildi", + "MonitorSelected": "Seçilenleri Bırak", "MovieIsNotMonitored": "Film takip edilemiyor", "SearchForAllMissingMovies": "Eksik tüm filmleri arayın", "SearchForAllMissingMoviesConfirmationCount": "{totalRecords} eksik filmin tamamını aramak istediğinizden emin misiniz?", @@ -1795,7 +1795,7 @@ "ReleaseDate": "Yayın tarihleri", "EditSelectedCustomFormats": "Seçilen Özel Formatları Düzenle", "DeleteSelected": "Seçileni Sil", - "CountCustomFormatsSelected": "{count} özel biçim seçildi", + "CountCustomFormatsSelected": "{count} özel format seçildi", "NoCustomFormatsFound": "Özel format bulunamadı", "ProgressBarProgress": "İlerleme Çubuğu %{progress} seviyesinde", "InvalidMovieInfoLanguageLanguage": "Film Bilgi Diliniz geçersiz bir değere ayarlanmış, düzeltin ve ayarlarınızı kaydedin", @@ -1816,7 +1816,7 @@ "TodayAt": "Bugün {time}'da", "YesterdayAt": "Dün saat {time}'da", "MinimumCustomFormatScoreIncrement": "Minimum Özel Format Puanı Artışı", - "MinimumCustomFormatScoreIncrementHelpText": "{appName}'in bunu bir yükseltme olarak değerlendirmesi için mevcut ve yeni sürümler arasında özel biçim puanında gereken minimum iyileştirme", + "MinimumCustomFormatScoreIncrementHelpText": "{appName}'in bunu bir yükseltme olarak değerlendirmesi için mevcut ve yeni sürümler arasında özel format puanında gereken minimum iyileştirme", "DayOfWeekAt": "{day}, {time} saatinde", "Disposition": "Düzen", "CustomFormatsSpecificationExceptLanguageHelpText": "Seçilen dil dışında herhangi bir dil mevcutsa eşleşir", @@ -1863,5 +1863,8 @@ "FavoriteFolderRemove": "Favori Klasörü Kaldır", "FavoriteFolders": "Favori Klasörler", "Warning": "Uyarı", - "ManageFormats": "Biçimleri Yönet" + "ManageFormats": "Formatları Yönet", + "MetadataKometaDeprecatedSetting": "Kullanım Dışı", + "MetadataKometaDeprecated": "Kometa dosyaları artık oluşturulmayacak, destek v6'da tamamen kaldırılacak", + "NotificationsSettingsWebhookHeaders": "Başlıklar" } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 89ace04326..695d4bb943 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1120,7 +1120,7 @@ "RetryingDownloadOn": "Завантаження відкладається до {0} о {1}", "TablePageSize": "Розмір сторінки", "BlocklistLoadError": "Не вдалося завантажити список блокувань", - "BlocklistReleaseHelpText": "Забороняє {appName} знову автоматично захопити цей випуск", + "BlocklistReleaseHelpText": "Блокує завантаження цього випуску {appName} через RSS або Автоматичний пошук", "DelayingDownloadUntil": "Завантаження відкладається до {date} о {time}", "DeletedReasonUpgrade": "Файл видалено, щоб імпортувати оновлення", "AutoRedownloadFailed": "Помилка повторного завантаження", @@ -1289,5 +1289,8 @@ "DefaultNotFoundMessage": "Ви, мабуть, заблукали, тут нічого не видно.", "Completed": "Завершено", "Delay": "Затримка", - "DownloadClientUnavailable": "Клієнт завантажувача недоступний" + "DownloadClientUnavailable": "Клієнт завантажувача недоступний", + "CountIndexersSelected": "{count} індексер(-и) обрано", + "AnnouncedMovieAvailabilityDescription": "Фільми вважаються доступними, щойно їх додають у {appName}.", + "CountCustomFormatsSelected": "Користувацькі формати обрано {count}" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 6b2f3c7969..2bfc8bc84c 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1864,5 +1864,6 @@ "OnFileImport": "关于文件导入", "ManageFormats": "管理格式", "NotificationsSettingsWebhookHeaders": "标头", - "Warning": "警告" + "Warning": "警告", + "MetadataKometaDeprecatedSetting": "弃用" } From 64fd8552f8415a4baebf9ae1998eadc59ac396a3 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 10 Dec 2024 19:25:13 -0800 Subject: [PATCH 128/579] Fixed: Error getting processes in some cases (cherry picked from commit b552d4e9f7ca7388404aa0d52566010a54cb0244) --- src/NzbDrone.Common/Processes/ProcessProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Common/Processes/ProcessProvider.cs b/src/NzbDrone.Common/Processes/ProcessProvider.cs index c7475fc325..aaa64c6bf7 100644 --- a/src/NzbDrone.Common/Processes/ProcessProvider.cs +++ b/src/NzbDrone.Common/Processes/ProcessProvider.cs @@ -313,7 +313,7 @@ private ProcessInfo ConvertToProcessInfo(Process process) processInfo = new ProcessInfo(); processInfo.Id = process.Id; processInfo.Name = process.ProcessName; - processInfo.StartPath = process.MainModule.FileName; + processInfo.StartPath = process.MainModule?.FileName; if (process.Id != GetCurrentProcessId() && process.HasExited) { From 23fce4bf2e50cef56b336761b01784e4484b09b6 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 11 Dec 2024 14:36:38 +0200 Subject: [PATCH 129/579] Fixed: Refresh backup list on deletion (cherry picked from commit 3b00112447361b19c04851a510e63f812597a043) --- src/Radarr.Api.V3/System/Backup/BackupController.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Radarr.Api.V3/System/Backup/BackupController.cs b/src/Radarr.Api.V3/System/Backup/BackupController.cs index aa864960a9..cb057d276b 100644 --- a/src/Radarr.Api.V3/System/Backup/BackupController.cs +++ b/src/Radarr.Api.V3/System/Backup/BackupController.cs @@ -50,7 +50,7 @@ public List GetBackupFiles() } [RestDeleteById] - public void DeleteBackup(int id) + public object DeleteBackup(int id) { var backup = GetBackup(id); @@ -67,6 +67,8 @@ public void DeleteBackup(int id) } _diskProvider.DeleteFile(path); + + return new { }; } [HttpPost("restore/{id:int}")] From 9032ac20ff599bda8aa9acd02e6d59741233b4da Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 15 Dec 2024 10:04:38 +0200 Subject: [PATCH 130/579] Bump version to 5.16.3 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 874767e5e3..a207651a1b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.16.2' + majorVersion: '5.16.3' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From e4106f0ede441aa637c50de3bf5279bbddf2ee9d Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 8 Dec 2024 17:24:47 -0800 Subject: [PATCH 131/579] Upgrade TypeScript and core-js (cherry picked from commit 148480909917f69ff3b2ca547ccb4716dd56606e) Closes #10763 --- .../createMovieQualityProfileSelector.ts | 3 ++- package.json | 4 ++-- yarn.lock | 16 ++++++++-------- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/frontend/src/Store/Selectors/createMovieQualityProfileSelector.ts b/frontend/src/Store/Selectors/createMovieQualityProfileSelector.ts index 1997cdef2a..73d4570940 100644 --- a/frontend/src/Store/Selectors/createMovieQualityProfileSelector.ts +++ b/frontend/src/Store/Selectors/createMovieQualityProfileSelector.ts @@ -1,13 +1,14 @@ import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; import Movie from 'Movie/Movie'; +import QualityProfile from 'typings/QualityProfile'; import { createMovieSelectorForHook } from './createMovieSelector'; function createMovieQualityProfileSelector(movieId: number) { return createSelector( (state: AppState) => state.settings.qualityProfiles.items, createMovieSelectorForHook(movieId), - (qualityProfiles, movie = {} as Movie) => { + (qualityProfiles: QualityProfile[], movie = {} as Movie) => { return qualityProfiles.find( (profile) => profile.id === movie.qualityProfileId ); diff --git a/package.json b/package.json index 444ba323d8..afe89811c7 100644 --- a/package.json +++ b/package.json @@ -84,7 +84,7 @@ "reselect": "4.1.8", "stacktrace-js": "2.0.2", "swiper": "8.3.2", - "typescript": "5.1.6" + "typescript": "5.7.2" }, "devDependencies": { "@babel/core": "7.25.8", @@ -108,7 +108,7 @@ "babel-loader": "9.2.1", "babel-plugin-inline-classnames": "2.0.1", "babel-plugin-transform-react-remove-prop-types": "0.4.24", - "core-js": "3.38.1", + "core-js": "3.39.0", "css-loader": "6.7.3", "css-modules-typescript-loader": "4.0.1", "eslint": "8.57.1", diff --git a/yarn.lock b/yarn.lock index 0dcc691d63..67383b1666 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2410,10 +2410,10 @@ core-js-compat@^3.38.0, core-js-compat@^3.38.1: dependencies: browserslist "^4.23.3" -core-js@3.38.1: - version "3.38.1" - resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.38.1.tgz#aa375b79a286a670388a1a363363d53677c0383e" - integrity sha512-OP35aUorbU3Zvlx7pjsFdu1rGNnD4pgw/CWoYzRY3t2EzoVT7shKHY1dlAy3f41cGIO7ZDPQimhGFTlEYkG/Hw== +core-js@3.39.0: + version "3.39.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" + integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== core-js@^2.4.0: version "2.6.12" @@ -6724,10 +6724,10 @@ typescript-plugin-css-modules@5.0.1: stylus "^0.59.0" tsconfig-paths "^4.1.2" -typescript@5.1.6: - version "5.1.6" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274" - integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA== +typescript@5.7.2: + version "5.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.7.2.tgz#3169cf8c4c8a828cde53ba9ecb3d2b1d5dd67be6" + integrity sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg== unbox-primitive@^1.0.2: version "1.0.2" From 4e024c51d3832e28e981f1e71a5904953bff32ec Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 10 Dec 2024 19:22:58 -0800 Subject: [PATCH 132/579] Fixed: Movies without tags bypassing tags on Download Client (cherry picked from commit c0e264cfc520ee387bfc882c95a5822c655e0d9b) Closes #10765 --- .../Download/DownloadClientProvider.cs | 23 ++++++++++--------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Core/Download/DownloadClientProvider.cs b/src/NzbDrone.Core/Download/DownloadClientProvider.cs index 9a4eb87955..4ee7a2ad95 100644 --- a/src/NzbDrone.Core/Download/DownloadClientProvider.cs +++ b/src/NzbDrone.Core/Download/DownloadClientProvider.cs @@ -38,6 +38,10 @@ public DownloadClientProvider(IDownloadClientStatusService downloadClientStatusS public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int indexerId = 0, bool filterBlockedClients = false, HashSet tags = null) { + // Tags aren't required, but download clients with tags should not be picked unless there is at least one matching tag. + // Defaulting to an empty HashSet ensures this is always checked. + tags ??= new HashSet(); + var blockedProviders = new HashSet(_downloadClientStatusService.GetBlockedProviders().Select(v => v.ProviderId)); var availableProviders = _downloadClientFactory.GetAvailableProviders().Where(v => v.Protocol == downloadProtocol).ToList(); @@ -46,18 +50,15 @@ public IDownloadClient GetDownloadClient(DownloadProtocol downloadProtocol, int return null; } - if (tags is { Count: > 0 }) + var matchingTagsClients = availableProviders.Where(i => i.Definition.Tags.Intersect(tags).Any()).ToList(); + + availableProviders = matchingTagsClients.Count > 0 ? + matchingTagsClients : + availableProviders.Where(i => i.Definition.Tags.Empty()).ToList(); + + if (!availableProviders.Any()) { - var matchingTagsClients = availableProviders.Where(i => i.Definition.Tags.Intersect(tags).Any()).ToList(); - - availableProviders = matchingTagsClients.Count > 0 ? - matchingTagsClients : - availableProviders.Where(i => i.Definition.Tags.Empty()).ToList(); - - if (!availableProviders.Any()) - { - throw new DownloadClientUnavailableException("No download client was found without tags or a matching movie tag. Please check your settings."); - } + throw new DownloadClientUnavailableException("No download client was found without tags or a matching movie tag. Please check your settings."); } if (indexerId > 0) From 8c6ba9a543a308fcf75d43ab7f4ddd43452d2cd4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 10 Dec 2024 19:33:48 -0800 Subject: [PATCH 133/579] Fixed: Augmenting languages from indexer for release with stale indexer ID (cherry picked from commit cb7489ce8fe933920ea04297bd2941496a0c07c6) Closes #10768 --- .../Aggregators/AggregateLanguagesFixture.cs | 96 +++++++++++++++++-- .../Aggregators/AggregateLanguages.cs | 5 +- 2 files changed, 91 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs b/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs index db353fa69e..638ea84019 100644 --- a/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs @@ -74,7 +74,7 @@ public void should_return_multi_languages_when_indexer_id_has_multi_languages_co Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } }; Mocker.GetMock() - .Setup(v => v.Get(1)) + .Setup(v => v.Find(1)) .Returns(indexerDefinition); _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { }, releaseTitle); @@ -82,7 +82,7 @@ public void should_return_multi_languages_when_indexer_id_has_multi_languages_co _remoteMovie.Release.Title = releaseTitle; Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); - Mocker.GetMock().Verify(c => c.Get(1), Times.Once()); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); Mocker.GetMock().VerifyNoOtherCalls(); } @@ -104,7 +104,7 @@ public void should_return_multi_languages_from_indexer_with_id_when_indexer_id_a }; Mocker.GetMock() - .Setup(v => v.Get(1)) + .Setup(v => v.Find(1)) .Returns(indexerDefinition1); Mocker.GetMock() @@ -117,7 +117,7 @@ public void should_return_multi_languages_from_indexer_with_id_when_indexer_id_a _remoteMovie.Release.Title = releaseTitle; Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); - Mocker.GetMock().Verify(c => c.Get(1), Times.Once()); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); Mocker.GetMock().VerifyNoOtherCalls(); } @@ -155,7 +155,7 @@ public void should_return_multi_languages_when_release_as_unknown_as_default_lan Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } }; Mocker.GetMock() - .Setup(v => v.Get(1)) + .Setup(v => v.Find(1)) .Returns(indexerDefinition); _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { Language.Unknown }, releaseTitle); @@ -163,7 +163,7 @@ public void should_return_multi_languages_when_release_as_unknown_as_default_lan _remoteMovie.Release.Title = releaseTitle; Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); - Mocker.GetMock().Verify(c => c.Get(1), Times.Once()); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); Mocker.GetMock().VerifyNoOtherCalls(); } @@ -177,7 +177,7 @@ public void should_return_original_when_indexer_has_no_multi_languages_configura Settings = new TorrentRssIndexerSettings { } }; Mocker.GetMock() - .Setup(v => v.Get(1)) + .Setup(v => v.Find(1)) .Returns(indexerDefinition); _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { }, releaseTitle); @@ -185,7 +185,7 @@ public void should_return_original_when_indexer_has_no_multi_languages_configura _remoteMovie.Release.Title = releaseTitle; Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage }); - Mocker.GetMock().Verify(c => c.Get(1), Times.Once()); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); Mocker.GetMock().VerifyNoOtherCalls(); } @@ -248,5 +248,85 @@ public void should_use_reparse_language_after_determining_languages_that_are_in_ Subject.Aggregate(_remoteMovie).Languages.Should().Equal(Language.Greek); } + + [Test] + public void should_return_multi_languages_from_indexer_with_name_when_indexer_id_does_not_exist() + { + var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup"; + var indexerDefinition1 = new IndexerDefinition + { + Id = 1, + Name = "MyIndexer1", + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } + }; + var indexerDefinition2 = new IndexerDefinition + { + Id = 2, + Name = "MyIndexer2", + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.German.Id } } + }; + + Mocker.GetMock() + .Setup(v => v.Find(1)) + .Returns(null as IndexerDefinition); + + Mocker.GetMock() + .Setup(v => v.FindByName("MyIndexer1")) + .Returns(indexerDefinition1); + + Mocker.GetMock() + .Setup(v => v.All()) + .Returns(new List() { indexerDefinition1, indexerDefinition2 }); + + _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { }, releaseTitle); + _remoteMovie.Release.IndexerId = 10; + _remoteMovie.Release.Indexer = "MyIndexer1"; + _remoteMovie.Release.Title = releaseTitle; + + Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); + Mocker.GetMock().Verify(c => c.Find(10), Times.Once()); + Mocker.GetMock().Verify(c => c.FindByName("MyIndexer1"), Times.Once()); + Mocker.GetMock().VerifyNoOtherCalls(); + } + + [Test] + public void should_return_multi_languages_from_indexer_with_name_when_indexer_id_not_available() + { + var releaseTitle = "Series.Title.S01E01.MULTi.1080p.WEB.H265-RlsGroup"; + var indexerDefinition1 = new IndexerDefinition + { + Id = 1, + Name = "MyIndexer1", + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } + }; + var indexerDefinition2 = new IndexerDefinition + { + Id = 2, + Name = "MyIndexer2", + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.German.Id } } + }; + + Mocker.GetMock() + .Setup(v => v.Find(1)) + .Returns(null as IndexerDefinition); + + Mocker.GetMock() + .Setup(v => v.FindByName("MyIndexer1")) + .Returns(indexerDefinition1); + + Mocker.GetMock() + .Setup(v => v.All()) + .Returns(new List() { indexerDefinition1, indexerDefinition2 }); + + _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { }, releaseTitle); + _remoteMovie.Release.IndexerId = 0; + _remoteMovie.Release.Indexer = "MyIndexer1"; + _remoteMovie.Release.Title = releaseTitle; + + Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); + Mocker.GetMock().Verify(c => c.Find(10), Times.Never()); + Mocker.GetMock().Verify(c => c.FindByName("MyIndexer1"), Times.Once()); + Mocker.GetMock().VerifyNoOtherCalls(); + } } } diff --git a/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs b/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs index 33bd341d63..5b89aa82e2 100644 --- a/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs +++ b/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs @@ -77,9 +77,10 @@ public RemoteMovie Aggregate(RemoteMovie remoteMovie) if (releaseInfo is { IndexerId: > 0 }) { - indexer = _indexerFactory.Get(releaseInfo.IndexerId); + indexer = _indexerFactory.Find(releaseInfo.IndexerId); } - else if (releaseInfo.Indexer?.IsNotNullOrWhiteSpace() == true) + + if (indexer == null && releaseInfo.Indexer?.IsNotNullOrWhiteSpace() == true) { indexer = _indexerFactory.FindByName(releaseInfo.Indexer); } From b2b5aa1f795632311303256aa5d1271bbe07af1f Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Mon, 9 Dec 2024 04:37:51 +0100 Subject: [PATCH 134/579] New: Optionally as Instance Name to Telegram notifications (cherry picked from commit 36633b5d08c19158f185c0fa5faabbaec607fcb5) Closes #10757 --- src/NzbDrone.Core/Localization/Core/en.json | 2 ++ .../Notifications/Telegram/Telegram.cs | 28 ++++++++++++++----- .../Notifications/Telegram/TelegramProxy.cs | 9 ++++-- .../Telegram/TelegramSettings.cs | 3 ++ 4 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 7b6c81d77b..2f646215e2 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1234,6 +1234,8 @@ "NotificationsTelegramSettingsChatIdHelpText": "You must start a conversation with the bot or add it to your group to receive messages", "NotificationsTelegramSettingsIncludeAppName": "Include {appName} in Title", "NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications", + "NotificationsTelegramSettingsIncludeInstanceName": "Include Instance Name in Title", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Optionally include Instance name in notification", "NotificationsTelegramSettingsSendSilently": "Send Silently", "NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound", "NotificationsTelegramSettingsTopicId": "Topic ID", diff --git a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs index 95914da879..71608aebff 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs @@ -2,6 +2,7 @@ using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Movies; namespace NzbDrone.Core.Notifications.Telegram @@ -9,41 +10,48 @@ namespace NzbDrone.Core.Notifications.Telegram public class Telegram : NotificationBase { private readonly ITelegramProxy _proxy; + private readonly IConfigFileProvider _configFileProvider; - public Telegram(ITelegramProxy proxy) + public Telegram(ITelegramProxy proxy, IConfigFileProvider configFileProvider) { _proxy = proxy; + _configFileProvider = configFileProvider; } public override string Name => "Telegram"; public override string Link => "https://telegram.org/"; + private string InstanceName => _configFileProvider.InstanceName; + public override void OnGrab(GrabMessage grabMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_GRABBED_TITLE_BRANDED : MOVIE_GRABBED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, grabMessage.Message, Settings); } public override void OnDownload(DownloadMessage message) { + string title; if (message.OldMovieFiles.Any()) { - var title = Settings.IncludeAppNameInTitle ? MOVIE_UPGRADED_TITLE_BRANDED : MOVIE_UPGRADED_TITLE; - - _proxy.SendNotification(title, message.Message, Settings); + title = Settings.IncludeAppNameInTitle ? MOVIE_UPGRADED_TITLE_BRANDED : MOVIE_UPGRADED_TITLE; } else { - var title = Settings.IncludeAppNameInTitle ? MOVIE_DOWNLOADED_TITLE_BRANDED : MOVIE_DOWNLOADED_TITLE; - - _proxy.SendNotification(title, message.Message, Settings); + title = Settings.IncludeAppNameInTitle ? MOVIE_DOWNLOADED_TITLE_BRANDED : MOVIE_DOWNLOADED_TITLE; } + + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + + _proxy.SendNotification(title, message.Message, Settings); } public override void OnMovieAdded(Movie movie) { var title = Settings.IncludeAppNameInTitle ? MOVIE_ADDED_TITLE_BRANDED : MOVIE_ADDED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, $"{movie.Title} added to library", Settings); } @@ -51,6 +59,7 @@ public override void OnMovieAdded(Movie movie) public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_FILE_DELETED_TITLE_BRANDED : MOVIE_FILE_DELETED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, deleteMessage.Message, Settings); } @@ -58,6 +67,7 @@ public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_DELETED_TITLE_BRANDED : MOVIE_DELETED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, deleteMessage.Message, Settings); } @@ -65,6 +75,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, healthCheck.Message, Settings); } @@ -72,6 +83,7 @@ public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) { var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", Settings); } @@ -79,6 +91,7 @@ public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, updateMessage.Message, Settings); } @@ -86,6 +99,7 @@ public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message) { var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE; + title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; _proxy.SendNotification(title, message.Message, Settings); } diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs index 56db188487..2edb9110f2 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs @@ -7,6 +7,7 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Localization; namespace NzbDrone.Core.Notifications.Telegram @@ -21,12 +22,14 @@ public class TelegramProxy : ITelegramProxy { private const string URL = "https://api.telegram.org"; private readonly IHttpClient _httpClient; + private readonly IConfigFileProvider _configFileProvider; private readonly ILocalizationService _localizationService; private readonly Logger _logger; - public TelegramProxy(IHttpClient httpClient, ILocalizationService localizationService, Logger logger) + public TelegramProxy(IHttpClient httpClient, IConfigFileProvider configFileProvider, ILocalizationService localizationService, Logger logger) { _httpClient = httpClient; + _configFileProvider = configFileProvider; _localizationService = localizationService; _logger = logger; } @@ -57,7 +60,9 @@ public ValidationFailure Test(TelegramSettings settings) const string title = "Test Notification"; const string body = "This is a test message from Radarr"; - SendNotification(settings.IncludeAppNameInTitle ? brandedTitle : title, body, settings); + var testMessageTitle = settings.IncludeAppNameInTitle ? brandedTitle : title; + testMessageTitle = settings.IncludeInstanceNameInTitle ? $"{testMessageTitle} - {_configFileProvider.InstanceName}" : testMessageTitle; + SendNotification(testMessageTitle, body, settings); } catch (Exception ex) { diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs index f3e4d24991..2701635134 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs @@ -34,6 +34,9 @@ public class TelegramSettings : NotificationSettingsBase [FieldDefinition(4, Label = "NotificationsTelegramSettingsIncludeAppName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeAppNameHelpText")] public bool IncludeAppNameInTitle { get; set; } + [FieldDefinition(5, Label = "NotificationsTelegramSettingsIncludeInstanceName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeInstanceNameHelpText", Advanced = true)] + public bool IncludeInstanceNameInTitle { get; set; } + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From b801aa093595a33a55e9edd5cda141c4c55a9bb5 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Tue, 30 Jul 2024 21:25:48 -0700 Subject: [PATCH 135/579] New: Add metadata links to telegram messages Co-authored-by: Ivar Stangeby Fixed errors sending Telegram notifications when links aren't available (cherry picked from commit 4eab168267db716a9e897a992e3a7f6889571f9f) (cherry picked from commit 4d7a3d0909437268b4ad0a0dbeb59d45b4435118) Closes #10242 Closes #10489 --- src/NzbDrone.Core/Localization/Core/en.json | 2 + .../Notifications/Telegram/Telegram.cs | 55 ++++++++++++++++--- .../Notifications/Telegram/TelegramLink.cs | 14 +++++ .../Notifications/Telegram/TelegramProxy.cs | 23 ++++++-- .../Telegram/TelegramSettings.cs | 21 +++++++ 5 files changed, 101 insertions(+), 14 deletions(-) create mode 100644 src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 2f646215e2..3a55611ff0 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1236,6 +1236,8 @@ "NotificationsTelegramSettingsIncludeAppNameHelpText": "Optionally prefix message title with {appName} to differentiate notifications from different applications", "NotificationsTelegramSettingsIncludeInstanceName": "Include Instance Name in Title", "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Optionally include Instance name in notification", + "NotificationsTelegramSettingsMetadataLinks": "Metadata Links", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Add links to movie metadata when sending notifications", "NotificationsTelegramSettingsSendSilently": "Send Silently", "NotificationsTelegramSettingsSendSilentlyHelpText": "Sends the message silently. Users will receive a notification with no sound", "NotificationsTelegramSettingsTopicId": "Topic ID", diff --git a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs index 71608aebff..769efd06c5 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/Telegram.cs @@ -27,8 +27,9 @@ public override void OnGrab(GrabMessage grabMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_GRABBED_TITLE_BRANDED : MOVIE_GRABBED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + var links = GetLinks(grabMessage.Movie); - _proxy.SendNotification(title, grabMessage.Message, Settings); + _proxy.SendNotification(title, grabMessage.Message, links, Settings); } public override void OnDownload(DownloadMessage message) @@ -44,32 +45,36 @@ public override void OnDownload(DownloadMessage message) } title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + var links = GetLinks(message.Movie); - _proxy.SendNotification(title, message.Message, Settings); + _proxy.SendNotification(title, message.Message, links, Settings); } public override void OnMovieAdded(Movie movie) { var title = Settings.IncludeAppNameInTitle ? MOVIE_ADDED_TITLE_BRANDED : MOVIE_ADDED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + var links = GetLinks(movie); - _proxy.SendNotification(title, $"{movie.Title} added to library", Settings); + _proxy.SendNotification(title, $"{movie.Title} added to library", links, Settings); } public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_FILE_DELETED_TITLE_BRANDED : MOVIE_FILE_DELETED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + var links = GetLinks(deleteMessage.Movie); - _proxy.SendNotification(title, deleteMessage.Message, Settings); + _proxy.SendNotification(title, deleteMessage.Message, links, Settings); } public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { var title = Settings.IncludeAppNameInTitle ? MOVIE_DELETED_TITLE_BRANDED : MOVIE_DELETED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; + var links = GetLinks(deleteMessage.Movie); - _proxy.SendNotification(title, deleteMessage.Message, Settings); + _proxy.SendNotification(title, deleteMessage.Message, links, Settings); } public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) @@ -77,7 +82,7 @@ public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) var title = Settings.IncludeAppNameInTitle ? HEALTH_ISSUE_TITLE_BRANDED : HEALTH_ISSUE_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; - _proxy.SendNotification(title, healthCheck.Message, Settings); + _proxy.SendNotification(title, healthCheck.Message, new List(), Settings); } public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) @@ -85,7 +90,7 @@ public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) var title = Settings.IncludeAppNameInTitle ? HEALTH_RESTORED_TITLE_BRANDED : HEALTH_RESTORED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; - _proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", Settings); + _proxy.SendNotification(title, $"The following issue is now resolved: {previousCheck.Message}", new List(), Settings); } public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) @@ -93,7 +98,7 @@ public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) var title = Settings.IncludeAppNameInTitle ? APPLICATION_UPDATE_TITLE_BRANDED : APPLICATION_UPDATE_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; - _proxy.SendNotification(title, updateMessage.Message, Settings); + _proxy.SendNotification(title, updateMessage.Message, new List(), Settings); } public override void OnManualInteractionRequired(ManualInteractionRequiredMessage message) @@ -101,7 +106,7 @@ public override void OnManualInteractionRequired(ManualInteractionRequiredMessag var title = Settings.IncludeAppNameInTitle ? MANUAL_INTERACTION_REQUIRED_TITLE_BRANDED : MANUAL_INTERACTION_REQUIRED_TITLE; title = Settings.IncludeInstanceNameInTitle ? $"{title} - {InstanceName}" : title; - _proxy.SendNotification(title, message.Message, Settings); + _proxy.SendNotification(title, message.Message, new List(), Settings); } public override ValidationResult Test() @@ -112,5 +117,37 @@ public override ValidationResult Test() return new ValidationResult(failures); } + + private List GetLinks(Movie movie) + { + var links = new List(); + + if (movie == null) + { + return links; + } + + foreach (var link in Settings.MetadataLinks) + { + var linkType = (MetadataLinkType)link; + + if (linkType == MetadataLinkType.Tmdb && movie.TmdbId > 0) + { + links.Add(new TelegramLink("TMDb", $"https://www.themoviedb.org/movie/{movie.TmdbId}")); + } + + if (linkType == MetadataLinkType.Imdb && movie.ImdbId.IsNotNullOrWhiteSpace()) + { + links.Add(new TelegramLink("IMDb", $"https://www.imdb.com/title/{movie.ImdbId}")); + } + + if (linkType == MetadataLinkType.Trakt && movie.TmdbId > 0) + { + links.Add(new TelegramLink("Trakt", $"https://trakt.tv/search/tmdb/{movie.TmdbId}?id_type=movie")); + } + } + + return links; + } } } diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs new file mode 100644 index 0000000000..ac131b483b --- /dev/null +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramLink.cs @@ -0,0 +1,14 @@ +namespace NzbDrone.Core.Notifications.Telegram +{ + public class TelegramLink + { + public string Label { get; set; } + public string Link { get; set; } + + public TelegramLink(string label, string link) + { + Label = label; + Link = link; + } + } +} diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs index 2edb9110f2..ef5bc5dcf4 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramProxy.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Net; +using System.Text; using System.Web; using FluentValidation.Results; using NLog; @@ -14,7 +15,7 @@ namespace NzbDrone.Core.Notifications.Telegram { public interface ITelegramProxy { - void SendNotification(string title, string message, TelegramSettings settings); + void SendNotification(string title, string message, List links, TelegramSettings settings); ValidationFailure Test(TelegramSettings settings); } @@ -34,10 +35,16 @@ public TelegramProxy(IHttpClient httpClient, IConfigFileProvider configFileProvi _logger = logger; } - public void SendNotification(string title, string message, TelegramSettings settings) + public void SendNotification(string title, string message, List links, TelegramSettings settings) { - // Format text to add the title before and bold using markdown - var text = $"{HttpUtility.HtmlEncode(title)}\n{HttpUtility.HtmlEncode(message)}"; + var text = new StringBuilder($"{HttpUtility.HtmlEncode(title)}\n"); + + text.AppendLine(HttpUtility.HtmlEncode(message)); + + foreach (var link in links) + { + text.AppendLine($"{HttpUtility.HtmlEncode(link.Label)}"); + } var requestBuilder = new HttpRequestBuilder(URL).Resource("bot{token}/sendmessage").Post(); @@ -60,9 +67,15 @@ public ValidationFailure Test(TelegramSettings settings) const string title = "Test Notification"; const string body = "This is a test message from Radarr"; + var links = new List + { + new ("Radarr.video", "https://radarr.video") + }; + var testMessageTitle = settings.IncludeAppNameInTitle ? brandedTitle : title; testMessageTitle = settings.IncludeInstanceNameInTitle ? $"{testMessageTitle} - {_configFileProvider.InstanceName}" : testMessageTitle; - SendNotification(testMessageTitle, body, settings); + + SendNotification(testMessageTitle, body, links, settings); } catch (Exception ex) { diff --git a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs index 2701635134..b87b5a9d80 100644 --- a/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs +++ b/src/NzbDrone.Core/Notifications/Telegram/TelegramSettings.cs @@ -1,3 +1,6 @@ +using System; +using System.Collections.Generic; +using System.Linq; using FluentValidation; using NzbDrone.Core.Annotations; using NzbDrone.Core.Validation; @@ -12,6 +15,16 @@ public TelegramSettingsValidator() RuleFor(c => c.ChatId).NotEmpty(); RuleFor(c => c.TopicId).Must(topicId => !topicId.HasValue || topicId > 1) .WithMessage("Topic ID must be greater than 1 or empty"); + RuleFor(c => c.MetadataLinks).Custom((links, context) => + { + foreach (var link in links) + { + if (!Enum.IsDefined(typeof(MetadataLinkType), link)) + { + context.AddFailure("MetadataLinks", $"MetadataLink is not valid: {link}"); + } + } + }); } } @@ -19,6 +32,11 @@ public class TelegramSettings : NotificationSettingsBase { private static readonly TelegramSettingsValidator Validator = new (); + public TelegramSettings() + { + MetadataLinks = Enumerable.Empty(); + } + [FieldDefinition(0, Label = "NotificationsTelegramSettingsBotToken", Privacy = PrivacyLevel.ApiKey, HelpLink = "https://core.telegram.org/bots")] public string BotToken { get; set; } @@ -37,6 +55,9 @@ public class TelegramSettings : NotificationSettingsBase [FieldDefinition(5, Label = "NotificationsTelegramSettingsIncludeInstanceName", Type = FieldType.Checkbox, HelpText = "NotificationsTelegramSettingsIncludeInstanceNameHelpText", Advanced = true)] public bool IncludeInstanceNameInTitle { get; set; } + [FieldDefinition(6, Label = "NotificationsTelegramSettingsMetadataLinks", Type = FieldType.Select, SelectOptions = typeof(MetadataLinkType), HelpText = "NotificationsTelegramSettingsMetadataLinksMovieHelpText")] + public IEnumerable MetadataLinks { get; set; } + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); From 5ae5d1043a78990ff3425c93ebb66e98aef531b7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 16 Dec 2024 01:25:03 +0200 Subject: [PATCH 136/579] Improve opening add movie modal for Discover Overview --- .../Overview/DiscoverMovieOverview.css | 8 ++++- .../Overview/DiscoverMovieOverview.css.d.ts | 1 + .../Overview/DiscoverMovieOverview.js | 33 +++++++++++-------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css index 43290e5b43..73ff1a651f 100644 --- a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css +++ b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css @@ -85,10 +85,16 @@ $hoverScale: 1.05; flex: 1 0 auto; } +.overviewContainer { + display: flex; + justify-content: space-between; + flex: 0 1 1000px; + flex-direction: column; +} + .overview { composes: link; - flex: 0 1 1000px; overflow: hidden; min-height: 0; } diff --git a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css.d.ts b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css.d.ts index 8c2e67476f..c1f09e1d97 100644 --- a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css.d.ts +++ b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.css.d.ts @@ -11,6 +11,7 @@ interface CssExports { 'link': string; 'lists': string; 'overview': string; + 'overviewContainer': string; 'poster': string; 'posterContainer': string; 'title': string; diff --git a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.js b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.js index dbc2714161..52fb0abe13 100644 --- a/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.js +++ b/frontend/src/DiscoverMovie/Overview/DiscoverMovieOverview.js @@ -133,14 +133,20 @@ class DiscoverMovieOverview extends Component { /> - + {...linkProps} + > + + @@ -242,11 +248,13 @@ class DiscoverMovieOverview extends Component {
-
- +
+ + +
-
From 86b656d323567e1fc83f61a79c41778cbeba91eb Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 15 Dec 2024 18:50:16 +0200 Subject: [PATCH 137/579] Use minor version for core-js in babel/preset-env --- frontend/build/webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/build/webpack.config.js b/frontend/build/webpack.config.js index da97f73313..0d0364950d 100644 --- a/frontend/build/webpack.config.js +++ b/frontend/build/webpack.config.js @@ -187,7 +187,7 @@ module.exports = (env) => { loose: true, debug: false, useBuiltIns: 'entry', - corejs: 3 + corejs: '3.39' } ] ] From 85171e40a58d65f3e6b2d137701ef95e649e4b6f Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 15 Dec 2024 23:33:16 +0000 Subject: [PATCH 138/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: GkhnGRBZ Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/da.json | 3 ++- src/NzbDrone.Core/Localization/Core/de.json | 3 ++- src/NzbDrone.Core/Localization/Core/es.json | 6 ++++- src/NzbDrone.Core/Localization/Core/fr.json | 4 ++- src/NzbDrone.Core/Localization/Core/ko.json | 3 ++- .../Localization/Core/pt_BR.json | 6 ++++- src/NzbDrone.Core/Localization/Core/tr.json | 26 +++++++++++-------- .../Localization/Core/zh_CN.json | 4 ++- 8 files changed, 37 insertions(+), 18 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 4f095dd3c2..cdb8098580 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1096,5 +1096,6 @@ "EditReleaseProfile": "Rediger forsinkelsesprofil", "DownloadClientUnavailable": "Downloadklienten er ikke tilgængelig", "AddReleaseProfile": "Rediger forsinkelsesprofil", - "ApiKeyValidationHealthCheckMessage": "Opdater din API-nøgle til at være på mindste {length} karakterer. Dette kan gøres i indstillingerne eller i konfigurationsfilen" + "ApiKeyValidationHealthCheckMessage": "Opdater din API-nøgle til at være på mindste {length} karakterer. Dette kan gøres i indstillingerne eller i konfigurationsfilen", + "AutoTaggingSpecificationTag": "Etiket" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 0abe90621a..d478e3501e 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1788,5 +1788,6 @@ "UnknownEventTooltip": "Unbekanntes Ereignis", "Warning": "Warnung", "YesterdayAt": "Gestern um {time}", - "RemotePathMappingsInfo": "Remote-Pfadzuordnungen sind sehr selten erforderlich. Wenn {appName} und dein Download-Client auf demselben System sind, ist es besser, deine Pfade abzugleichen. Weitere Informationen findest du im [Wiki]({wikiLink})." + "RemotePathMappingsInfo": "Remote-Pfadzuordnungen sind sehr selten erforderlich. Wenn {appName} und dein Download-Client auf demselben System sind, ist es besser, deine Pfade abzugleichen. Weitere Informationen findest du im [Wiki]({wikiLink}).", + "NotificationsTelegramSettingsMetadataLinks": "Metadaten-Links" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 4c660c5318..2317dbe9c8 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1866,5 +1866,9 @@ "NotificationsSettingsWebhookHeaders": "Cabeceras", "MetadataKometaDeprecated": "Los archivos de Kometa no seguirán siendo creados, el soporte se eliminará completamente en la v6", "MetadataKometaDeprecatedSetting": "Obsoleto", - "Fallback": "Retirada" + "Fallback": "Retirada", + "NotificationsTelegramSettingsMetadataLinks": "Enlaces de metadatos", + "NotificationsTelegramSettingsIncludeInstanceName": "Incluir el nombre de la instancia en el título", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Opcionalmente incluye el nombre de la instancia en la notificación", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Añade un enlace a los metadatos de la película cuando se envían notificaciones" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 195acebd0a..3ce1506792 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1846,5 +1846,7 @@ "FileBrowser": "Explorateur de fichiers", "Completed": "Terminé", "Delay": "Délai", - "DownloadClientUnavailable": "Le client de téléchargement n'est pas disponible" + "DownloadClientUnavailable": "Le client de téléchargement n'est pas disponible", + "NotificationsTelegramSettingsMetadataLinks": "Liens de métadonnées", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index edd38a3d8a..6c3faa9b97 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1091,5 +1091,6 @@ "Warning": "경고", "VideoDynamicRange": "동영상 다이나믹 레인지", "XmlRpcPath": "XML RPC 경로", - "YesterdayAt": "어제 {time}" + "YesterdayAt": "어제 {time}", + "DownloadClientPneumaticSettingsNzbFolder": "Nzb 폴더" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index ca7d685fc6..f1c8e078f8 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1866,5 +1866,9 @@ "DownloadClientUnavailable": "Cliente de download indisponível", "NotificationsSettingsWebhookHeaders": "Cabeçalhos", "MetadataKometaDeprecatedSetting": "Deprecado", - "MetadataKometaDeprecated": "Os arquivos Kometa não serão mais criados, o suporte será completamente removido na v6" + "MetadataKometaDeprecated": "Os arquivos Kometa não serão mais criados, o suporte será completamente removido na v6", + "NotificationsTelegramSettingsIncludeInstanceName": "Incluir nome da instância no título", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Opcionalmente, inclua o nome da instância na notificação", + "NotificationsTelegramSettingsMetadataLinks": "Links de metadados", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Adicione links aos metadados da série ao enviar notificações" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 6be032e0fb..fe0ca841aa 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -99,7 +99,7 @@ "RemoveSelected": "Seçilenleri Kaldır", "RemovedMovieCheckSingleMessage": "{movie} filmi TMDb'den çıkarıldı", "RemovedMovieCheckMultipleMessage": "{movies} filmleri TMDb'den çıkarıldı", - "ReleaseTitle": "Yayin Başlığı", + "ReleaseTitle": "Yayın Başlığı", "ReleaseStatus": "Yayın Durumu", "ReleaseGroup": "Yayımlayan Grup", "ReleaseBranchCheckOfficialBranchMessage": "{0} şubesi geçerli bir {appName} sürüm dalı değil; güncelleme almayacaksınız", @@ -236,7 +236,7 @@ "InteractiveSearch": "Etkileşimli Arama", "MovieInvalidFormat": "Film: Geçersiz Format", "Negated": "Reddedildi", - "OutputPath": "Çıkış yolu", + "OutputPath": "İndirilen Yol", "PreferIndexerFlagsHelpText": "Yayınları özel işaretlerle önceliklendirin", "RefreshInformationAndScanDisk": "Bilgileri ve tarama diskini yenileyin", "RemoveFromDownloadClient": "İndirme İstemcisinden Kaldır", @@ -291,7 +291,7 @@ "Sunday": "Pazar", "Table": "Tablo", "TableOptions": "Tablo Seçenekleri", - "TableOptionsColumnsMessage": "Hangi sütunların görünür olduğunu ve hangi sırada görüneceklerini seçin", + "TableOptionsColumnsMessage": "Hangi sütunların görünür olacağını ve hangi sırayla görüneceğini seçin", "TagIsNotUsedAndCanBeDeleted": "Etiket kullanılmaz ve silinebilir", "TestAll": "Tümünü Test Et", "TheLogLevelDefault": "Log seviyesi varsayılan olarak 'Bilgi' şeklindedir ve [Genel Ayarlar](/ayarlar/genel) bölümünden değiştirilebilir", @@ -375,7 +375,7 @@ "AddNewMovie": "Yeni Film Ekle", "Add": "Ekle", "AddCustomFormat": "Özel Format Ekle", - "AddDelayProfile": "Gecikme Profili Ekleme", + "AddDelayProfile": "Gecikme Profili Ekle", "AddDownloadClient": "İndirme İstemcisi Ekle", "AddedToDownloadQueue": "İndirme kuyruğuna eklendi", "AllMoviesInPathHaveBeenImported": "{path} içindeki tüm filmler içe aktarıldı", @@ -478,7 +478,7 @@ "OnlyUsenet": "Sadece Usenet", "PendingChangesMessage": "Kaydedilmemiş değişiklikleriniz var, bu sayfadan ayrılmak istediğinizden emin misiniz?", "ProxyType": "Proxy Türü", - "RegularExpressionsCanBeTested": "Düzenli ifadeler [burada]({url}) test edilebilir.", + "RegularExpressionsCanBeTested": "Düzenli ifadeler [burada](http://regexstorm.net/tester) test edilebilir.", "ShowGenres": "Türleri Göster", "UpgradesAllowed": "Yükseltmelere İzin Ver", "Pending": "Bekliyor", @@ -552,7 +552,7 @@ "DeleteCustomFormat": "Özel Formatı Sil", "DeleteDownloadClient": "İndirme İstemcisini Sil", "DeleteBackupMessageText": "'{name}' yedeğini silmek istediğinizden emin misiniz?", - "Edition": "Baskı", + "Edition": "Versiyon", "EnableCompletedDownloadHandlingHelpText": "Tamamlanan indirmeleri indirme istemcisinden otomatik olarak içe aktarın", "ListEnabledHelpText": "Bu listeyi {appName}'da kullanmak üzere etkinleştirin", "Ended": "Biten", @@ -900,7 +900,7 @@ "SearchForMovie": "Film ara", "SearchMissing": "Arama Eksik", "SearchMovie": "Film Ara", - "SearchOnAdd": "Eklemede ara", + "SearchOnAdd": "Ekle ve Ara", "ListSearchOnAddMovieHelpText": "Kitaplığa eklendiğinde bu listedeki filmleri arayın", "Seconds": "Saniye", "Seeders": "Ekme makineleri", @@ -1481,7 +1481,7 @@ "RemotePathMappingCheckImportFailed": "{appName} filmi içe aktaramadı. Ayrıntılar için log kayıtlarınızı kontrol edin.", "OnManualInteractionRequired": "Manuel Etkileşim Gerektiğinde", "OnHealthRestored": "Sağlığın İyileştirilmesi Hakkında", - "OrganizeNamingPattern": "Adlandırma düzeni: `{episodeFormat}`", + "OrganizeNamingPattern": "Adlandırma düzeni: `{standardMovieFormat}`", "OrganizeNothingToRename": "Başarılı! İşim bitti, yeniden adlandırılacak dosya yok.", "OverrideGrabModalTitle": "Geçersiz Kıl ve Al - {title}", "QueueLoadError": "Kuyruk yüklenemedi", @@ -1605,7 +1605,7 @@ "NotificationsValidationUnableToConnectToApi": "{service} API'sine bağlanılamıyor. Sunucu bağlantısı başarısız oldu: ({responseCode}) {exceptionMessage}", "Recommendation": "Öneri", "Recommended": "Önerilen", - "RegularExpressionsTutorialLink": "Düzenli ifadeler hakkında daha fazla ayrıntı [burada]({url}) bulunabilir.", + "RegularExpressionsTutorialLink": "Düzenli ifadeler hakkında daha fazla ayrıntıyı [burada](https://www.regular-expressions.info/tutorial.html) bulabilirsiniz.", "NotificationsTwitterSettingsDirectMessageHelpText": "Herkese açık mesaj yerine doğrudan mesaj gönderin", "NzbgetHistoryItemMessage": "PAR Durumu: {parStatus} - Paketten Çıkarma Durumu: {unpackStatus} - Taşıma Durumu: {moveStatus} - Komut Dosyası Durumu: {scriptStatus} - Silme Durumu: {deleteStatus} - İşaretleme Durumu: {markStatus}", "OneMinute": "1 dakika", @@ -1664,7 +1664,7 @@ "RemoveSelectedItemsQueueMessageText": "{selectedCount} öğeyi kuyruktan kaldırmak istediğinizden emin misiniz?", "RemoveSelectedBlocklistMessageText": "Seçilen öğeleri engellenenler listesinden kaldırmak istediğinizden emin misiniz?", "RemoveTagsAutomatically": "Otomatik Etiketlemeyi Kaldır", - "RemotePathMappingsInfo": "Uzak Yol Eşlemeleri çok nadiren gereklidir, {appName} ve indirme istemciniz aynı sistemdeyse yollarınızı eşleştirmeniz daha iyidir. Daha fazla bilgi için [wiki]({wikiLink}) adresini ziyaret edin", + "RemotePathMappingsInfo": "Uzak Yol Eşlemeleri çok nadiren gereklidir, {appName} ve indirme istemciniz aynı sistemdeyse yollarınızı eşleştirmeniz daha iyidir. Daha fazla bilgi için [wiki]({wikiLink}) adresini ziyaret edin.", "ResetDefinitions": "Tanımları Sıfırla", "UpdateFiltered": "Filtrelenenleri Güncelle", "RemoveFailedDownloads": "Başarısız İndirmeleri Kaldır", @@ -1866,5 +1866,9 @@ "ManageFormats": "Formatları Yönet", "MetadataKometaDeprecatedSetting": "Kullanım Dışı", "MetadataKometaDeprecated": "Kometa dosyaları artık oluşturulmayacak, destek v6'da tamamen kaldırılacak", - "NotificationsSettingsWebhookHeaders": "Başlıklar" + "NotificationsSettingsWebhookHeaders": "Başlıklar", + "NotificationsTelegramSettingsIncludeInstanceName": "Başlığa Örnek Adını Dahil Et", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "İsteğe bağlı olarak Örnek adını bildirime ekleyin", + "NotificationsTelegramSettingsMetadataLinks": "Meta Veri Bağlantıları", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Bildirim gönderirken film meta verilerine bir bağlantı ekleyin" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 2bfc8bc84c..78bedaee2d 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1865,5 +1865,7 @@ "ManageFormats": "管理格式", "NotificationsSettingsWebhookHeaders": "标头", "Warning": "警告", - "MetadataKometaDeprecatedSetting": "弃用" + "MetadataKometaDeprecatedSetting": "弃用", + "NotificationsTelegramSettingsMetadataLinks": "元数据链接", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "添加一个在发送通知时指向电影元数据的链接" } From 99c3c8ce5b03fc75b620e54fc6e96fbee3a2053c Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Tue, 27 Feb 2024 05:30:58 +0000 Subject: [PATCH 139/579] Replace URLs in translations with tokens (cherry picked from commit 98d60e1a8e9abce6b31b3cdd745eff0fed181458) --- .../Specifications/EditSpecificationModalContent.js | 4 ++-- .../Specifications/EditSpecificationModalContent.js | 4 ++-- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 4 ++-- src/NzbDrone.Core/Localization/Core/en.json | 4 ++-- src/NzbDrone.Core/Localization/Core/es.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fi.json | 4 ++-- src/NzbDrone.Core/Localization/Core/fr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt_BR.json | 4 ++-- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 4 ++-- src/NzbDrone.Core/Localization/Core/zh_CN.json | 4 ++-- 16 files changed, 26 insertions(+), 26 deletions(-) diff --git a/frontend/src/Settings/CustomFormats/CustomFormats/Specifications/EditSpecificationModalContent.js b/frontend/src/Settings/CustomFormats/CustomFormats/Specifications/EditSpecificationModalContent.js index 8558326201..71f3cffa95 100644 --- a/frontend/src/Settings/CustomFormats/CustomFormats/Specifications/EditSpecificationModalContent.js +++ b/frontend/src/Settings/CustomFormats/CustomFormats/Specifications/EditSpecificationModalContent.js @@ -55,10 +55,10 @@ function EditSpecificationModalContent(props) {
- +
- +
} diff --git a/frontend/src/Settings/Tags/AutoTagging/Specifications/EditSpecificationModalContent.js b/frontend/src/Settings/Tags/AutoTagging/Specifications/EditSpecificationModalContent.js index 2ab1e4a1cd..04302729be 100644 --- a/frontend/src/Settings/Tags/AutoTagging/Specifications/EditSpecificationModalContent.js +++ b/frontend/src/Settings/Tags/AutoTagging/Specifications/EditSpecificationModalContent.js @@ -86,10 +86,10 @@ function EditSpecificationModalContent(props) {
- +
- +
} diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 1cce9a1a15..41fe487554 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -711,7 +711,7 @@ "RefreshLists": "Actualitza llistes", "RefreshMonitoredIntervalHelpText": "Amb quina freqüència s'actualitzen les baixades monitorades dels clients de descàrrega, mínim 1 minut", "RefreshMovie": "Actualitza pel·lícula", - "RegularExpressionsCanBeTested": "Les expressions regulars es poden provar [aquí](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Les expressions regulars es poden provar [aquí]({url}).", "RejectionCount": "Recompte de rebuigs", "RelativePath": "Camí relatiu", "ReleaseBranchCheckOfficialBranchMessage": "La branca {0} no és una branca de llançament de {appName} vàlida, no rebreu actualitzacions", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index cdb8098580..4d7da10167 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -310,7 +310,7 @@ "RecyclingBinCleanup": "Oprydning af papirkurven", "Refresh": "Opdater", "RefreshMovie": "Opdater film", - "RegularExpressionsCanBeTested": "Regulære udtryk kan testes [her](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Regulære udtryk kan testes [her]({url}).", "RejectionCount": "Afvisningstal", "RelativePath": "Relativ sti", "Released": "Udgivet", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index d478e3501e..b9b4c23ff3 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -658,7 +658,7 @@ "AddConditionError": "Die neue Bedingung konnte nicht hinzugefügt werden, bitte erneut probieren.", "FileBrowserPlaceholderText": "Beginne mit der Eingabe oder wähle unten einen Pfad aus", "Restore": "Wiederherstellen", - "RegularExpressionsCanBeTested": "Reguläre Ausdrücke können [hier](http://regexstorm.net/tester) getestet werden.", + "RegularExpressionsCanBeTested": "Reguläre Ausdrücke können [hier]({url}) getestet werden.", "SupportedCustomConditions": "{appName} unterstützt benutzerdefinierte Bedingungen für die Release-Eigenschaften unten.", "SupportedListsMovie": "RSS Film Listen sowie unten aufgelistete werden untertützt.", "SupportedIndexers": "{appName} unterstützt jeden Indexer, der den Newznab-Standard verwendet, sowie andere Indexer, die unten aufgelistet sind.", @@ -1317,7 +1317,7 @@ "EditIndexerImplementation": "Indexer bearbeiten - {implementationName}", "Lists": "Listen", "MustNotContainHelpText": "Das Release wird abgelehnt, wenn einer oder mehrere dieser Begriffe enthalten sind (Groß- und Kleinschreibung ignorieren)", - "RegularExpressionsTutorialLink": "Weitere Details zu regulären Ausdrücken finden Sie [hier](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "Weitere Details zu regulären Ausdrücken finden Sie [hier]({url}).", "Release": "Veröffentlichung", "Space": "Platz", "TablePageSize": "Seitengröße", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 3a55611ff0..cff52025f1 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1422,8 +1422,8 @@ "RefreshLists": "Refresh Lists", "RefreshMonitoredIntervalHelpText": "How often to refresh monitored downloads from download clients, minimum 1 minute", "RefreshMovie": "Refresh movie", - "RegularExpressionsCanBeTested": "Regular expressions can be tested [here](http://regexstorm.net/tester).", - "RegularExpressionsTutorialLink": "More details on regular expressions can be found [here](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsCanBeTested": "Regular expressions can be tested [here]({url}).", + "RegularExpressionsTutorialLink": "More details on regular expressions can be found [here]({url}).", "RejectionCount": "Rejection Count", "Rejections": "Rejections", "RelativePath": "Relative Path", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 2317dbe9c8..6a935434a7 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -661,7 +661,7 @@ "TagIsNotUsedAndCanBeDeleted": "La etiqueta no se usa y puede ser borrada", "FileBrowserPlaceholderText": "Comienza a escribir o selecciona una ruta debajo", "Restore": "Restaurar", - "RegularExpressionsCanBeTested": "Las expresiones regulares pueden ser probadas [aquí](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Las expresiones regulares pueden ser probadas [aquí]({url}).", "SupportedListsMovie": "{appName} soporta cualquier lista RSS de películas, como también la listada debajo.", "SupportedIndexers": "{appName} soporta cualquier indexador que use el estándar Newznab, así como otros indexadores listados a continuación.", "SupportedDownloadClients": "{appName} soporta muchos torrent populares y clientes de descarga de usenet.", @@ -1745,7 +1745,7 @@ "Underscore": "Guion bajo", "AddDelayProfileError": "No se pudo añadir un nuevo perfil de retraso, por favor inténtalo de nuevo.", "ChownGroup": "chown del grupo", - "RegularExpressionsTutorialLink": "Más detalles de las expresiones regulares pueden ser encontrados [aquí](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "Más detalles de las expresiones regulares pueden ser encontrados [aquí]({url}).", "ReleaseGroupFootNote": "Opcionalmente controla el truncamiento hasta un número máximo de bytes, incluyendo elipsis (`...`). Está soportado truncar tanto desde el final (p. ej. `{Grupo de lanzamiento:30}`) como desde el principio (p. ej. `{Grupo de lanzamiento:-30}`).", "EditionFootNote": "Opcionalmente controla el truncamiento hasta un número máximo de bytes, incluyendo elipsis (`...`). Está soportado truncar tanto desde el final (p. ej. `{Etiquetas de edición:30}`) como desde el principio (p. ej. `{Etiquetas de edición:-30}`).", "MovieFootNote": "Opcionalmente controla el truncamiento hasta un número máximo de bytes, incluyendo elipsis (`...`). Está soportado truncar tanto desde el final (p. ej. `{Título de película:30}`) como desde el principio (p. ej. `{Título de película:-30}`).", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 6d3897c77b..76a358940d 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -232,7 +232,7 @@ "ReadTheWikiForMoreInformation": "Wikistä löydät lisää tietoja", "Reason": "Syy", "Refresh": "Päivitä", - "RegularExpressionsCanBeTested": "Säännöllisiä lausekkeita voidaan testata [täällä](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Säännöllisiä lausekkeita voidaan testata [täällä]({url}).", "New": "Uutta", "LocalPath": "Paikallinen sijainti", "RemotePath": "Kaukopolku", @@ -1695,7 +1695,7 @@ "RestartLater": "Käynnistän uudelleen myöhemmin", "Repack": "Uudelleenpaketoitu", "Release": "Julkaisu", - "RegularExpressionsTutorialLink": "Lisätietoja säännöllisistä lausekkeista löytyy [täältä](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "Lisätietoja säännöllisistä lausekkeista löytyy [täältä]({url}).", "ReleaseProfileIndexerHelpText": "Määritä mitä tietolähdettä profiili koskee.", "ReleaseProfileTagMovieHelpText": "Julkaisuprofiileja sovelletaan elokuviin, jotka on merkitty ainakin yhdellä vastaavalla tunnisteella. Käytä kaikille elokuville jättämällä tyhjäksi.", "SearchMoviesOnAdd": "Etsi elokuvia kun ne lisätään", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 3ce1506792..5a76364d2a 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -670,7 +670,7 @@ "Remove": "Retirer", "ReleaseRejected": "Libération rejetée", "ReleaseDates": "Date de sortie", - "RegularExpressionsCanBeTested": "Les expressions régulières peuvent être testées [ici](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Les expressions régulières peuvent être testées [ici]({url}).", "RefreshMovie": "Actualiser le film", "RefreshInformationAndScanDisk": "Actualiser les informations et analyser le disque", "RecyclingBinCleanup": "Nettoyage du bac de recyclage", @@ -1669,7 +1669,7 @@ "NoDelay": "Pas de délai", "OptionalName": "Nom facultatif", "Popular": "Populaire", - "RegularExpressionsTutorialLink": "Vous trouverez plus de détails sur les expressions régulières [ici](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "Vous trouverez plus de détails sur les expressions régulières [ici]({url}).", "Trending": "Tendance", "TypeOfList": "{typeOfList} Liste", "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Vous devez vous connecter à votre poste de travail en tant que {username} et le configurer manuellement dans les paramètres de la DownloadStation sous BT/HTTP/FTP/NZB -> Location.", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 14e4d13646..24f414dbb2 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1337,7 +1337,7 @@ "RemoveTagsAutomatically": "Címkék automatikus eltávolítása", "RestartLater": "Később újraindítom", "QualitiesLoadError": "Nem lehet minőségeket betölteni", - "RegularExpressionsTutorialLink": "További részletek a reguláris kifejezésekről [itt](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "További részletek a reguláris kifejezésekről [itt]({url}).", "PasswordConfirmation": "Jelszó megerősítése", "SecretToken": "Titkos token", "AddListExclusion": "Listakizárás hozzáadása", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 70326e45ec..94b1043d3b 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -409,7 +409,7 @@ "ReleaseRejected": "Release rifiutata", "ReleaseDates": "Date di rilascio", "RejectionCount": "Rifiuta il conteggio", - "RegularExpressionsCanBeTested": "Le espressioni regolari possono essere testate [qui](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Le espressioni regolari possono essere testate [qui]({url}).", "RefreshMovie": "Aggiorna il Film", "RefreshInformationAndScanDisk": "Aggiorna le informazioni e scansiona il disco", "RecyclingBinCleanup": "Pulizia Cestino", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 0963f311a3..41ca4bebe4 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -662,7 +662,7 @@ "AddDownloadClientError": "Kon geen nieuwe downloader toevoegen, gelieve opnieuw te proberen.", "AddCustomFormatError": "Kon geen nieuw eigen formaat toevoegen, gelieve opnieuw te proberen.", "AddConditionError": "Kon geen nieuwe conditie toevoegen, gelieve opnieuw te proberen.", - "RegularExpressionsCanBeTested": "Reguliere expressies kunnen [hier] worden getest (http:://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Reguliere expressies kunnen [hier] worden getest ({url}).", "SupportedCustomConditions": "{appName} ondersteunt aangepaste condities tegenover de uitgave eigenschappen hieronder.", "SupportedListsMovie": "{appName} ondersteunt elke RSS filmlijst, tevens ook de ander hieronder weergegeven lijsten.", "SupportedIndexers": "{appName} ondersteund elke indexeerder die gebruik maakt van de Newznab standaard, tevens ook de ander hieronder weergegeven indexeerders.", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index f1c8e078f8..914d27cfd2 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -747,7 +747,7 @@ "ReleasedMovieDescription": "Filme lançado", "ReleaseDates": "Datas de lançamento", "RelativePath": "Caminho relativo", - "RegularExpressionsCanBeTested": "Expressões regulares podem ser testadas [aqui](http://regexstorm.net/tester).", + "RegularExpressionsCanBeTested": "Expressões regulares podem ser testadas [aqui]({url}).", "RefreshMovie": "Atualizar filme", "RefreshLists": "Atualizar listas", "RefreshInformationAndScanDisk": "Atualizar as informações e verificar o disco", @@ -1711,7 +1711,7 @@ "DelayProfileProtocol": "Protocolo: {preferredProtocol}", "DeleteReleaseProfile": "Excluir perfil de lançamento", "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages suporta um sufixo `:EN+DE` permitindo filtrar os idiomas incluídos no nome do arquivo. Use `-DE` para excluir idiomas específicos. Anexar `+` (por exemplo, `:EN+`) resultará em `[EN]`/`[EN+--]`/`[--]` dependendo dos idiomas excluídos. Por exemplo, `{MediaInfo Full:EN+DE}`.", - "RegularExpressionsTutorialLink": "Mais detalhes sobre expressões regulares podem ser encontrados [aqui](https://www.regular-expressions.info/tutorial.html).", + "RegularExpressionsTutorialLink": "Mais detalhes sobre expressões regulares podem ser encontrados [aqui]({url}).", "RestartRequiredToApplyChanges": "{appName} requer reinicialização para aplicar as alterações. Deseja reiniciar agora?", "SupportedAutoTaggingProperties": "{appName} oferece suporte às propriedades a seguir para regras de codificação automática", "WantMoreControlAddACustomFormat": "Quer mais controle sobre quais downloads são preferidos? Adicione um [Formato Personalizado](/settings/customformats)", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 0b95a75c4f..b5e0c40349 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -288,7 +288,7 @@ "SupportedListsMoreInfo": "Pentru mai multe informații despre listele de import individuale, faceți clic pe butoanele de informații.", "LogLevelTraceHelpTextWarning": "Înregistrarea urmăririi trebuie activată doar temporar", "Lowercase": "Minuscule", - "MappedNetworkDrivesWindowsService": "Unitățile de rețea mapate nu sunt disponibile atunci când rulează ca serviciu Windows. Vă rugăm să consultați FAQ pentru mai multe informații", + "MappedNetworkDrivesWindowsService": "Unitățile de rețea mapate nu sunt disponibile atunci când rulează ca serviciu Windows. Vă rugăm să consultați [FAQ]({url}) pentru mai multe informații", "MinutesHundredTwenty": "120 de minute: {0}", "MinutesNinety": "90 de minute: {0}", "Months": "Luni", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index fe0ca841aa..8d10a1bf31 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -478,7 +478,7 @@ "OnlyUsenet": "Sadece Usenet", "PendingChangesMessage": "Kaydedilmemiş değişiklikleriniz var, bu sayfadan ayrılmak istediğinizden emin misiniz?", "ProxyType": "Proxy Türü", - "RegularExpressionsCanBeTested": "Düzenli ifadeler [burada](http://regexstorm.net/tester) test edilebilir.", + "RegularExpressionsCanBeTested": "Düzenli ifadeler [burada]({url}) test edilebilir.", "ShowGenres": "Türleri Göster", "UpgradesAllowed": "Yükseltmelere İzin Ver", "Pending": "Bekliyor", @@ -1605,7 +1605,7 @@ "NotificationsValidationUnableToConnectToApi": "{service} API'sine bağlanılamıyor. Sunucu bağlantısı başarısız oldu: ({responseCode}) {exceptionMessage}", "Recommendation": "Öneri", "Recommended": "Önerilen", - "RegularExpressionsTutorialLink": "Düzenli ifadeler hakkında daha fazla ayrıntıyı [burada](https://www.regular-expressions.info/tutorial.html) bulabilirsiniz.", + "RegularExpressionsTutorialLink": "Düzenli ifadeler hakkında daha fazla ayrıntıyı [burada]({url}) bulabilirsiniz.", "NotificationsTwitterSettingsDirectMessageHelpText": "Herkese açık mesaj yerine doğrudan mesaj gönderin", "NzbgetHistoryItemMessage": "PAR Durumu: {parStatus} - Paketten Çıkarma Durumu: {unpackStatus} - Taşıma Durumu: {moveStatus} - Komut Dosyası Durumu: {scriptStatus} - Silme Durumu: {deleteStatus} - İşaretleme Durumu: {markStatus}", "OneMinute": "1 dakika", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 78bedaee2d..e71fa99e01 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -802,7 +802,7 @@ "PreviewRenameHelpText": "小提示:要预览重命名效果,选择 “取消” ,然后点击任何电影标题并使用", "PtpOldSettingsCheckMessage": "以下 PassThePopcorn 索引器的设置已弃用,应更新为:{0}", "QualityDefinitions": "质量定义", - "RegularExpressionsCanBeTested": "正则表达式可在 [此处](http://regexstorm.net/tester) 测试。", + "RegularExpressionsCanBeTested": "正则表达式可在 [此处]({url}) 测试。", "ReleaseTitle": "发布资源标题", "RemoveHelpTextWarning": "移除操作会从下载客户端中删除任务和已下载文件。", "RequiredRestrictionHelpText": "发布资源必须至少包含这些项目之一(不区分大小写)", @@ -1588,7 +1588,7 @@ "OptionalName": "可选名称", "Period": "时期", "QualityCutoffNotMet": "未达到质量阈值", - "RegularExpressionsTutorialLink": "有关正则表达式的更多详细信息,请参阅[此处](https://www.regular-expressions.info/tutorial.html)。", + "RegularExpressionsTutorialLink": "有关正则表达式的更多详细信息,请参阅[此处]({url})。", "RestartLater": "稍后重启", "RestartRequiredWindowsService": "根据运行{appName}的用户,在服务自动启动之前,您可能需要以管理员身份重新启动{appName}一次。", "IndexerSettingsMultiLanguageRelease": "多种语言", From 1d21bbf78f69ed8996334d6db43d673681fd353e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 16 Dec 2024 20:24:54 +0200 Subject: [PATCH 140/579] Bump version to 5.17.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index a207651a1b..e065c33f0c 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.16.3' + majorVersion: '5.17.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From aae68e681ea83c78baf078979b700b7ee9bd9e79 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 15 Dec 2024 08:44:18 -0800 Subject: [PATCH 141/579] Upgrade babel to 7.26.0 (cherry picked from commit bfcd017012730c97eb587ae2d2e91f72ee7a1de3) --- package.json | 12 +- yarn.lock | 1245 +++++++++++++++++++++++++++----------------------- 2 files changed, 668 insertions(+), 589 deletions(-) diff --git a/package.json b/package.json index afe89811c7..2f7e97f40d 100644 --- a/package.json +++ b/package.json @@ -87,13 +87,13 @@ "typescript": "5.7.2" }, "devDependencies": { - "@babel/core": "7.25.8", - "@babel/eslint-parser": "7.25.8", - "@babel/plugin-proposal-export-default-from": "7.25.8", + "@babel/core": "7.26.0", + "@babel/eslint-parser": "7.25.9", + "@babel/plugin-proposal-export-default-from": "7.25.9", "@babel/plugin-syntax-dynamic-import": "7.8.3", - "@babel/preset-env": "7.25.8", - "@babel/preset-react": "7.25.7", - "@babel/preset-typescript": "7.25.7", + "@babel/preset-env": "7.26.0", + "@babel/preset-react": "7.26.3", + "@babel/preset-typescript": "7.26.0", "@types/lodash": "4.14.195", "@types/react-document-title": "2.0.10", "@types/react-lazyload": "3.2.3", diff --git a/yarn.lock b/yarn.lock index 67383b1666..39d3ddd5c9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,7 +15,7 @@ "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.24" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7", "@babel/code-frame@^7.25.7": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.16.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.25.7.tgz#438f2c524071531d643c6f0188e1e28f130cebc7" integrity sha512-0xZJFNE5XMpENsgfHYTw8FbX4kv53mFLn2i3XPoq69LyhYSCBJtitaHx9QnsVTrsogI4Z3+HtEfZ2/GFPOtf5g== @@ -23,47 +23,62 @@ "@babel/highlight" "^7.25.7" picocolors "^1.0.0" -"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7", "@babel/compat-data@^7.25.8": +"@babel/code-frame@^7.25.9", "@babel/code-frame@^7.26.0", "@babel/code-frame@^7.26.2": + version "7.26.2" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.26.2.tgz#4b5fab97d33338eff916235055f0ebc21e573a85" + integrity sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ== + dependencies: + "@babel/helper-validator-identifier" "^7.25.9" + js-tokens "^4.0.0" + picocolors "^1.0.0" + +"@babel/compat-data@^7.22.6", "@babel/compat-data@^7.25.7": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.25.8.tgz#0376e83df5ab0eb0da18885c0140041f0747a402" integrity sha512-ZsysZyXY4Tlx+Q53XdnOFmqwfB9QDTHYxaZYajWRoBLuLEAwI2UIbtxOjWh/cFaa9IKUlcB+DDuoskLuKu56JA== -"@babel/core@7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.25.8.tgz#a57137d2a51bbcffcfaeba43cb4dd33ae3e0e1c6" - integrity sha512-Oixnb+DzmRT30qu9d3tJSQkxuygWm32DFykT4bRoORPa9hZ/L4KhVB/XiRm6KG+roIEM7DBQlmg27kw2HZkdZg== +"@babel/compat-data@^7.25.9", "@babel/compat-data@^7.26.0": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.26.3.tgz#99488264a56b2aded63983abd6a417f03b92ed02" + integrity sha512-nHIxvKPniQXpmQLb0vhY3VaFb3S0YrTAwpOWJZh1wn3oJPjJk9Asva204PsBdmAE8vpzfHudT8DB0scYvy9q0g== + +"@babel/core@7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.26.0.tgz#d78b6023cc8f3114ccf049eb219613f74a747b40" + integrity sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg== dependencies: "@ampproject/remapping" "^2.2.0" - "@babel/code-frame" "^7.25.7" - "@babel/generator" "^7.25.7" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helpers" "^7.25.7" - "@babel/parser" "^7.25.8" - "@babel/template" "^7.25.7" - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.8" + "@babel/code-frame" "^7.26.0" + "@babel/generator" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helpers" "^7.26.0" + "@babel/parser" "^7.26.0" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.26.0" convert-source-map "^2.0.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.2.3" semver "^6.3.1" -"@babel/eslint-parser@7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.8.tgz#0119dec46be547d7a339978dedb9d29e517c2443" - integrity sha512-Po3VLMN7fJtv0nsOjBDSbO1J71UhzShE9MuOSkWEV9IZQXzhZklYtzKZ8ZD/Ij3a0JBv1AG3Ny2L3jvAHQVOGg== +"@babel/eslint-parser@7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.25.9.tgz#603c68a63078796527bc9d0833f5e52dd5f9224c" + integrity sha512-5UXfgpK0j0Xr/xIdgdLEhOFxaDZ0bRPWJJchRpqOSur/3rZoPbqqki5mm0p4NE2cs28krBEiSM2MB7//afRSQQ== dependencies: "@nicolo-ribaudo/eslint-scope-5-internals" "5.1.1-v1" eslint-visitor-keys "^2.1.0" semver "^6.3.1" -"@babel/generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.25.7.tgz#de86acbeb975a3e11ee92dd52223e6b03b479c56" - integrity sha512-5Dqpl5fyV9pIAD62yK9P7fcA768uVPUyrQmqpqstHWgMma4feF1x/oFysBCVZLY5wJ2GkMUCdsNDnGZrPoR6rA== +"@babel/generator@^7.26.0", "@babel/generator@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.26.3.tgz#ab8d4360544a425c90c248df7059881f4b2ce019" + integrity sha512-6FF/urZvD0sTeO7k6/B15pMLC4CHUv1426lzr3N01aHJTl046uCAh9LXW/fzeXXjPNCJ6iABW5XaWOsIZB93aQ== dependencies: - "@babel/types" "^7.25.7" + "@babel/parser" "^7.26.3" + "@babel/types" "^7.26.3" "@jridgewell/gen-mapping" "^0.3.5" "@jridgewell/trace-mapping" "^0.3.25" jsesc "^3.0.2" @@ -75,15 +90,14 @@ dependencies: "@babel/types" "^7.25.7" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.25.7.tgz#d721650c1f595371e0a23ee816f1c3c488c0d622" - integrity sha512-12xfNeKNH7jubQNm7PAkzlLwEmCs1tfuX3UjIw6vP6QXi+leKh6+LyC/+Ed4EIQermwd58wsyh070yjDHFlNGg== +"@babel/helper-annotate-as-pure@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.25.9.tgz#d8eac4d2dc0d7b6e11fa6e535332e0d3184f06b4" + integrity sha512-gv7320KBUFJz1RnylIg5WWYPRXKZ884AGkYpgpWW02TH66Dl+HaC1t1CKd0z3R4b6hdYEcmrNZHUmfCP+1u3/g== dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/types" "^7.25.9" -"@babel/helper-compilation-targets@^7.22.6", "@babel/helper-compilation-targets@^7.25.7": +"@babel/helper-compilation-targets@^7.22.6": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.7.tgz#11260ac3322dda0ef53edfae6e97b961449f5fa4" integrity sha512-DniTEax0sv6isaw6qSQSfV4gVRNtw2rte8HHM45t9ZR0xILaufBRNkpMifCRiAPyvL4ACD6v0gfCwCmtOQaV4A== @@ -94,20 +108,31 @@ lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-class-features-plugin@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.7.tgz#5d65074c76cae75607421c00d6bd517fe1892d6b" - integrity sha512-bD4WQhbkx80mAyj/WCm4ZHcF4rDxkoLFO6ph8/5/mQ3z4vAzltQXAmbc7GvVJx5H+lk5Mi5EmbTeox5nMGCsbw== +"@babel/helper-compilation-targets@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.25.9.tgz#55af025ce365be3cdc0c1c1e56c6af617ce88875" + integrity sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-member-expression-to-functions" "^7.25.7" - "@babel/helper-optimise-call-expression" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/compat-data" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + browserslist "^4.24.0" + lru-cache "^5.1.1" semver "^6.3.1" -"@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.25.7": +"@babel/helper-create-class-features-plugin@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.25.9.tgz#7644147706bb90ff613297d49ed5266bde729f83" + integrity sha512-UTZQMvt0d/rSz6KI+qdu7GQze5TIajwTS++GUozlw8VBJDEOAqSXwm1WvmYEZwqdqSGQshRocPDqrt4HBZB3fQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/traverse" "^7.25.9" + semver "^6.3.1" + +"@babel/helper-create-regexp-features-plugin@^7.18.6": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.25.7.tgz#dcb464f0e2cdfe0c25cc2a0a59c37ab940ce894e" integrity sha512-byHhumTj/X47wJ6C6eLpK7wW/WBEcnUeb7D0FNc/jFQnQVw7DOso3Zz5u9x/zLrFVkHa89ZGDbkAa1D54NdrCQ== @@ -116,6 +141,15 @@ regexpu-core "^6.1.1" semver "^6.3.1" +"@babel/helper-create-regexp-features-plugin@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.26.3.tgz#5169756ecbe1d95f7866b90bb555b022595302a0" + integrity sha512-G7ZRb40uUgdKOQqPLjfD12ZmGA54PzqDFUv2BKImnC9QIfGhIHKvVML0oN8IUiDq4iRqpq74ABpvOaerfWdong== + dependencies: + "@babel/helper-annotate-as-pure" "^7.25.9" + regexpu-core "^6.2.0" + semver "^6.3.1" + "@babel/helper-define-polyfill-provider@^0.6.2": version "0.6.2" resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.6.2.tgz#18594f789c3594acb24cfdb4a7f7b7d2e8bd912d" @@ -127,109 +161,120 @@ lodash.debounce "^4.0.8" resolve "^1.14.2" -"@babel/helper-member-expression-to-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.7.tgz#541a33b071f0355a63a0fa4bdf9ac360116b8574" - integrity sha512-O31Ssjd5K6lPbTX9AAYpSKrZmLeagt9uwschJd+Ixo6QiRyfpvgtVQp8qrDR9UNFjZ8+DO34ZkdrN+BnPXemeA== +"@babel/helper-member-expression-to-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.25.9.tgz#9dfffe46f727005a5ea29051ac835fb735e4c1a3" + integrity sha512-wbfdZ9w5vk0C0oyHqAJbc62+vet5prjj01jjJ8sKn3j9h3MQQlflEdXYvuqRWjHnM12coDEqiC1IRCi0U/EKwQ== dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/helper-module-imports@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.7.tgz#dba00d9523539152906ba49263e36d7261040472" - integrity sha512-o0xCgpNmRohmnoWKQ0Ij8IdddjyBFE4T2kagL/x6M3+4zUgc+4qTOUBoNe4XxDskt1HPKO007ZPiMgLDq2s7Kw== +"@babel/helper-module-imports@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.25.9.tgz#e7f8d20602ebdbf9ebbea0a0751fb0f2a4141715" + integrity sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw== dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/helper-module-transforms@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.25.7.tgz#2ac9372c5e001b19bc62f1fe7d96a18cb0901d1a" - integrity sha512-k/6f8dKG3yDz/qCwSM+RKovjMix563SLxQFo0UhRNo239SP6n9u5/eLtKD6EAjwta2JHJ49CsD8pms2HdNiMMQ== +"@babel/helper-module-transforms@^7.25.9", "@babel/helper-module-transforms@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.26.0.tgz#8ce54ec9d592695e58d84cd884b7b5c6a2fdeeae" + integrity sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw== dependencies: - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-simple-access" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/helper-optimise-call-expression@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.7.tgz#1de1b99688e987af723eed44fa7fc0ee7b97d77a" - integrity sha512-VAwcwuYhv/AT+Vfr28c9y6SHzTan1ryqrydSTFGjU0uDJHw3uZ+PduI8plCLkRsDnqK2DMEDmwrOQRsK/Ykjng== +"@babel/helper-optimise-call-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.25.9.tgz#3324ae50bae7e2ab3c33f60c9a877b6a0146b54e" + integrity sha512-FIpuNaz5ow8VyrYcnXQTDRGvV6tTjkNtCK/RYNDXGSLlUD6cBuQTSw43CShGxjvfBTfcUA/r6UhUCbtYqkhcuQ== dependencies: - "@babel/types" "^7.25.7" + "@babel/types" "^7.25.9" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.25.7", "@babel/helper-plugin-utils@^7.8.0": +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.18.6", "@babel/helper-plugin-utils@^7.22.5", "@babel/helper-plugin-utils@^7.8.0": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.7.tgz#8ec5b21812d992e1ef88a9b068260537b6f0e36c" integrity sha512-eaPZai0PiqCi09pPs3pAFfl/zYgGaE6IdXtYvmf0qlcDTd3WCtO7JWCcRd64e0EQrcYgiHibEZnOGsSY4QSgaw== -"@babel/helper-remap-async-to-generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.7.tgz#9efdc39df5f489bcd15533c912b6c723a0a65021" - integrity sha512-kRGE89hLnPfcz6fTrlNU+uhgcwv0mBE4Gv3P9Ke9kLVJYpi4AMVVEElXvB5CabrPZW4nCM8P8UyyjrzCM0O2sw== - dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-wrap-function" "^7.25.7" - "@babel/traverse" "^7.25.7" +"@babel/helper-plugin-utils@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.25.9.tgz#9cbdd63a9443a2c92a725cca7ebca12cc8dd9f46" + integrity sha512-kSMlyUVdWe25rEsRGviIgOWnoT/nfABVWlqt9N19/dIPWViAOW2s9wznP5tURbs/IDuNk4gPy3YdYRgH3uxhBw== -"@babel/helper-replace-supers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.7.tgz#38cfda3b6e990879c71d08d0fef9236b62bd75f5" - integrity sha512-iy8JhqlUW9PtZkd4pHM96v6BdJ66Ba9yWSE4z0W4TvSZwLBPkyDsiIU3ENe4SmrzRBs76F7rQXTy1lYC49n6Lw== +"@babel/helper-remap-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.25.9.tgz#e53956ab3d5b9fb88be04b3e2f31b523afd34b92" + integrity sha512-IZtukuUeBbhgOcaW2s06OXTzVNJR0ybm4W5xC1opWFFJMZbwRj5LCk+ByYH7WdZPZTt8KnFwA8pvjN2yqcPlgw== dependencies: - "@babel/helper-member-expression-to-functions" "^7.25.7" - "@babel/helper-optimise-call-expression" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-wrap-function" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/helper-simple-access@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.25.7.tgz#5eb9f6a60c5d6b2e0f76057004f8dacbddfae1c0" - integrity sha512-FPGAkJmyoChQeM+ruBGIDyrT2tKfZJO8NcxdC+CWNJi7N8/rZpSxK7yvBJ5O/nF1gfu5KzN7VKG3YVSLFfRSxQ== +"@babel/helper-replace-supers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.25.9.tgz#ba447224798c3da3f8713fc272b145e33da6a5c5" + integrity sha512-IiDqTOTBQy0sWyeXyGSC5TBJpGFXBkRynjBeXsvbhQFKj2viwJC76Epz35YLU1fpe/Am6Vppb7W7zM4fPQzLsQ== dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/helper-member-expression-to-functions" "^7.25.9" + "@babel/helper-optimise-call-expression" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/helper-skip-transparent-expression-wrappers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.7.tgz#382831c91038b1a6d32643f5f49505b8442cb87c" - integrity sha512-pPbNbchZBkPMD50K0p3JGcFMNLVUCuU/ABybm/PGNj4JiHrpmNyqqCphBk4i19xXtNV0JhldQJJtbSW5aUvbyA== +"@babel/helper-skip-transparent-expression-wrappers@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.25.9.tgz#0b2e1b62d560d6b1954893fd2b705dc17c91f0c9" + integrity sha512-K4Du3BFa3gvyhzgPcntrkDgZzQaq6uozzcpGbOO1OEJaI+EJdqWIMTLgFgQf6lrfiDFo5FU+BxKepI9RmZqahA== dependencies: - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" "@babel/helper-string-parser@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.7.tgz#d50e8d37b1176207b4fe9acedec386c565a44a54" integrity sha512-CbkjYdsJNHFk8uqpEkpCvRs3YRp9tY6FmFY7wLMSYuGYkrdUi7r2lc4/wqsvlHoMznX3WJ9IP8giGPq68T/Y6g== +"@babel/helper-string-parser@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.25.9.tgz#1aabb72ee72ed35789b4bbcad3ca2862ce614e8c" + integrity sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA== + "@babel/helper-validator-identifier@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.7.tgz#77b7f60c40b15c97df735b38a66ba1d7c3e93da5" integrity sha512-AM6TzwYqGChO45oiuPqwL2t20/HdMC1rTPAesnBCgPCSF1x3oN9MVUwQV2iyz4xqWrctwK5RNC8LV22kaQCNYg== +"@babel/helper-validator-identifier@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.25.9.tgz#24b64e2c3ec7cd3b3c547729b8d16871f22cbdc7" + integrity sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ== + "@babel/helper-validator-option@^7.25.7": version "7.25.7" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.7.tgz#97d1d684448228b30b506d90cace495d6f492729" integrity sha512-ytbPLsm+GjArDYXJ8Ydr1c/KJuutjF2besPNbIZnZ6MKUxi/uTA22t2ymmA4WFjZFpjiAMO0xuuJPqK2nvDVfQ== -"@babel/helper-wrap-function@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.7.tgz#9f6021dd1c4fdf4ad515c809967fc4bac9a70fe7" - integrity sha512-MA0roW3JF2bD1ptAaJnvcabsVlNQShUaThyJbCDD4bCp8NEgiFvpoqRI2YS22hHlc2thjO/fTg2ShLMC3jygAg== - dependencies: - "@babel/template" "^7.25.7" - "@babel/traverse" "^7.25.7" - "@babel/types" "^7.25.7" +"@babel/helper-validator-option@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.25.9.tgz#86e45bd8a49ab7e03f276577f96179653d41da72" + integrity sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw== -"@babel/helpers@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.25.7.tgz#091b52cb697a171fe0136ab62e54e407211f09c2" - integrity sha512-Sv6pASx7Esm38KQpF/U/OXLwPPrdGHNKoeblRxgZRLXnAtnkEe4ptJPDtAZM7fBLadbc1Q07kQpSiGQ0Jg6tRA== +"@babel/helper-wrap-function@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.25.9.tgz#d99dfd595312e6c894bd7d237470025c85eea9d0" + integrity sha512-ETzz9UTjQSTmw39GboatdymDq4XIQbR8ySgVrylRhPOFpsd+JrKHIuF0de7GCWmem+T4uC5z7EZguod7Wj4A4g== dependencies: - "@babel/template" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/template" "^7.25.9" + "@babel/traverse" "^7.25.9" + "@babel/types" "^7.25.9" + +"@babel/helpers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.26.0.tgz#30e621f1eba5aa45fe6f4868d2e9154d884119a4" + integrity sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw== + dependencies: + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.0" "@babel/highlight@^7.25.7": version "7.25.7" @@ -241,58 +286,58 @@ js-tokens "^4.0.0" picocolors "^1.0.0" -"@babel/parser@^7.25.7", "@babel/parser@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.25.8.tgz#f6aaf38e80c36129460c1657c0762db584c9d5e2" - integrity sha512-HcttkxzdPucv3nNFmfOOMfFf64KgdJVqm1KaCm25dPGMLElo9nsLvXeJECQg8UzPuBGLyTSA0ZzqCtDSzKTEoQ== +"@babel/parser@^7.25.9", "@babel/parser@^7.26.0", "@babel/parser@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.26.3.tgz#8c51c5db6ddf08134af1ddbacf16aaab48bac234" + integrity sha512-WJ/CvmY8Mea8iDXo6a7RK2wbmJITT5fN3BEkRuFlxVyNx8jOKIIhmC4fSkTcPcf8JyavbBwIe6OpiCOBXt/IcA== dependencies: - "@babel/types" "^7.25.8" + "@babel/types" "^7.26.3" -"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.7.tgz#93969ac50ef4d68b2504b01b758af714e4cbdd64" - integrity sha512-UV9Lg53zyebzD1DwQoT9mzkEKa922LNUp5YkTJ6Uta0RbyXaQNUgcvSt7qIu1PpPzVb6rd10OVNTzkyBGeVmxQ== +"@babel/plugin-bugfix-firefox-class-in-computed-class-key@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-firefox-class-in-computed-class-key/-/plugin-bugfix-firefox-class-in-computed-class-key-7.25.9.tgz#cc2e53ebf0a0340777fff5ed521943e253b4d8fe" + integrity sha512-ZkRyVkThtxQ/J6nv3JFYv1RYY+JT5BvU0y3k5bWrmuG4woXypRa4PXmm9RhOwodRkYFWqC0C0cqcJ4OqR7kW+g== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.7.tgz#a338d611adb9dcd599b8b1efa200c88ebeffe046" - integrity sha512-GDDWeVLNxRIkQTnJn2pDOM1pkCgYdSqPeT1a9vh9yIqu2uzzgw1zcqEb+IJOhy+dTBMlNdThrDIksr2o09qrrQ== +"@babel/plugin-bugfix-safari-class-field-initializer-scope@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-class-field-initializer-scope/-/plugin-bugfix-safari-class-field-initializer-scope-7.25.9.tgz#af9e4fb63ccb8abcb92375b2fcfe36b60c774d30" + integrity sha512-MrGRLZxLD/Zjj0gdU15dfs+HH/OXvnw/U4jJD8vpcP2CJQapPEv1IWwjc/qMg7ItBlPwSv1hRBbb7LeuANdcnw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.7.tgz#c5f755e911dfac7ef6957300c0f9c4a8c18c06f4" - integrity sha512-wxyWg2RYaSUYgmd9MR0FyRGyeOMQE/Uzr1wzd/g5cf5bwi9A4v6HFdDm7y1MgDtod/fLOSTZY6jDgV0xU9d5bA== +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.25.9.tgz#e8dc26fcd616e6c5bf2bd0d5a2c151d4f92a9137" + integrity sha512-2qUwwfAFpJLZqxd02YW9btUCZHl+RFvdDkNfZwaIJrvB8Tesjsk8pEQkTvGwZXLqXUx/2oyY3ySRhm6HOXuCug== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.7.tgz#3b7ea04492ded990978b6deaa1dfca120ad4455a" - integrity sha512-Xwg6tZpLxc4iQjorYsyGMyfJE7nP5MV8t/Ka58BgiA7Jw0fRqQNcANlLfdJ/yvBt9z9LD2We+BEkT7vLqZRWng== +"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining/-/plugin-bugfix-v8-spread-parameters-in-optional-chaining-7.25.9.tgz#807a667f9158acac6f6164b4beb85ad9ebc9e1d1" + integrity sha512-6xWgLZTJXwilVjlnV7ospI3xi+sl8lN8rXXbBD6vYn3UYDlGsag8wrZkKcSI8G6KgqKP7vNFaDgeDnfAABq61g== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/plugin-transform-optional-chaining" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" -"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.7.tgz#9622b1d597a703aa3a921e6f58c9c2d9a028d2c5" - integrity sha512-UVATLMidXrnH+GMUIuxq55nejlj02HP7F5ETyBONzP6G87fPBogG4CH6kxrSrdIuAjdwNO9VzyaYsrZPscWUrw== +"@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly/-/plugin-bugfix-v8-static-class-fields-redefine-readonly-7.25.9.tgz#de7093f1e7deaf68eadd7cc6b07f2ab82543269e" + integrity sha512-aLnMXYPnzwwqhYSCyXfKkIkYgJ8zv9RK+roo9DkTXz38ynIhd9XCbN08s3MGvqL2MYGVUGdRQLL/JqBIeJhJBg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-proposal-export-default-from@7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.25.8.tgz#fa22151caa240683c3659796037237813767f348" - integrity sha512-5SLPHA/Gk7lNdaymtSVS9jH77Cs7yuHTR3dYj+9q+M7R7tNLXhNuvnmOfafRIzpWL+dtMibuu1I4ofrc768Gkw== +"@babel/plugin-proposal-export-default-from@7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.25.9.tgz#52702be6ef8367fc8f18b8438278332beeb8f87c" + integrity sha512-ykqgwNfSnNOB+C8fV5X4mG3AVmvu+WVxcaU9xHHtBb7PCrPeweMmPjGsn8eMaeJg6SJuoUuZENeeSWaarWqonQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-proposal-private-property-in-object@7.21.0-placeholder-for-preset-env.2": version "7.21.0-placeholder-for-preset-env.2" @@ -306,33 +351,33 @@ dependencies: "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-import-assertions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.25.7.tgz#8ce248f9f4ed4b7ed4cb2e0eb4ed9efd9f52921f" - integrity sha512-ZvZQRmME0zfJnDQnVBKYzHxXT7lYBB3Revz1GuS7oLXWMgqUPX4G+DDbT30ICClht9WKV34QVrZhSw6WdklwZQ== +"@babel/plugin-syntax-import-assertions@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-assertions/-/plugin-syntax-import-assertions-7.26.0.tgz#620412405058efa56e4a564903b79355020f445f" + integrity sha512-QCWT5Hh830hK5EQa7XzuqIkQU9tT/whqbDz7kuaZMHFl1inRRg7JnuAEOQ0Ur0QUl0NufCk1msK2BeY79Aj/eg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-syntax-import-attributes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.25.7.tgz#d78dd0499d30df19a598e63ab895e21b909bc43f" - integrity sha512-AqVo+dguCgmpi/3mYBdu9lkngOBlQ2w2vnNpa6gfiCxQZLzV4ZbhsXitJ2Yblkoe1VQwtHSaNmIaGll/26YWRw== +"@babel/plugin-syntax-import-attributes@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-attributes/-/plugin-syntax-import-attributes-7.26.0.tgz#3b1412847699eea739b4f2602c74ce36f6b0b0f7" + integrity sha512-e2dttdsJ1ZTpi3B9UYGLw41hifAubg19AtCu/2I/F1QNVclOBr1dYpTdmdyZ84Xiz43BS/tCUkMAZNLv12Pi+A== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-syntax-jsx@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.7.tgz#5352d398d11ea5e7ef330c854dea1dae0bf18165" - integrity sha512-ruZOnKO+ajVL/MVx+PwNBPOkrnXTXoWMtte1MBpegfCArhqOe3Bj52avVj1huLLxNKYKXYaSxZ2F+woK1ekXfw== +"@babel/plugin-syntax-jsx@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.25.9.tgz#a34313a178ea56f1951599b929c1ceacee719290" + integrity sha512-ld6oezHQMZsZfp6pWtbjaNDF2tiiCYYDqQszHt5VV437lewP9aSi2Of99CK0D0XB21k7FLgnLcmQKyKzynfeAA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-syntax-typescript@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.7.tgz#bfc05b0cc31ebd8af09964650cee723bb228108b" - integrity sha512-rR+5FDjpCHqqZN2bzZm18bVYGaejGq5ZkpVCJLXor/+zlSrSoc4KWcHI0URVWjl/68Dyr1uwZUz/1njycEAv9g== +"@babel/plugin-syntax-typescript@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.25.9.tgz#67dda2b74da43727cf21d46cf9afef23f4365399" + integrity sha512-hjMgRy5hb8uJJjUcdWunWVcoi9bGpJp8p5Ol1229PoN6aytsLwNMgmdftO23wnCLMfVmTwZDWMPNq/D1SY60JQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" "@babel/plugin-syntax-unicode-sets-regex@^7.18.6": version "7.18.6" @@ -342,498 +387,505 @@ "@babel/helper-create-regexp-features-plugin" "^7.18.6" "@babel/helper-plugin-utils" "^7.18.6" -"@babel/plugin-transform-arrow-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.7.tgz#1b9ed22e6890a0e9ff470371c73b8c749bcec386" - integrity sha512-EJN2mKxDwfOUCPxMO6MUI58RN3ganiRAG/MS/S3HfB6QFNjroAMelQo/gybyYq97WerCBAZoyrAoW8Tzdq2jWg== +"@babel/plugin-transform-arrow-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.25.9.tgz#7821d4410bee5daaadbb4cdd9a6649704e176845" + integrity sha512-6jmooXYIwn9ca5/RylZADJ+EnSxVUS5sjeJ9UPk6RWRzXCmOJCy6dqItPJFpw2cuCangPK4OYr5uhGKcmrm5Qg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-async-generator-functions@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.8.tgz#3331de02f52cc1f2c75b396bec52188c85b0b1ec" - integrity sha512-9ypqkozyzpG+HxlH4o4gdctalFGIjjdufzo7I2XPda0iBnZ6a+FO0rIEQcdSPXp02CkvGsII1exJhmROPQd5oA== +"@babel/plugin-transform-async-generator-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-generator-functions/-/plugin-transform-async-generator-functions-7.25.9.tgz#1b18530b077d18a407c494eb3d1d72da505283a2" + integrity sha512-RXV6QAzTBbhDMO9fWwOmwwTuYaiPbggWQ9INdZqAYeSHyG7FzQ+nOZaUUjNwKv9pV3aE4WFqFm1Hnbci5tBCAw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-remap-async-to-generator" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-async-to-generator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.7.tgz#a44c7323f8d4285a6c568dd43c5c361d6367ec52" - integrity sha512-ZUCjAavsh5CESCmi/xCpX1qcCaAglzs/7tmuvoFnJgA1dM7gQplsguljoTg+Ru8WENpX89cQyAtWoaE0I3X3Pg== +"@babel/plugin-transform-async-to-generator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.25.9.tgz#c80008dacae51482793e5a9c08b39a5be7e12d71" + integrity sha512-NT7Ejn7Z/LjUH0Gv5KsBCxh7BH3fbLTV0ptHvpeMvrt3cPThHfJfst9Wrb7S8EvJ7vRTFI7z+VAvFVEQn/m5zQ== dependencies: - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-remap-async-to-generator" "^7.25.7" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-remap-async-to-generator" "^7.25.9" -"@babel/plugin-transform-block-scoped-functions@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.7.tgz#e0b8843d5571719a2f1bf7e284117a3379fcc17c" - integrity sha512-xHttvIM9fvqW+0a3tZlYcZYSBpSWzGBFIt/sYG3tcdSzBB8ZeVgz2gBP7Df+sM0N1850jrviYSSeUuc+135dmQ== +"@babel/plugin-transform-block-scoped-functions@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.25.9.tgz#5700691dbd7abb93de300ca7be94203764fce458" + integrity sha512-toHc9fzab0ZfenFpsyYinOX0J/5dgJVA2fm64xPewu7CoYHWEivIWKxkK2rMi4r3yQqLnVmheMXRdG+k239CgA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-block-scoping@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.7.tgz#6dab95e98adf780ceef1b1c3ab0e55cd20dd410a" - integrity sha512-ZEPJSkVZaeTFG/m2PARwLZQ+OG0vFIhPlKHK/JdIMy8DbRJ/htz6LRrTFtdzxi9EHmcwbNPAKDnadpNSIW+Aow== +"@babel/plugin-transform-block-scoping@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.25.9.tgz#c33665e46b06759c93687ca0f84395b80c0473a1" + integrity sha512-1F05O7AYjymAtqbsFETboN1NvBdcnzMerO+zlMyJBEz6WkMdejvGWw9p05iTSjC85RLlBseHHQpYaM4gzJkBGg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-class-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.7.tgz#a389cfca7a10ac80e3ff4c75fca08bd097ad1523" - integrity sha512-mhyfEW4gufjIqYFo9krXHJ3ElbFLIze5IDp+wQTxoPd+mwFb1NxatNAwmv8Q8Iuxv7Zc+q8EkiMQwc9IhyGf4g== +"@babel/plugin-transform-class-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-properties/-/plugin-transform-class-properties-7.25.9.tgz#a8ce84fedb9ad512549984101fa84080a9f5f51f" + integrity sha512-bbMAII8GRSkcd0h0b4X+36GksxuheLFjP65ul9w6C3KgAamI3JqErNgSrosX6ZPj+Mpim5VvEbawXxJCyEUV3Q== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-class-static-block@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.25.8.tgz#a8af22028920fe404668031eceb4c3aadccb5262" - integrity sha512-e82gl3TCorath6YLf9xUwFehVvjvfqFhdOo4+0iVIVju+6XOi5XHkqB3P2AXnSwoeTX0HBoXq5gJFtvotJzFnQ== +"@babel/plugin-transform-class-static-block@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-class-static-block/-/plugin-transform-class-static-block-7.26.0.tgz#6c8da219f4eb15cae9834ec4348ff8e9e09664a0" + integrity sha512-6J2APTs7BDDm+UMqP1useWqhcRAXo0WIoVj26N7kPFB6S73Lgvyka4KTZYIxtgYXiN5HTyRObA72N2iu628iTQ== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-classes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.7.tgz#5103206cf80d02283bbbd044509ea3b65d0906bb" - integrity sha512-9j9rnl+YCQY0IGoeipXvnk3niWicIB6kCsWRGLwX241qSXpbA4MKxtp/EdvFxsc4zI5vqfLxzOd0twIJ7I99zg== +"@babel/plugin-transform-classes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.25.9.tgz#7152457f7880b593a63ade8a861e6e26a4469f52" + integrity sha512-mD8APIXmseE7oZvZgGABDyM34GUmK45Um2TXiBUt7PnuAxrgoSVf123qUzPxEr/+/BHrRn5NMZCdE2m/1F8DGg== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" + "@babel/traverse" "^7.25.9" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.7.tgz#7f621f0aa1354b5348a935ab12e3903842466f65" - integrity sha512-QIv+imtM+EtNxg/XBKL3hiWjgdLjMOmZ+XzQwSgmBfKbfxUjBzGgVPklUuE55eq5/uVoh8gg3dqlrwR/jw3ZeA== +"@babel/plugin-transform-computed-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.25.9.tgz#db36492c78460e534b8852b1d5befe3c923ef10b" + integrity sha512-HnBegGqXZR12xbcTHlJ9HGxw1OniltT26J5YpfruGqtUHlz/xKf/G2ak9e+t0rVqrjXa9WOhvYPz1ERfMj23AA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/template" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/template" "^7.25.9" -"@babel/plugin-transform-destructuring@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.7.tgz#f6f26a9feefb5aa41fd45b6f5838901b5333d560" - integrity sha512-xKcfLTlJYUczdaM1+epcdh1UGewJqr9zATgrNHcLBcV2QmfvPPEixo/sK/syql9cEmbr7ulu5HMFG5vbbt/sEA== +"@babel/plugin-transform-destructuring@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.25.9.tgz#966ea2595c498224340883602d3cfd7a0c79cea1" + integrity sha512-WkCGb/3ZxXepmMiX101nnGiU+1CAdut8oHyEOHxkKuS1qKpU2SMXE2uSvfz8PBuLd49V6LEsbtyPhWC7fnkgvQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-dotall-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.7.tgz#9d775c4a3ff1aea64045300fcd4309b4a610ef02" - integrity sha512-kXzXMMRzAtJdDEgQBLF4oaiT6ZCU3oWHgpARnTKDAqPkDJ+bs3NrZb310YYevR5QlRo3Kn7dzzIdHbZm1VzJdQ== +"@babel/plugin-transform-dotall-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.25.9.tgz#bad7945dd07734ca52fe3ad4e872b40ed09bb09a" + integrity sha512-t7ZQ7g5trIgSRYhI9pIJtRl64KHotutUJsh4Eze5l7olJv+mRSg4/MmbZ0tv1eeqRbdvo/+trvJD/Oc5DmW2cA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-duplicate-keys@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.7.tgz#fbba7d1155eab76bd4f2a038cbd5d65883bd7a93" - integrity sha512-by+v2CjoL3aMnWDOyCIg+yxU9KXSRa9tN6MbqggH5xvymmr9p4AMjYkNlQy4brMceBnUyHZ9G8RnpvT8wP7Cfg== +"@babel/plugin-transform-duplicate-keys@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.25.9.tgz#8850ddf57dce2aebb4394bb434a7598031059e6d" + integrity sha512-LZxhJ6dvBb/f3x8xwWIuyiAHy56nrRG3PeYTpBkkzkYRRQ6tJLu68lEF5VIqMUZiAV7a8+Tb78nEoMCMcqjXBw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.7.tgz#102b31608dcc22c08fbca1894e104686029dc141" - integrity sha512-HvS6JF66xSS5rNKXLqkk7L9c/jZ/cdIVIcoPVrnl8IsVpLggTjXs8OWekbLHs/VtYDDh5WXnQyeE3PPUGm22MA== +"@babel/plugin-transform-duplicate-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-named-capturing-groups-regex/-/plugin-transform-duplicate-named-capturing-groups-regex-7.25.9.tgz#6f7259b4de127721a08f1e5165b852fcaa696d31" + integrity sha512-0UfuJS0EsXbRvKnwcLjFtJy/Sxc5J5jhLHnFhy7u4zih97Hz6tJkLU+O+FMMrNZrosUPxDi6sYxJ/EA8jDiAog== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-dynamic-import@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.8.tgz#f1edbe75b248cf44c70c8ca8ed3818a668753aaa" - integrity sha512-gznWY+mr4ZQL/EWPcbBQUP3BXS5FwZp8RUOw06BaRn8tQLzN4XLIxXejpHN9Qo8x8jjBmAAKp6FoS51AgkSA/A== +"@babel/plugin-transform-dynamic-import@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dynamic-import/-/plugin-transform-dynamic-import-7.25.9.tgz#23e917de63ed23c6600c5dd06d94669dce79f7b8" + integrity sha512-GCggjexbmSLaFhqsojeugBpeaRIgWNTcgKVq/0qIteFEqY2A+b9QidYadrWlnbWQUrW5fn+mCvf3tr7OeBFTyg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-exponentiation-operator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.25.7.tgz#5961a3a23a398faccd6cddb34a2182807d75fb5f" - integrity sha512-yjqtpstPfZ0h/y40fAXRv2snciYr0OAoMXY/0ClC7tm4C/nG5NJKmIItlaYlLbIVAWNfrYuy9dq1bE0SbX0PEg== +"@babel/plugin-transform-exponentiation-operator@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.26.3.tgz#e29f01b6de302c7c2c794277a48f04a9ca7f03bc" + integrity sha512-7CAHcQ58z2chuXPWblnn1K6rLDnDWieghSOEmqQsrBenH0P9InCUtOJYD89pvngljmZlJcz3fcmgYsXFNGa1ZQ== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-export-namespace-from@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.8.tgz#d1988c3019a380b417e0516418b02804d3858145" - integrity sha512-sPtYrduWINTQTW7FtOy99VCTWp4H23UX7vYcut7S4CIMEXU+54zKX9uCoGkLsWXteyaMXzVHgzWbLfQ1w4GZgw== +"@babel/plugin-transform-export-namespace-from@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-export-namespace-from/-/plugin-transform-export-namespace-from-7.25.9.tgz#90745fe55053394f554e40584cda81f2c8a402a2" + integrity sha512-2NsEz+CxzJIVOPx2o9UsW1rXLqtChtLoVnwYHHiB04wS5sgn7mrV45fWMBX0Kk+ub9uXytVYfNP2HjbVbCB3Ww== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-for-of@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.7.tgz#0acfea0f27aa290818b5b48a5a44b3f03fc13669" - integrity sha512-n/TaiBGJxYFWvpJDfsxSj9lEEE44BFM1EPGz4KEiTipTgkoFVVcCmzAL3qA7fdQU96dpo4gGf5HBx/KnDvqiHw== +"@babel/plugin-transform-for-of@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.25.9.tgz#4bdc7d42a213397905d89f02350c5267866d5755" + integrity sha512-LqHxduHoaGELJl2uhImHwRQudhCM50pT46rIBNvtT/Oql3nqiS3wOwP+5ten7NpYSXrrVLgtZU3DZmPtWZo16A== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-function-name@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.7.tgz#7e394ccea3693902a8b50ded8b6ae1fa7b8519fd" - integrity sha512-5MCTNcjCMxQ63Tdu9rxyN6cAWurqfrDZ76qvVPrGYdBxIj+EawuuxTu/+dgJlhK5eRz3v1gLwp6XwS8XaX2NiQ== +"@babel/plugin-transform-function-name@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.25.9.tgz#939d956e68a606661005bfd550c4fc2ef95f7b97" + integrity sha512-8lP+Yxjv14Vc5MuWBpJsoUCd3hD6V9DgBon2FVYL4jJgbnVQ9fTgYmonchzZJOVNgzEgbxp4OwAf6xz6M/14XA== dependencies: - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-json-strings@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.8.tgz#6fb3ec383a2ea92652289fdba653e3f9de722694" - integrity sha512-4OMNv7eHTmJ2YXs3tvxAfa/I43di+VcF+M4Wt66c88EAED1RoGaf1D64cL5FkRpNL+Vx9Hds84lksWvd/wMIdA== +"@babel/plugin-transform-json-strings@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-json-strings/-/plugin-transform-json-strings-7.25.9.tgz#c86db407cb827cded902a90c707d2781aaa89660" + integrity sha512-xoTMk0WXceiiIvsaquQQUaLLXSW1KJ159KP87VilruQm0LNNGxWzahxSS6T6i4Zg3ezp4vA4zuwiNUR53qmQAw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.7.tgz#70cbdc742f2cfdb1a63ea2cbd018d12a60b213c3" - integrity sha512-fwzkLrSu2fESR/cm4t6vqd7ebNIopz2QHGtjoU+dswQo/P6lwAG04Q98lliE3jkz/XqnbGFLnUcE0q0CVUf92w== +"@babel/plugin-transform-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.25.9.tgz#1a1c6b4d4aa59bc4cad5b6b3a223a0abd685c9de" + integrity sha512-9N7+2lFziW8W9pBl2TzaNht3+pgMIRP74zizeCSrtnSKVdUl8mAjjOP2OOVQAfZ881P2cNjDj1uAMEdeD50nuQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-logical-assignment-operators@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.8.tgz#01868ff92daa9e525b4c7902aa51979082a05710" - integrity sha512-f5W0AhSbbI+yY6VakT04jmxdxz+WsID0neG7+kQZbCOjuyJNdL5Nn4WIBm4hRpKnUcO9lP0eipUhFN12JpoH8g== +"@babel/plugin-transform-logical-assignment-operators@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-logical-assignment-operators/-/plugin-transform-logical-assignment-operators-7.25.9.tgz#b19441a8c39a2fda0902900b306ea05ae1055db7" + integrity sha512-wI4wRAzGko551Y8eVf6iOY9EouIDTtPb0ByZx+ktDGHwv6bHFimrgJM/2T021txPZ2s4c7bqvHbd+vXG6K948Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-member-expression-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.7.tgz#0a36c3fbd450cc9e6485c507f005fa3d1bc8fca5" - integrity sha512-Std3kXwpXfRV0QtQy5JJcRpkqP8/wG4XL7hSKZmGlxPlDqmpXtEPRmhF7ztnlTCtUN3eXRUJp+sBEZjaIBVYaw== +"@babel/plugin-transform-member-expression-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.25.9.tgz#63dff19763ea64a31f5e6c20957e6a25e41ed5de" + integrity sha512-PYazBVfofCQkkMzh2P6IdIUaCEWni3iYEerAsRWuVd8+jlM1S9S9cz1dF9hIzyoZ8IA3+OwVYIp9v9e+GbgZhA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-modules-amd@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.7.tgz#bb4e543b5611f6c8c685a2fd485408713a3adf3d" - integrity sha512-CgselSGCGzjQvKzghCvDTxKHP3iooenLpJDO842ehn5D2G5fJB222ptnDwQho0WjEvg7zyoxb9P+wiYxiJX5yA== +"@babel/plugin-transform-modules-amd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.25.9.tgz#49ba478f2295101544abd794486cd3088dddb6c5" + integrity sha512-g5T11tnI36jVClQlMlt4qKDLlWnG5pP9CSM4GhdRciTNMRgkfpo5cR6b4rGIOYPgRRuFAvwjPQ/Yk+ql4dyhbw== dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-modules-commonjs@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.25.7.tgz#173f0c791bb7407c092ce6d77ee90eb3f2d1d2fd" - integrity sha512-L9Gcahi0kKFYXvweO6n0wc3ZG1ChpSFdgG+eV1WYZ3/dGbJK7vvk91FgGgak8YwRgrCuihF8tE/Xg07EkL5COg== +"@babel/plugin-transform-modules-commonjs@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.26.3.tgz#8f011d44b20d02c3de44d8850d971d8497f981fb" + integrity sha512-MgR55l4q9KddUDITEzEFYn5ZsGDXMSsU9E+kh7fjRXTIC3RHqfCo8RPRbyReYJh44HQ/yomFkqbOFohXvDCiIQ== dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-simple-access" "^7.25.7" + "@babel/helper-module-transforms" "^7.26.0" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-modules-systemjs@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.7.tgz#8b14d319a177cc9c85ef8b0512afd429d9e2e60b" - integrity sha512-t9jZIvBmOXJsiuyOwhrIGs8dVcD6jDyg2icw1VL4A/g+FnWyJKwUfSSU2nwJuMV2Zqui856El9u+ElB+j9fV1g== +"@babel/plugin-transform-modules-systemjs@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.25.9.tgz#8bd1b43836269e3d33307151a114bcf3ba6793f8" + integrity sha512-hyss7iIlH/zLHaehT+xwiymtPOpsiwIIRlCAOwBB04ta5Tt+lNItADdlXw3jAWZ96VJ2jlhl/c+PNIQPKNfvcA== dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-identifier" "^7.25.7" - "@babel/traverse" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@babel/traverse" "^7.25.9" -"@babel/plugin-transform-modules-umd@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.7.tgz#00ee7a7e124289549381bfb0e24d87fd7f848367" - integrity sha512-p88Jg6QqsaPh+EB7I9GJrIqi1Zt4ZBHUQtjw3z1bzEXcLh6GfPqzZJ6G+G1HBGKUNukT58MnKG7EN7zXQBCODw== +"@babel/plugin-transform-modules-umd@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.25.9.tgz#6710079cdd7c694db36529a1e8411e49fcbf14c9" + integrity sha512-bS9MVObUgE7ww36HEfwe6g9WakQ0KF07mQF74uuXdkoziUPfKyu/nIm663kz//e5O1nPInPFx36z7WJmJ4yNEw== dependencies: - "@babel/helper-module-transforms" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-module-transforms" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-named-capturing-groups-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.7.tgz#a2f3f6d7f38693b462542951748f0a72a34d196d" - integrity sha512-BtAT9LzCISKG3Dsdw5uso4oV1+v2NlVXIIomKJgQybotJY3OwCwJmkongjHgwGKoZXd0qG5UZ12JUlDQ07W6Ow== +"@babel/plugin-transform-named-capturing-groups-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.25.9.tgz#454990ae6cc22fd2a0fa60b3a2c6f63a38064e6a" + integrity sha512-oqB6WHdKTGl3q/ItQhpLSnWWOpjUJLsOCLVyeFgeTktkBSCiurvPOsyt93gibI9CmuKvTUEtWmG5VhZD+5T/KA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-new-target@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.7.tgz#52b2bde523b76c548749f38dc3054f1f45e82bc9" - integrity sha512-CfCS2jDsbcZaVYxRFo2qtavW8SpdzmBXC2LOI4oO0rP+JSRDxxF3inF4GcPsLgfb5FjkhXG5/yR/lxuRs2pySA== +"@babel/plugin-transform-new-target@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.25.9.tgz#42e61711294b105c248336dcb04b77054ea8becd" + integrity sha512-U/3p8X1yCSoKyUj2eOBIx3FOn6pElFOKvAAGf8HTtItuPyB+ZeOqfn+mvTtg9ZlOAjsPdK3ayQEjqHjU/yLeVQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-nullish-coalescing-operator@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.8.tgz#befb4900c130bd52fccf2b926314557987f1b552" - integrity sha512-Z7WJJWdQc8yCWgAmjI3hyC+5PXIubH9yRKzkl9ZEG647O9szl9zvmKLzpbItlijBnVhTUf1cpyWBsZ3+2wjWPQ== +"@babel/plugin-transform-nullish-coalescing-operator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-nullish-coalescing-operator/-/plugin-transform-nullish-coalescing-operator-7.25.9.tgz#bcb1b0d9e948168102d5f7104375ca21c3266949" + integrity sha512-ENfftpLZw5EItALAD4WsY/KUWvhUlZndm5GC7G3evUsVeSJB6p0pBeLQUnRnBCBx7zV0RKQjR9kCuwrsIrjWog== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-numeric-separator@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.8.tgz#91e370486371637bd42161052f2602c701386891" - integrity sha512-rm9a5iEFPS4iMIy+/A/PiS0QN0UyjPIeVvbU5EMZFKJZHt8vQnasbpo3T3EFcxzCeYO0BHfc4RqooCZc51J86Q== +"@babel/plugin-transform-numeric-separator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-numeric-separator/-/plugin-transform-numeric-separator-7.25.9.tgz#bfed75866261a8b643468b0ccfd275f2033214a1" + integrity sha512-TlprrJ1GBZ3r6s96Yq8gEQv82s8/5HnCVHtEJScUj90thHQbwe+E5MLhi2bbNHBEJuzrvltXSru+BUxHDoog7Q== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-object-rest-spread@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.8.tgz#0904ac16bcce41df4db12d915d6780f85c7fb04b" - integrity sha512-LkUu0O2hnUKHKE7/zYOIjByMa4VRaV2CD/cdGz0AxU9we+VA3kDDggKEzI0Oz1IroG+6gUP6UmWEHBMWZU316g== +"@babel/plugin-transform-object-rest-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-rest-spread/-/plugin-transform-object-rest-spread-7.25.9.tgz#0203725025074164808bcf1a2cfa90c652c99f18" + integrity sha512-fSaXafEE9CVHPweLYw4J0emp1t8zYTXyzN3UuG+lylqkvYd7RMrsOQ8TYx5RF231be0vqtFC6jnx3UmpJmKBYg== dependencies: - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-transform-parameters" "^7.25.7" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" -"@babel/plugin-transform-object-super@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.7.tgz#582a9cea8cf0a1e02732be5b5a703a38dedf5661" - integrity sha512-pWT6UXCEW3u1t2tcAGtE15ornCBvopHj9Bps9D2DsH15APgNVOTwwczGckX+WkAvBmuoYKRCFa4DK+jM8vh5AA== +"@babel/plugin-transform-object-super@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.25.9.tgz#385d5de135162933beb4a3d227a2b7e52bb4cf03" + integrity sha512-Kj/Gh+Rw2RNLbCK1VAWj2U48yxxqL2x0k10nPtSdRa0O2xnHXalD0s+o1A6a0W43gJ00ANo38jxkQreckOzv5A== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-replace-supers" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-replace-supers" "^7.25.9" -"@babel/plugin-transform-optional-catch-binding@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.8.tgz#2649b86a3bb202c6894ec81a6ddf41b94d8f3103" - integrity sha512-EbQYweoMAHOn7iJ9GgZo14ghhb9tTjgOc88xFgYngifx7Z9u580cENCV159M4xDh3q/irbhSjZVpuhpC2gKBbg== +"@babel/plugin-transform-optional-catch-binding@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-catch-binding/-/plugin-transform-optional-catch-binding-7.25.9.tgz#10e70d96d52bb1f10c5caaac59ac545ea2ba7ff3" + integrity sha512-qM/6m6hQZzDcZF3onzIhZeDHDO43bkNNlOX0i8n3lR6zLbu0GN2d8qfM/IERJZYauhAHSLHy39NF0Ctdvcid7g== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-optional-chaining@^7.25.7", "@babel/plugin-transform-optional-chaining@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.8.tgz#f46283b78adcc5b6ab988a952f989e7dce70653f" - integrity sha512-q05Bk7gXOxpTHoQ8RSzGSh/LHVB9JEIkKnk3myAWwZHnYiTGYtbdrYkIsS8Xyh4ltKf7GNUSgzs/6P2bJtBAQg== +"@babel/plugin-transform-optional-chaining@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-optional-chaining/-/plugin-transform-optional-chaining-7.25.9.tgz#e142eb899d26ef715435f201ab6e139541eee7dd" + integrity sha512-6AvV0FsLULbpnXeBjrY4dmWF8F7gf8QnvTEoO/wX/5xm/xE1Xo8oPuD3MPS+KS9f9XBEAWN7X1aWr4z9HdOr7A== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-parameters@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.7.tgz#80c38b03ef580f6d6bffe1c5254bb35986859ac7" - integrity sha512-FYiTvku63me9+1Nz7TOx4YMtW3tWXzfANZtrzHhUZrz4d47EEtMQhzFoZWESfXuAMMT5mwzD4+y1N8ONAX6lMQ== +"@babel/plugin-transform-parameters@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.25.9.tgz#b856842205b3e77e18b7a7a1b94958069c7ba257" + integrity sha512-wzz6MKwpnshBAiRmn4jR8LYz/g8Ksg0o80XmwZDlordjwEk9SxBzTWC7F5ef1jhbrbOW2DJ5J6ayRukrJmnr0g== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-private-methods@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.7.tgz#c790a04f837b4bd61d6b0317b43aa11ff67dce80" - integrity sha512-KY0hh2FluNxMLwOCHbxVOKfdB5sjWG4M183885FmaqWWiGMhRZq4DQRKH6mHdEucbJnyDyYiZNwNG424RymJjA== +"@babel/plugin-transform-private-methods@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-methods/-/plugin-transform-private-methods-7.25.9.tgz#847f4139263577526455d7d3223cd8bda51e3b57" + integrity sha512-D/JUozNpQLAPUVusvqMxyvjzllRaF8/nSrP1s2YGQT/W4LHK4xxsMcHjhOGTS01mp9Hda8nswb+FblLdJornQw== dependencies: - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-private-property-in-object@^7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.8.tgz#1234f856ce85e061f9688764194e51ea7577c434" - integrity sha512-8Uh966svuB4V8RHHg0QJOB32QK287NBksJOByoKmHMp1TAobNniNalIkI2i5IPj5+S9NYCG4VIjbEuiSN8r+ow== +"@babel/plugin-transform-private-property-in-object@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-private-property-in-object/-/plugin-transform-private-property-in-object-7.25.9.tgz#9c8b73e64e6cc3cbb2743633885a7dd2c385fe33" + integrity sha512-Evf3kcMqzXA3xfYJmZ9Pg1OvKdtqsDMSWBDzZOPLvHiTt36E75jLDQo5w1gtRU95Q4E5PDttrTf25Fw8d/uWLw== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-property-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.7.tgz#a8612b4ea4e10430f00012ecf0155662c7d6550d" - integrity sha512-lQEeetGKfFi0wHbt8ClQrUSUMfEeI3MMm74Z73T9/kuz990yYVtfofjf3NuA42Jy3auFOpbjDyCSiIkTs1VIYw== +"@babel/plugin-transform-property-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.25.9.tgz#d72d588bd88b0dec8b62e36f6fda91cedfe28e3f" + integrity sha512-IvIUeV5KrS/VPavfSM/Iu+RE6llrHrYIKY1yfCzyO/lMXHQ+p7uGhonmGVisv6tSBSVgWzMBohTcvkC9vQcQFA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-display-name@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.7.tgz#2753e875a1b702fb1d806c4f5d4c194d64cadd88" - integrity sha512-r0QY7NVU8OnrwE+w2IWiRom0wwsTbjx4+xH2RTd7AVdof3uurXOF+/mXHQDRk+2jIvWgSaCHKMgggfvM4dyUGA== +"@babel/plugin-transform-react-display-name@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.25.9.tgz#4b79746b59efa1f38c8695065a92a9f5afb24f7d" + integrity sha512-KJfMlYIUxQB1CJfO3e0+h0ZHWOTLCPP115Awhaz8U0Zpq36Gl/cXlpoyMRnUWlhNUBAzldnCiAZNvCDj7CrKxQ== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-react-jsx-development@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.7.tgz#2fbd77887b8fa2942d7cb61edf1029ea1b048554" - integrity sha512-5yd3lH1PWxzW6IZj+p+Y4OLQzz0/LzlOG8vGqonHfVR3euf1vyzyMUJk9Ac+m97BH46mFc/98t9PmYLyvgL3qg== +"@babel/plugin-transform-react-jsx-development@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.25.9.tgz#8fd220a77dd139c07e25225a903b8be8c829e0d7" + integrity sha512-9mj6rm7XVYs4mdLIpbZnHOYdpW42uoiBCTVowg7sP1thUOiANgMb4UtpRivR0pp5iL+ocvUv7X4mZgFRpJEzGw== dependencies: - "@babel/plugin-transform-react-jsx" "^7.25.7" + "@babel/plugin-transform-react-jsx" "^7.25.9" -"@babel/plugin-transform-react-jsx@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.7.tgz#f5e2af6020a562fe048dd343e571c4428e6c5632" - integrity sha512-vILAg5nwGlR9EXE8JIOX4NHXd49lrYbN8hnjffDtoULwpL9hUx/N55nqh2qd0q6FyNDfjl9V79ecKGvFbcSA0Q== +"@babel/plugin-transform-react-jsx@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.25.9.tgz#06367940d8325b36edff5e2b9cbe782947ca4166" + integrity sha512-s5XwpQYCqGerXl+Pu6VDL3x0j2d82eiV77UJ8a2mDHAW7j9SWRqQ2y1fNo1Z74CdcYipl5Z41zvjj4Nfzq36rw== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-module-imports" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/plugin-syntax-jsx" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-module-imports" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/plugin-syntax-jsx" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/plugin-transform-react-pure-annotations@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.7.tgz#6d0b8dadb2d3c5cbb8ade68c5efd49470b0d65f7" - integrity sha512-6YTHJ7yjjgYqGc8S+CbEXhLICODk0Tn92j+vNJo07HFk9t3bjFgAKxPLFhHwF2NjmQVSI1zBRfBWUeVBa2osfA== +"@babel/plugin-transform-react-pure-annotations@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.25.9.tgz#ea1c11b2f9dbb8e2d97025f43a3b5bc47e18ae62" + integrity sha512-KQ/Takk3T8Qzj5TppkS1be588lkbTp5uj7w6a0LeQaTMSckU/wK0oJ/pih+T690tkgI5jfmg2TqDJvd41Sj1Cg== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-regenerator@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.7.tgz#6eb006e6d26f627bc2f7844a9f19770721ad6f3e" - integrity sha512-mgDoQCRjrY3XK95UuV60tZlFCQGXEtMg8H+IsW72ldw1ih1jZhzYXbJvghmAEpg5UVhhnCeia1CkGttUvCkiMQ== +"@babel/plugin-transform-regenerator@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.25.9.tgz#03a8a4670d6cebae95305ac6defac81ece77740b" + integrity sha512-vwDcDNsgMPDGP0nMqzahDWE5/MLcX8sv96+wfX7as7LoF/kr97Bo/7fI00lXY4wUXYfVmwIIyG80fGZ1uvt2qg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" regenerator-transform "^0.15.2" -"@babel/plugin-transform-reserved-words@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.7.tgz#dc56b25e02afaabef3ce0c5b06b0916e8523e995" - integrity sha512-3OfyfRRqiGeOvIWSagcwUTVk2hXBsr/ww7bLn6TRTuXnexA+Udov2icFOxFX9abaj4l96ooYkcNN1qi2Zvqwng== +"@babel/plugin-transform-regexp-modifiers@^7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regexp-modifiers/-/plugin-transform-regexp-modifiers-7.26.0.tgz#2f5837a5b5cd3842a919d8147e9903cc7455b850" + integrity sha512-vN6saax7lrA2yA/Pak3sCxuD6F5InBjn9IcrIKQPjpsLvuHYLVroTxjdlVRHjjBWxKOqIwpTXDkOssYT4BFdRw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-shorthand-properties@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.7.tgz#92690a9c671915602d91533c278cc8f6bf12275f" - integrity sha512-uBbxNwimHi5Bv3hUccmOFlUy3ATO6WagTApenHz9KzoIdn0XeACdB12ZJ4cjhuB2WSi80Ez2FWzJnarccriJeA== +"@babel/plugin-transform-reserved-words@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.25.9.tgz#0398aed2f1f10ba3f78a93db219b27ef417fb9ce" + integrity sha512-7DL7DKYjn5Su++4RXu8puKZm2XBPHyjWLUidaPEkCUBbE7IPcsrkRHggAOOKydH1dASWdcUBxrkOGNxUv5P3Jg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-spread@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.7.tgz#df83e899a9fc66284ee601a7b738568435b92998" - integrity sha512-Mm6aeymI0PBh44xNIv/qvo8nmbkpZze1KvR8MkEqbIREDxoiWTi18Zr2jryfRMwDfVZF9foKh060fWgni44luw== +"@babel/plugin-transform-shorthand-properties@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.25.9.tgz#bb785e6091f99f826a95f9894fc16fde61c163f2" + integrity sha512-MUv6t0FhO5qHnS/W8XCbHmiRWOphNufpE1IVxhK5kuN3Td9FT1x4rx4K42s3RYdMXCXpfWkGSbCSd0Z64xA7Ng== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-sticky-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.7.tgz#341c7002bef7f29037be7fb9684e374442dd0d17" - integrity sha512-ZFAeNkpGuLnAQ/NCsXJ6xik7Id+tHuS+NT+ue/2+rn/31zcdnupCdmunOizEaP0JsUmTFSTOPoQY7PkK2pttXw== +"@babel/plugin-transform-spread@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.25.9.tgz#24a35153931b4ba3d13cec4a7748c21ab5514ef9" + integrity sha512-oNknIB0TbURU5pqJFVbOOFspVlrpVwo2H1+HUIsVDvp5VauGGDP1ZEvO8Nn5xyMEs3dakajOxlmkNW7kNgSm6A== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" -"@babel/plugin-transform-template-literals@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.7.tgz#e566c581bb16d8541dd8701093bb3457adfce16b" - integrity sha512-SI274k0nUsFFmyQupiO7+wKATAmMFf8iFgq2O+vVFXZ0SV9lNfT1NGzBEhjquFmD8I9sqHLguH+gZVN3vww2AA== +"@babel/plugin-transform-sticky-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.25.9.tgz#c7f02b944e986a417817b20ba2c504dfc1453d32" + integrity sha512-WqBUSgeVwucYDP9U/xNRQam7xV8W5Zf+6Eo7T2SRVUFlhRiMNFdFz58u0KZmCVVqs2i7SHgpRnAhzRNmKfi2uA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-typeof-symbol@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.7.tgz#debb1287182efd20488f126be343328c679b66eb" - integrity sha512-OmWmQtTHnO8RSUbL0NTdtpbZHeNTnm68Gj5pA4Y2blFNh+V4iZR68V1qL9cI37J21ZN7AaCnkfdHtLExQPf2uA== +"@babel/plugin-transform-template-literals@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.25.9.tgz#6dbd4a24e8fad024df76d1fac6a03cf413f60fe1" + integrity sha512-o97AE4syN71M/lxrCtQByzphAdlYluKPDBzDVzMmfCobUjjhAryZV0AIpRPrxN0eAkxXO6ZLEScmt+PNhj2OTw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-typescript@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.25.7.tgz#8fc7c3d28ddd36bce45b9b48594129d0e560cfbe" - integrity sha512-VKlgy2vBzj8AmEzunocMun2fF06bsSWV+FvVXohtL6FGve/+L217qhHxRTVGHEDO/YR8IANcjzgJsd04J8ge5Q== +"@babel/plugin-transform-typeof-symbol@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.25.9.tgz#224ba48a92869ddbf81f9b4a5f1204bbf5a2bc4b" + integrity sha512-v61XqUMiueJROUv66BVIOi0Fv/CUuZuZMl5NkRoCVxLAnMexZ0A3kMe7vvZ0nulxMuMp0Mk6S5hNh48yki08ZA== dependencies: - "@babel/helper-annotate-as-pure" "^7.25.7" - "@babel/helper-create-class-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-skip-transparent-expression-wrappers" "^7.25.7" - "@babel/plugin-syntax-typescript" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-escapes@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.7.tgz#973592b6d13a914794e1de8cf1383e50e0f87f81" - integrity sha512-BN87D7KpbdiABA+t3HbVqHzKWUDN3dymLaTnPFAMyc8lV+KN3+YzNhVRNdinaCPA4AUqx7ubXbQ9shRjYBl3SQ== +"@babel/plugin-transform-typescript@^7.25.9": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.26.3.tgz#3d6add9c78735623317387ee26d5ada540eee3fd" + integrity sha512-6+5hpdr6mETwSKjmJUdYw0EIkATiQhnELWlE3kJFBwSg/BGIVwVaVbX+gOXBCdc7Ln1RXZxyWGecIXhUfnl7oA== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-annotate-as-pure" "^7.25.9" + "@babel/helper-create-class-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-skip-transparent-expression-wrappers" "^7.25.9" + "@babel/plugin-syntax-typescript" "^7.25.9" -"@babel/plugin-transform-unicode-property-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.7.tgz#25349197cce964b1343f74fa7cfdf791a1b1919e" - integrity sha512-IWfR89zcEPQGB/iB408uGtSPlQd3Jpq11Im86vUgcmSTcoWAiQMCTOa2K2yNNqFJEBVICKhayctee65Ka8OB0w== +"@babel/plugin-transform-unicode-escapes@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.25.9.tgz#a75ef3947ce15363fccaa38e2dd9bc70b2788b82" + integrity sha512-s5EDrE6bW97LtxOcGj1Khcx5AaXwiMmi4toFWRDP9/y0Woo6pXC+iyPu/KuhKtfSrNFd7jJB+/fkOtZy6aIC6Q== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.7.tgz#f93a93441baf61f713b6d5552aaa856bfab34809" - integrity sha512-8JKfg/hiuA3qXnlLx8qtv5HWRbgyFx2hMMtpDDuU2rTckpKkGu4ycK5yYHwuEa16/quXfoxHBIApEsNyMWnt0g== +"@babel/plugin-transform-unicode-property-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-property-regex/-/plugin-transform-unicode-property-regex-7.25.9.tgz#a901e96f2c1d071b0d1bb5dc0d3c880ce8f53dd3" + integrity sha512-Jt2d8Ga+QwRluxRQ307Vlxa6dMrYEMZCgGxoPR8V52rxPyldHu3hdlHspxaqYmE7oID5+kB+UKUB/eWS+DkkWg== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/plugin-transform-unicode-sets-regex@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.7.tgz#d1b3295d29e0f8f4df76abc909ad1ebee919560c" - integrity sha512-YRW8o9vzImwmh4Q3Rffd09bH5/hvY0pxg+1H1i0f7APoUeg12G7+HhLj9ZFNIrYkgBXhIijPJ+IXypN0hLTIbw== +"@babel/plugin-transform-unicode-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.25.9.tgz#5eae747fe39eacf13a8bd006a4fb0b5d1fa5e9b1" + integrity sha512-yoxstj7Rg9dlNn9UQxzk4fcNivwv4nUYz7fYXBaKxvw/lnmPuOm/ikoELygbYq68Bls3D/D+NBPHiLwZdZZ4HA== dependencies: - "@babel/helper-create-regexp-features-plugin" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" -"@babel/preset-env@7.25.8": - version "7.25.8" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.25.8.tgz#dc6b719627fb29cd9cccbbbe041802fd575b524c" - integrity sha512-58T2yulDHMN8YMUxiLq5YmWUnlDCyY1FsHM+v12VMx+1/FlrUj5tY50iDCpofFQEM8fMYOaY9YRvym2jcjn1Dg== +"@babel/plugin-transform-unicode-sets-regex@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-sets-regex/-/plugin-transform-unicode-sets-regex-7.25.9.tgz#65114c17b4ffc20fa5b163c63c70c0d25621fabe" + integrity sha512-8BYqO3GeVNHtx69fdPshN3fnzUNLrWdHhk/icSwigksJGczKSizZ+Z6SBCxTs723Fr5VSNorTIK7a+R2tISvwQ== dependencies: - "@babel/compat-data" "^7.25.8" - "@babel/helper-compilation-targets" "^7.25.7" - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.7" - "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.7" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.7" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.7" - "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.7" + "@babel/helper-create-regexp-features-plugin" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + +"@babel/preset-env@7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.26.0.tgz#30e5c6bc1bcc54865bff0c5a30f6d4ccdc7fa8b1" + integrity sha512-H84Fxq0CQJNdPFT2DrfnylZ3cf5K43rGfWK4LJGPpjKHiZlk0/RzwEus3PDDZZg+/Er7lCA03MVacueUuXdzfw== + dependencies: + "@babel/compat-data" "^7.26.0" + "@babel/helper-compilation-targets" "^7.25.9" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-bugfix-firefox-class-in-computed-class-key" "^7.25.9" + "@babel/plugin-bugfix-safari-class-field-initializer-scope" "^7.25.9" + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.25.9" + "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.25.9" + "@babel/plugin-bugfix-v8-static-class-fields-redefine-readonly" "^7.25.9" "@babel/plugin-proposal-private-property-in-object" "7.21.0-placeholder-for-preset-env.2" - "@babel/plugin-syntax-import-assertions" "^7.25.7" - "@babel/plugin-syntax-import-attributes" "^7.25.7" + "@babel/plugin-syntax-import-assertions" "^7.26.0" + "@babel/plugin-syntax-import-attributes" "^7.26.0" "@babel/plugin-syntax-unicode-sets-regex" "^7.18.6" - "@babel/plugin-transform-arrow-functions" "^7.25.7" - "@babel/plugin-transform-async-generator-functions" "^7.25.8" - "@babel/plugin-transform-async-to-generator" "^7.25.7" - "@babel/plugin-transform-block-scoped-functions" "^7.25.7" - "@babel/plugin-transform-block-scoping" "^7.25.7" - "@babel/plugin-transform-class-properties" "^7.25.7" - "@babel/plugin-transform-class-static-block" "^7.25.8" - "@babel/plugin-transform-classes" "^7.25.7" - "@babel/plugin-transform-computed-properties" "^7.25.7" - "@babel/plugin-transform-destructuring" "^7.25.7" - "@babel/plugin-transform-dotall-regex" "^7.25.7" - "@babel/plugin-transform-duplicate-keys" "^7.25.7" - "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.7" - "@babel/plugin-transform-dynamic-import" "^7.25.8" - "@babel/plugin-transform-exponentiation-operator" "^7.25.7" - "@babel/plugin-transform-export-namespace-from" "^7.25.8" - "@babel/plugin-transform-for-of" "^7.25.7" - "@babel/plugin-transform-function-name" "^7.25.7" - "@babel/plugin-transform-json-strings" "^7.25.8" - "@babel/plugin-transform-literals" "^7.25.7" - "@babel/plugin-transform-logical-assignment-operators" "^7.25.8" - "@babel/plugin-transform-member-expression-literals" "^7.25.7" - "@babel/plugin-transform-modules-amd" "^7.25.7" - "@babel/plugin-transform-modules-commonjs" "^7.25.7" - "@babel/plugin-transform-modules-systemjs" "^7.25.7" - "@babel/plugin-transform-modules-umd" "^7.25.7" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.7" - "@babel/plugin-transform-new-target" "^7.25.7" - "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.8" - "@babel/plugin-transform-numeric-separator" "^7.25.8" - "@babel/plugin-transform-object-rest-spread" "^7.25.8" - "@babel/plugin-transform-object-super" "^7.25.7" - "@babel/plugin-transform-optional-catch-binding" "^7.25.8" - "@babel/plugin-transform-optional-chaining" "^7.25.8" - "@babel/plugin-transform-parameters" "^7.25.7" - "@babel/plugin-transform-private-methods" "^7.25.7" - "@babel/plugin-transform-private-property-in-object" "^7.25.8" - "@babel/plugin-transform-property-literals" "^7.25.7" - "@babel/plugin-transform-regenerator" "^7.25.7" - "@babel/plugin-transform-reserved-words" "^7.25.7" - "@babel/plugin-transform-shorthand-properties" "^7.25.7" - "@babel/plugin-transform-spread" "^7.25.7" - "@babel/plugin-transform-sticky-regex" "^7.25.7" - "@babel/plugin-transform-template-literals" "^7.25.7" - "@babel/plugin-transform-typeof-symbol" "^7.25.7" - "@babel/plugin-transform-unicode-escapes" "^7.25.7" - "@babel/plugin-transform-unicode-property-regex" "^7.25.7" - "@babel/plugin-transform-unicode-regex" "^7.25.7" - "@babel/plugin-transform-unicode-sets-regex" "^7.25.7" + "@babel/plugin-transform-arrow-functions" "^7.25.9" + "@babel/plugin-transform-async-generator-functions" "^7.25.9" + "@babel/plugin-transform-async-to-generator" "^7.25.9" + "@babel/plugin-transform-block-scoped-functions" "^7.25.9" + "@babel/plugin-transform-block-scoping" "^7.25.9" + "@babel/plugin-transform-class-properties" "^7.25.9" + "@babel/plugin-transform-class-static-block" "^7.26.0" + "@babel/plugin-transform-classes" "^7.25.9" + "@babel/plugin-transform-computed-properties" "^7.25.9" + "@babel/plugin-transform-destructuring" "^7.25.9" + "@babel/plugin-transform-dotall-regex" "^7.25.9" + "@babel/plugin-transform-duplicate-keys" "^7.25.9" + "@babel/plugin-transform-duplicate-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-dynamic-import" "^7.25.9" + "@babel/plugin-transform-exponentiation-operator" "^7.25.9" + "@babel/plugin-transform-export-namespace-from" "^7.25.9" + "@babel/plugin-transform-for-of" "^7.25.9" + "@babel/plugin-transform-function-name" "^7.25.9" + "@babel/plugin-transform-json-strings" "^7.25.9" + "@babel/plugin-transform-literals" "^7.25.9" + "@babel/plugin-transform-logical-assignment-operators" "^7.25.9" + "@babel/plugin-transform-member-expression-literals" "^7.25.9" + "@babel/plugin-transform-modules-amd" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-modules-systemjs" "^7.25.9" + "@babel/plugin-transform-modules-umd" "^7.25.9" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.25.9" + "@babel/plugin-transform-new-target" "^7.25.9" + "@babel/plugin-transform-nullish-coalescing-operator" "^7.25.9" + "@babel/plugin-transform-numeric-separator" "^7.25.9" + "@babel/plugin-transform-object-rest-spread" "^7.25.9" + "@babel/plugin-transform-object-super" "^7.25.9" + "@babel/plugin-transform-optional-catch-binding" "^7.25.9" + "@babel/plugin-transform-optional-chaining" "^7.25.9" + "@babel/plugin-transform-parameters" "^7.25.9" + "@babel/plugin-transform-private-methods" "^7.25.9" + "@babel/plugin-transform-private-property-in-object" "^7.25.9" + "@babel/plugin-transform-property-literals" "^7.25.9" + "@babel/plugin-transform-regenerator" "^7.25.9" + "@babel/plugin-transform-regexp-modifiers" "^7.26.0" + "@babel/plugin-transform-reserved-words" "^7.25.9" + "@babel/plugin-transform-shorthand-properties" "^7.25.9" + "@babel/plugin-transform-spread" "^7.25.9" + "@babel/plugin-transform-sticky-regex" "^7.25.9" + "@babel/plugin-transform-template-literals" "^7.25.9" + "@babel/plugin-transform-typeof-symbol" "^7.25.9" + "@babel/plugin-transform-unicode-escapes" "^7.25.9" + "@babel/plugin-transform-unicode-property-regex" "^7.25.9" + "@babel/plugin-transform-unicode-regex" "^7.25.9" + "@babel/plugin-transform-unicode-sets-regex" "^7.25.9" "@babel/preset-modules" "0.1.6-no-external-plugins" babel-plugin-polyfill-corejs2 "^0.4.10" babel-plugin-polyfill-corejs3 "^0.10.6" @@ -850,28 +902,28 @@ "@babel/types" "^7.4.4" esutils "^2.0.2" -"@babel/preset-react@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.25.7.tgz#081cbe1dea363b732764d06a0fdda67ffa17735d" - integrity sha512-GjV0/mUEEXpi1U5ZgDprMRRgajGMRW3G5FjMr5KLKD8nT2fTG8+h/klV3+6Dm5739QE+K5+2e91qFKAYI3pmRg== +"@babel/preset-react@7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.26.3.tgz#7c5e028d623b4683c1f83a0bd4713b9100560caa" + integrity sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-transform-react-display-name" "^7.25.7" - "@babel/plugin-transform-react-jsx" "^7.25.7" - "@babel/plugin-transform-react-jsx-development" "^7.25.7" - "@babel/plugin-transform-react-pure-annotations" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-transform-react-display-name" "^7.25.9" + "@babel/plugin-transform-react-jsx" "^7.25.9" + "@babel/plugin-transform-react-jsx-development" "^7.25.9" + "@babel/plugin-transform-react-pure-annotations" "^7.25.9" -"@babel/preset-typescript@7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.25.7.tgz#43c5b68eccb856ae5b52274b77b1c3c413cde1b7" - integrity sha512-rkkpaXJZOFN45Fb+Gki0c+KMIglk4+zZXOoMJuyEK8y8Kkc8Jd3BDmP7qPsz0zQMJj+UD7EprF+AqAXcILnexw== +"@babel/preset-typescript@7.26.0": + version "7.26.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.26.0.tgz#4a570f1b8d104a242d923957ffa1eaff142a106d" + integrity sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg== dependencies: - "@babel/helper-plugin-utils" "^7.25.7" - "@babel/helper-validator-option" "^7.25.7" - "@babel/plugin-syntax-jsx" "^7.25.7" - "@babel/plugin-transform-modules-commonjs" "^7.25.7" - "@babel/plugin-transform-typescript" "^7.25.7" + "@babel/helper-plugin-utils" "^7.25.9" + "@babel/helper-validator-option" "^7.25.9" + "@babel/plugin-syntax-jsx" "^7.25.9" + "@babel/plugin-transform-modules-commonjs" "^7.25.9" + "@babel/plugin-transform-typescript" "^7.25.9" "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.12.1", "@babel/runtime@^7.12.13", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2": version "7.25.7" @@ -880,29 +932,29 @@ dependencies: regenerator-runtime "^0.14.0" -"@babel/template@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.7.tgz#27f69ce382855d915b14ab0fe5fb4cbf88fa0769" - integrity sha512-wRwtAgI3bAS+JGU2upWNL9lSlDcRCqD05BZ1n3X2ONLH1WilFP6O1otQjeMK/1g0pvYcXC7b/qVUB1keofjtZA== +"@babel/template@^7.25.9": + version "7.25.9" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.25.9.tgz#ecb62d81a8a6f5dc5fe8abfc3901fc52ddf15016" + integrity sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg== dependencies: - "@babel/code-frame" "^7.25.7" - "@babel/parser" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/code-frame" "^7.25.9" + "@babel/parser" "^7.25.9" + "@babel/types" "^7.25.9" -"@babel/traverse@^7.25.7": - version "7.25.7" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.25.7.tgz#83e367619be1cab8e4f2892ef30ba04c26a40fa8" - integrity sha512-jatJPT1Zjqvh/1FyJs6qAHL+Dzb7sTb+xr7Q+gM1b+1oBsMsQQ4FkVKb6dFlJvLlVssqkRzV05Jzervt9yhnzg== +"@babel/traverse@^7.25.9": + version "7.26.4" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.26.4.tgz#ac3a2a84b908dde6d463c3bfa2c5fdc1653574bd" + integrity sha512-fH+b7Y4p3yqvApJALCPJcwb0/XaOSgtK4pzV6WVjPR5GLFQBRI7pfoX2V2iM48NXvX07NUxxm1Vw98YjqTcU5w== dependencies: - "@babel/code-frame" "^7.25.7" - "@babel/generator" "^7.25.7" - "@babel/parser" "^7.25.7" - "@babel/template" "^7.25.7" - "@babel/types" "^7.25.7" + "@babel/code-frame" "^7.26.2" + "@babel/generator" "^7.26.3" + "@babel/parser" "^7.26.3" + "@babel/template" "^7.25.9" + "@babel/types" "^7.26.3" debug "^4.3.1" globals "^11.1.0" -"@babel/types@^7.25.7", "@babel/types@^7.25.8", "@babel/types@^7.4.4": +"@babel/types@^7.25.7", "@babel/types@^7.4.4": version "7.25.8" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.25.8.tgz#5cf6037258e8a9bcad533f4979025140cb9993e1" integrity sha512-JWtuCu8VQsMladxVz/P4HzHUGCAwpuqacmowgXFs5XjxIgKuNjnLokQzuVjlTvIzODaDmpjT3oxcC48vyk9EWg== @@ -911,6 +963,14 @@ "@babel/helper-validator-identifier" "^7.25.7" to-fast-properties "^2.0.0" +"@babel/types@^7.25.9", "@babel/types@^7.26.0", "@babel/types@^7.26.3": + version "7.26.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.26.3.tgz#37e79830f04c2b5687acc77db97fbc75fb81f3c0" + integrity sha512-vN5p+1kl59GVKMvTHt55NzzmYVxprfJD+ql7U9NFIfKCBkYE55LYtS+WtPlaYOyzydrKI8Nezd+aZextrd+FMA== + dependencies: + "@babel/helper-string-parser" "^7.25.9" + "@babel/helper-validator-identifier" "^7.25.9" + "@csstools/css-parser-algorithms@^2.1.1": version "2.7.1" resolved "https://registry.yarnpkg.com/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.7.1.tgz#6d93a8f7d8aeb7cd9ed0868f946e46f021b6aa70" @@ -5769,6 +5829,18 @@ regexpu-core@^6.1.1: unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.1.0" +regexpu-core@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-6.2.0.tgz#0e5190d79e542bf294955dccabae04d3c7d53826" + integrity sha512-H66BPQMrv+V16t8xtmq+UC0CBpiTBA60V8ibS1QVReIp8T1z8hwFxqcGzm9K6lgsN7sB5edVH8a+ze6Fqm4weA== + dependencies: + regenerate "^1.4.2" + regenerate-unicode-properties "^10.2.0" + regjsgen "^0.8.0" + regjsparser "^0.12.0" + unicode-match-property-ecmascript "^2.0.0" + unicode-match-property-value-ecmascript "^2.1.0" + regjsgen@^0.8.0: version "0.8.0" resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.8.0.tgz#df23ff26e0c5b300a6470cad160a9d090c3a37ab" @@ -5781,6 +5853,13 @@ regjsparser@^0.11.0: dependencies: jsesc "~3.0.2" +regjsparser@^0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.12.0.tgz#0e846df6c6530586429377de56e0475583b088dc" + integrity sha512-cnE+y8bz4NhMjISKbgeVJtqNbtf5QpjZP+Bslo+UqkIt9QPnX9q095eiRRASJG1/tz6dlNr6Z5NsBiWYokp6EQ== + dependencies: + jsesc "~3.0.2" + relateurl@^0.2.7: version "0.2.7" resolved "https://registry.yarnpkg.com/relateurl/-/relateurl-0.2.7.tgz#54dbf377e51440aca90a4cd274600d3ff2d888a9" From 38f9543526d1cc57ffc3d05382535c0ed363a19b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 15 Dec 2024 08:45:49 -0800 Subject: [PATCH 142/579] Upgrade Font Awesome to 6.7.1 (cherry picked from commit 016b5718386593c030f14fcac307c93ee1ceeca6) --- package.json | 10 +++++----- yarn.lock | 56 ++++++++++++++++++++++++++-------------------------- 2 files changed, 33 insertions(+), 33 deletions(-) diff --git a/package.json b/package.json index 2f7e97f40d..ed3b3636c4 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "defaults" ], "dependencies": { - "@fortawesome/fontawesome-free": "6.6.0", - "@fortawesome/fontawesome-svg-core": "6.6.0", - "@fortawesome/free-brands-svg-icons": "6.6.0", - "@fortawesome/free-regular-svg-icons": "6.6.0", - "@fortawesome/free-solid-svg-icons": "6.6.0", + "@fortawesome/fontawesome-free": "6.7.1", + "@fortawesome/fontawesome-svg-core": "6.7.1", + "@fortawesome/free-brands-svg-icons": "6.7.1", + "@fortawesome/free-regular-svg-icons": "6.7.1", + "@fortawesome/free-solid-svg-icons": "6.7.1", "@fortawesome/react-fontawesome": "0.2.2", "@juggle/resize-observer": "3.4.0", "@microsoft/signalr": "6.0.25", diff --git a/yarn.lock b/yarn.lock index 39d3ddd5c9..4587462866 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1028,43 +1028,43 @@ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-8.57.1.tgz#de633db3ec2ef6a3c89e2f19038063e8a122e2c2" integrity sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q== -"@fortawesome/fontawesome-common-types@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.6.0.tgz#31ab07ca6a06358c5de4d295d4711b675006163f" - integrity sha512-xyX0X9mc0kyz9plIyryrRbl7ngsA9jz77mCZJsUkLl+ZKs0KWObgaEBoSgQiYWAsSmjz/yjl0F++Got0Mdp4Rw== +"@fortawesome/fontawesome-common-types@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.7.1.tgz#6201640f39fdcf8e41cd9d1a92b2da3a96817fa4" + integrity sha512-gbDz3TwRrIPT3i0cDfujhshnXO9z03IT1UKRIVi/VEjpNHtSBIP2o5XSm+e816FzzCFEzAxPw09Z13n20PaQJQ== -"@fortawesome/fontawesome-free@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.6.0.tgz#0e984f0f2344ee513c185d87d77defac4c0c8224" - integrity sha512-60G28ke/sXdtS9KZCpZSHHkCbdsOGEhIUGlwq6yhY74UpTiToIh8np7A8yphhM4BWsvNFtIvLpi4co+h9Mr9Ow== +"@fortawesome/fontawesome-free@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-free/-/fontawesome-free-6.7.1.tgz#160a48730d533ec77578ed0141661a8f0150a71d" + integrity sha512-ALIk/MOh5gYe1TG/ieS5mVUsk7VUIJTJKPMK9rFFqOgfp0Q3d5QiBXbcOMwUvs37fyZVCz46YjOE6IFeOAXCHA== -"@fortawesome/fontawesome-svg-core@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.6.0.tgz#2a24c32ef92136e98eae2ff334a27145188295ff" - integrity sha512-KHwPkCk6oRT4HADE7smhfsKudt9N/9lm6EJ5BVg0tD1yPA5hht837fB87F8pn15D8JfTqQOjhKTktwmLMiD7Kg== +"@fortawesome/fontawesome-svg-core@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.7.1.tgz#1f8ebb6f35cf02f89c110198514e848de17ac99e" + integrity sha512-8dBIHbfsKlCk2jHQ9PoRBg2Z+4TwyE3vZICSnoDlnsHA6SiMlTwfmW6yX0lHsRmWJugkeb92sA0hZdkXJhuz+g== dependencies: - "@fortawesome/fontawesome-common-types" "6.6.0" + "@fortawesome/fontawesome-common-types" "6.7.1" -"@fortawesome/free-brands-svg-icons@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.6.0.tgz#2797f2cc66d21e7e47fa64e680b8835e8d30e825" - integrity sha512-1MPD8lMNW/earme4OQi1IFHtmHUwAKgghXlNwWi9GO7QkTfD+IIaYpIai4m2YJEzqfEji3jFHX1DZI5pbY/biQ== +"@fortawesome/free-brands-svg-icons@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-brands-svg-icons/-/free-brands-svg-icons-6.7.1.tgz#1c1bbbac3ab897d02322b18fbbdf4d9b67ec1619" + integrity sha512-nJR76eqPzCnMyhbiGf6X0aclDirZriTPRcFm1YFvuupyJOGwlNF022w3YBqu+yrHRhnKRpzFX+8wJKqiIjWZkA== dependencies: - "@fortawesome/fontawesome-common-types" "6.6.0" + "@fortawesome/fontawesome-common-types" "6.7.1" -"@fortawesome/free-regular-svg-icons@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.6.0.tgz#fc49a947ac8dfd20403c9ea5f37f0919425bdf04" - integrity sha512-Yv9hDzL4aI73BEwSEh20clrY8q/uLxawaQ98lekBx6t9dQKDHcDzzV1p2YtBGTtolYtNqcWdniOnhzB+JPnQEQ== +"@fortawesome/free-regular-svg-icons@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.7.1.tgz#d7ec06f896ee91116a388a5a234cd26420ccdfe4" + integrity sha512-e13cp+bAx716RZOTQ59DhqikAgETA9u1qTBHO3e3jMQQ+4H/N1NC1ZVeFYt1V0m+Th68BrEL1/X6XplISutbXg== dependencies: - "@fortawesome/fontawesome-common-types" "6.6.0" + "@fortawesome/fontawesome-common-types" "6.7.1" -"@fortawesome/free-solid-svg-icons@6.6.0": - version "6.6.0" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.6.0.tgz#061751ca43be4c4d814f0adbda8f006164ec9f3b" - integrity sha512-IYv/2skhEDFc2WGUcqvFJkeK39Q+HyPf5GHUrT/l2pKbtgEIv1al1TKd6qStR5OIwQdN1GZP54ci3y4mroJWjA== +"@fortawesome/free-solid-svg-icons@6.7.1": + version "6.7.1" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.7.1.tgz#c1f9a6c25562a12c283e87e284f9d82a5b0dbcc0" + integrity sha512-BTKc0b0mgjWZ2UDKVgmwaE0qt0cZs6ITcDgjrti5f/ki7aF5zs+N91V6hitGo3TItCFtnKg6cUVGdTmBFICFRg== dependencies: - "@fortawesome/fontawesome-common-types" "6.6.0" + "@fortawesome/fontawesome-common-types" "6.7.1" "@fortawesome/react-fontawesome@0.2.2": version "0.2.2" From 5efefd804bcb8f9350d324e5e5f456fa90855c17 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Mon, 16 Dec 2024 16:09:27 -0800 Subject: [PATCH 143/579] Upgrade @typescript-eslint packages to 8.181.1 (cherry picked from commit ed10b63fa0c161cac7e0a2084e53785ab1798208) --- frontend/src/App/State/MetadataAppState.ts | 2 +- frontend/src/App/State/MovieCreditAppState.ts | 2 +- frontend/src/App/State/SettingsAppState.ts | 3 +- .../Components/Table/Cells/TableRowCell.tsx | 2 +- .../src/Utilities/String/getLanguageName.ts | 2 +- frontend/src/Utilities/String/translate.ts | 2 +- package.json | 4 +- yarn.lock | 170 +++++++++--------- 8 files changed, 93 insertions(+), 94 deletions(-) diff --git a/frontend/src/App/State/MetadataAppState.ts b/frontend/src/App/State/MetadataAppState.ts index 60d5c434cb..495f109d8b 100644 --- a/frontend/src/App/State/MetadataAppState.ts +++ b/frontend/src/App/State/MetadataAppState.ts @@ -1,6 +1,6 @@ import { AppSectionProviderState } from 'App/State/AppSectionState'; import Metadata from 'typings/Metadata'; -interface MetadataAppState extends AppSectionProviderState {} +type MetadataAppState = AppSectionProviderState; export default MetadataAppState; diff --git a/frontend/src/App/State/MovieCreditAppState.ts b/frontend/src/App/State/MovieCreditAppState.ts index 424de2ca46..31c418616c 100644 --- a/frontend/src/App/State/MovieCreditAppState.ts +++ b/frontend/src/App/State/MovieCreditAppState.ts @@ -1,6 +1,6 @@ import AppSectionState from 'App/State/AppSectionState'; import MovieCredit from 'typings/MovieCredit'; -interface MovieCreditAppState extends AppSectionState {} +type MovieCreditAppState = AppSectionState; export default MovieCreditAppState; diff --git a/frontend/src/App/State/SettingsAppState.ts b/frontend/src/App/State/SettingsAppState.ts index b9f8e64b48..af81ed7b8e 100644 --- a/frontend/src/App/State/SettingsAppState.ts +++ b/frontend/src/App/State/SettingsAppState.ts @@ -37,8 +37,7 @@ export interface NamingAppState extends AppSectionItemState, AppSectionSaveState {} -export interface NamingExamplesAppState - extends AppSectionItemState {} +export type NamingExamplesAppState = AppSectionItemState; export interface ImportListAppState extends AppSectionState, diff --git a/frontend/src/Components/Table/Cells/TableRowCell.tsx b/frontend/src/Components/Table/Cells/TableRowCell.tsx index 00b6acb1d6..aed6932223 100644 --- a/frontend/src/Components/Table/Cells/TableRowCell.tsx +++ b/frontend/src/Components/Table/Cells/TableRowCell.tsx @@ -1,7 +1,7 @@ import React, { ComponentPropsWithoutRef } from 'react'; import styles from './TableRowCell.css'; -export interface TableRowCellProps extends ComponentPropsWithoutRef<'td'> {} +export type TableRowCellProps = ComponentPropsWithoutRef<'td'>; export default function TableRowCell({ className = styles.cell, diff --git a/frontend/src/Utilities/String/getLanguageName.ts b/frontend/src/Utilities/String/getLanguageName.ts index bf1b5451ee..6bbaf32524 100644 --- a/frontend/src/Utilities/String/getLanguageName.ts +++ b/frontend/src/Utilities/String/getLanguageName.ts @@ -35,7 +35,7 @@ export default function getLanguageName(code: string) { try { return languageNames.of(code) ?? code; - } catch (error) { + } catch { return code; } } diff --git a/frontend/src/Utilities/String/translate.ts b/frontend/src/Utilities/String/translate.ts index f4cab8ec6d..11abc3116e 100644 --- a/frontend/src/Utilities/String/translate.ts +++ b/frontend/src/Utilities/String/translate.ts @@ -17,7 +17,7 @@ export async function fetchTranslations(): Promise { translations = data.Strings; resolve(true); - } catch (error) { + } catch { resolve(false); } }); diff --git a/package.json b/package.json index ed3b3636c4..fbfa42482b 100644 --- a/package.json +++ b/package.json @@ -102,8 +102,8 @@ "@types/react-window": "1.8.8", "@types/redux-actions": "2.6.5", "@types/webpack-livereload-plugin": "2.3.6", - "@typescript-eslint/eslint-plugin": "6.21.0", - "@typescript-eslint/parser": "6.21.0", + "@typescript-eslint/eslint-plugin": "8.18.1", + "@typescript-eslint/parser": "8.18.1", "autoprefixer": "10.4.20", "babel-loader": "9.2.1", "babel-plugin-inline-classnames": "2.0.1", diff --git a/yarn.lock b/yarn.lock index 4587462866..d60c4e453b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1003,7 +1003,12 @@ dependencies: eslint-visitor-keys "^3.3.0" -"@eslint-community/regexpp@^4.5.1", "@eslint-community/regexpp@^4.6.1": +"@eslint-community/regexpp@^4.10.0": + version "4.12.1" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" + integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ== + +"@eslint-community/regexpp@^4.6.1": version "4.11.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.11.1.tgz#a547badfc719eb3e5f4b556325e542fbe9d7a18f" integrity sha512-m4DVN9ZqskZoLU5GlWZadwDnYo3vAEydiUayB9widCl9ffWx2IvPnp6n3on5rJmziJSw9Bv+Z3ChDVdMwXCY8Q== @@ -1320,7 +1325,7 @@ resolved "https://registry.yarnpkg.com/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz#4fc33a00c1d0c16987b1a20cf92d20614c55ac35" integrity sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg== -"@types/json-schema@^7.0.12", "@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": +"@types/json-schema@^7.0.8", "@types/json-schema@^7.0.9": version "7.0.15" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.15.tgz#596a1747233694d50f6ad8a7869fcb6f56cf5841" integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== @@ -1473,11 +1478,6 @@ resolved "https://registry.yarnpkg.com/@types/redux-actions/-/redux-actions-2.6.5.tgz#3728477ada6c4bc0fe54ffae11def23a65c0714b" integrity sha512-RgXOigay5cNweP+xH1ru+Vaaj1xXYLpWIfSVO8cSA8Ii2xvR+HRfWYdLe1UVOA8X0kIklalGOa0DTDyld0obkg== -"@types/semver@^7.5.0": - version "7.5.8" - resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.5.8.tgz#8268a8c57a3e4abd25c165ecd36237db7948a55e" - integrity sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ== - "@types/source-list-map@*": version "0.1.6" resolved "https://registry.yarnpkg.com/@types/source-list-map/-/source-list-map-0.1.6.tgz#164e169dd061795b50b83c19e4d3be09f8d3a454" @@ -1523,91 +1523,86 @@ anymatch "^3.0.0" source-map "^0.6.0" -"@typescript-eslint/eslint-plugin@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz#30830c1ca81fd5f3c2714e524c4303e0194f9cd3" - integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA== +"@typescript-eslint/eslint-plugin@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.18.1.tgz#992e5ac1553ce20d0d46aa6eccd79dc36dedc805" + integrity sha512-Ncvsq5CT3Gvh+uJG0Lwlho6suwDfUXH0HztslDf5I+F2wAFAZMRwYLEorumpKLzmO2suAXZ/td1tBg4NZIi9CQ== dependencies: - "@eslint-community/regexpp" "^4.5.1" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/type-utils" "6.21.0" - "@typescript-eslint/utils" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" - debug "^4.3.4" + "@eslint-community/regexpp" "^4.10.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/type-utils" "8.18.1" + "@typescript-eslint/utils" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" graphemer "^1.4.0" - ignore "^5.2.4" + ignore "^5.3.1" natural-compare "^1.4.0" - semver "^7.5.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/parser@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-6.21.0.tgz#af8fcf66feee2edc86bc5d1cf45e33b0630bf35b" - integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ== +"@typescript-eslint/parser@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.18.1.tgz#c258bae062778b7696793bc492249027a39dfb95" + integrity sha512-rBnTWHCdbYM2lh7hjyXqxk70wvon3p2FyaniZuey5TrcGBpfhVp0OxOa6gxr9Q9YhZFKyfbEnxc24ZnVbbUkCA== dependencies: - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" debug "^4.3.4" -"@typescript-eslint/scope-manager@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz#ea8a9bfc8f1504a6ac5d59a6df308d3a0630a2b1" - integrity sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg== +"@typescript-eslint/scope-manager@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.18.1.tgz#52cedc3a8178d7464a70beffed3203678648e55b" + integrity sha512-HxfHo2b090M5s2+/9Z3gkBhI6xBH8OJCFjH9MhQ+nnoZqxU3wNxkLT+VWXWSFWc3UF3Z+CfPAyqdCTdoXtDPCQ== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" -"@typescript-eslint/type-utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-6.21.0.tgz#6473281cfed4dacabe8004e8521cee0bd9d4c01e" - integrity sha512-rZQI7wHfao8qMX3Rd3xqeYSMCL3SoiSQLBATSiVKARdFGCYSRvmViieZjqc58jKgs8Y8i9YvVVhRbHSTA4VBag== +"@typescript-eslint/type-utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.18.1.tgz#10f41285475c0bdee452b79ff7223f0e43a7781e" + integrity sha512-jAhTdK/Qx2NJPNOTxXpMwlOiSymtR2j283TtPqXkKBdH8OAMmhiUfP0kJjc/qSE51Xrq02Gj9NY7MwK+UxVwHQ== dependencies: - "@typescript-eslint/typescript-estree" "6.21.0" - "@typescript-eslint/utils" "6.21.0" + "@typescript-eslint/typescript-estree" "8.18.1" + "@typescript-eslint/utils" "8.18.1" debug "^4.3.4" - ts-api-utils "^1.0.1" + ts-api-utils "^1.3.0" -"@typescript-eslint/types@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-6.21.0.tgz#205724c5123a8fef7ecd195075fa6e85bac3436d" - integrity sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg== +"@typescript-eslint/types@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.18.1.tgz#d7f4f94d0bba9ebd088de840266fcd45408a8fff" + integrity sha512-7uoAUsCj66qdNQNpH2G8MyTFlgerum8ubf21s3TSM3XmKXuIn+H2Sifh/ES2nPOPiYSRJWAk0fDkW0APBWcpfw== -"@typescript-eslint/typescript-estree@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz#c47ae7901db3b8bddc3ecd73daff2d0895688c46" - integrity sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ== +"@typescript-eslint/typescript-estree@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.18.1.tgz#2a86cd64b211a742f78dfa7e6f4860413475367e" + integrity sha512-z8U21WI5txzl2XYOW7i9hJhxoKKNG1kcU4RzyNvKrdZDmbjkmLBo8bgeiOJmA06kizLI76/CCBAAGlTlEeUfyg== dependencies: - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/visitor-keys" "6.21.0" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/visitor-keys" "8.18.1" debug "^4.3.4" - globby "^11.1.0" + fast-glob "^3.3.2" is-glob "^4.0.3" - minimatch "9.0.3" - semver "^7.5.4" - ts-api-utils "^1.0.1" + minimatch "^9.0.4" + semver "^7.6.0" + ts-api-utils "^1.3.0" -"@typescript-eslint/utils@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-6.21.0.tgz#4714e7a6b39e773c1c8e97ec587f520840cd8134" - integrity sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ== +"@typescript-eslint/utils@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.18.1.tgz#c4199ea23fc823c736e2c96fd07b1f7235fa92d5" + integrity sha512-8vikiIj2ebrC4WRdcAdDcmnu9Q/MXXwg+STf40BVfT8exDqBCUPdypvzcUPxEqRGKg9ALagZ0UWcYCtn+4W2iQ== dependencies: "@eslint-community/eslint-utils" "^4.4.0" - "@types/json-schema" "^7.0.12" - "@types/semver" "^7.5.0" - "@typescript-eslint/scope-manager" "6.21.0" - "@typescript-eslint/types" "6.21.0" - "@typescript-eslint/typescript-estree" "6.21.0" - semver "^7.5.4" + "@typescript-eslint/scope-manager" "8.18.1" + "@typescript-eslint/types" "8.18.1" + "@typescript-eslint/typescript-estree" "8.18.1" -"@typescript-eslint/visitor-keys@6.21.0": - version "6.21.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz#87a99d077aa507e20e238b11d56cc26ade45fe47" - integrity sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A== +"@typescript-eslint/visitor-keys@8.18.1": + version "8.18.1" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.18.1.tgz#344b4f6bc83f104f514676facf3129260df7610a" + integrity sha512-Vj0WLm5/ZsD013YeUKn+K0y8p1M0jPpxOkKdbD1wB0ns53a5piVY02zjf072TblEweAbcYiFiPoSMF3kp+VhhQ== dependencies: - "@typescript-eslint/types" "6.21.0" - eslint-visitor-keys "^3.4.1" + "@typescript-eslint/types" "8.18.1" + eslint-visitor-keys "^4.2.0" "@ungap/structured-clone@^1.2.0": version "1.2.0" @@ -3185,6 +3180,11 @@ eslint-visitor-keys@^3.3.0, eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4 resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz#0cd72fe8550e3c2eae156a96a4dddcd1c8ac5800" integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag== +eslint-visitor-keys@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz#687bacb2af884fcdda8a6e7d65c606f46a14cd45" + integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw== + eslint@8.57.1: version "8.57.1" resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.57.1.tgz#7df109654aba7e3bbe5c8eae533c5e461d3c6ca9" @@ -3292,7 +3292,7 @@ fast-diff@^1.1.2: resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.3.0.tgz#ece407fa550a64d638536cd727e129c61616e0f0" integrity sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw== -fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9: +fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.9, fast-glob@^3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.3.2.tgz#a904501e57cfdd2ffcded45e99a54fef55e46129" integrity sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow== @@ -3831,7 +3831,7 @@ ieee754@^1.1.13: resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== -ignore@^5.2.0, ignore@^5.2.4: +ignore@^5.2.0, ignore@^5.2.4, ignore@^5.3.1: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -4666,13 +4666,6 @@ mini-css-extract-plugin@2.9.1: schema-utils "^4.0.0" tapable "^2.2.1" -minimatch@9.0.3: - version "9.0.3" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.3.tgz#a6e00c3de44c3a542bfaae70abfc22420a6da825" - integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg== - dependencies: - brace-expansion "^2.0.1" - minimatch@^10.0.0: version "10.0.1" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.0.1.tgz#ce0521856b453c86e25f2c4c0d03e6ff7ddc440b" @@ -4694,6 +4687,13 @@ minimatch@^5.1.0: dependencies: brace-expansion "^2.0.1" +minimatch@^9.0.4: + version "9.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" + integrity sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow== + dependencies: + brace-expansion "^2.0.1" + minimatch@~3.0.4: version "3.0.8" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.8.tgz#5e6a59bd11e2ab0de1cfb843eb2d82e546c321c1" @@ -6082,7 +6082,7 @@ semver@^6.0.0, semver@^6.3.1: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.1.tgz#556d2ef8689146e46dcea4bfdd095f3434dffcb4" integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA== -semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.5.4: +semver@^7.3.4, semver@^7.3.5, semver@^7.3.8, semver@^7.6.0: version "7.6.3" resolved "https://registry.yarnpkg.com/semver/-/semver-7.6.3.tgz#980f7b5550bc175fb4dc09403085627f9eb33143" integrity sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A== @@ -6665,10 +6665,10 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== -ts-api-utils@^1.0.1: - version "1.3.0" - resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.3.0.tgz#4b490e27129f1e8e686b45cc4ab63714dc60eea1" - integrity sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ== +ts-api-utils@^1.3.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/ts-api-utils/-/ts-api-utils-1.4.3.tgz#bfc2215fe6528fecab2b0fba570a2e8a4263b064" + integrity sha512-i3eMG77UTMD0hZhgRS562pv83RC6ukSAC2GMNWc+9dieh/+jDM5u5YG+NHX6VNDRHQcHwmsTHctP9LhbC3WxVw== ts-loader@9.5.1: version "9.5.1" From c81b2e80ee22bbe0acc3d48b04d151612f5b187b Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 7 Dec 2024 19:04:18 -0800 Subject: [PATCH 144/579] Convert MediaInfo to TypeScript (cherry picked from commit 4e4bf3507f20c0f8581c66804f8ef406c41952d8) Closes #10753 --- frontend/src/MovieFile/Editor/MediaInfo.tsx | 27 +++++ .../src/MovieFile/Editor/MediaInfoPopover.js | 33 ------ .../MovieFile/Editor/MovieFileEditorRow.js | 12 +- frontend/src/MovieFile/FileDetailsModal.js | 4 +- frontend/src/MovieFile/MediaInfo.js | 104 ------------------ frontend/src/MovieFile/MediaInfo.tsx | 92 ++++++++++++++++ frontend/src/MovieFile/MediaInfoConnector.js | 21 ---- .../MovieFile/MovieFileLanguageConnector.js | 17 --- frontend/src/MovieFile/MovieFileLanguages.tsx | 15 +++ frontend/src/MovieFile/useMovieFile.ts | 18 +++ frontend/src/Utilities/Object/getEntries.ts | 9 ++ .../src/Wanted/CutoffUnmet/CutoffUnmetRow.js | 4 +- 12 files changed, 171 insertions(+), 185 deletions(-) create mode 100644 frontend/src/MovieFile/Editor/MediaInfo.tsx delete mode 100644 frontend/src/MovieFile/Editor/MediaInfoPopover.js delete mode 100644 frontend/src/MovieFile/MediaInfo.js create mode 100644 frontend/src/MovieFile/MediaInfo.tsx delete mode 100644 frontend/src/MovieFile/MediaInfoConnector.js delete mode 100644 frontend/src/MovieFile/MovieFileLanguageConnector.js create mode 100644 frontend/src/MovieFile/MovieFileLanguages.tsx create mode 100644 frontend/src/MovieFile/useMovieFile.ts create mode 100644 frontend/src/Utilities/Object/getEntries.ts diff --git a/frontend/src/MovieFile/Editor/MediaInfo.tsx b/frontend/src/MovieFile/Editor/MediaInfo.tsx new file mode 100644 index 0000000000..d0a8951750 --- /dev/null +++ b/frontend/src/MovieFile/Editor/MediaInfo.tsx @@ -0,0 +1,27 @@ +import React from 'react'; +import DescriptionList from 'Components/DescriptionList/DescriptionList'; +import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; +import MediaInfoProps from 'typings/MediaInfo'; +import getEntries from 'Utilities/Object/getEntries'; + +function MediaInfo(props: MediaInfoProps) { + return ( + + {getEntries(props).map(([key, value]) => { + const title = key + .replace(/([A-Z])/g, ' $1') + .replace(/^./, (str) => str.toUpperCase()); + + if (!value) { + return null; + } + + return ( + + ); + })} + + ); +} + +export default MediaInfo; diff --git a/frontend/src/MovieFile/Editor/MediaInfoPopover.js b/frontend/src/MovieFile/Editor/MediaInfoPopover.js deleted file mode 100644 index a3d0d24031..0000000000 --- a/frontend/src/MovieFile/Editor/MediaInfoPopover.js +++ /dev/null @@ -1,33 +0,0 @@ -import React from 'react'; -import DescriptionList from 'Components/DescriptionList/DescriptionList'; -import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; - -function MediaInfoPopover(props) { - return ( - - { - Object.keys(props).map((key) => { - const title = key - .replace(/([A-Z])/g, ' $1') - .replace(/^./, (str) => str.toUpperCase()); - - const value = props[key]; - - if (!value) { - return null; - } - - return ( - - ); - }) - } - - ); -} - -export default MediaInfoPopover; diff --git a/frontend/src/MovieFile/Editor/MovieFileEditorRow.js b/frontend/src/MovieFile/Editor/MovieFileEditorRow.js index f93e318380..4659b8d5e8 100644 --- a/frontend/src/MovieFile/Editor/MovieFileEditorRow.js +++ b/frontend/src/MovieFile/Editor/MovieFileEditorRow.js @@ -14,7 +14,7 @@ import MovieFormats from 'Movie/MovieFormats'; import MovieLanguages from 'Movie/MovieLanguages'; import MovieQuality from 'Movie/MovieQuality'; import FileEditModal from 'MovieFile/Edit/FileEditModal'; -import MediaInfoConnector from 'MovieFile/MediaInfoConnector'; +import MediaInfo from 'MovieFile/MediaInfo'; import * as mediaInfoTypes from 'MovieFile/mediaInfoTypes'; import formatBytes from 'Utilities/Number/formatBytes'; import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; @@ -224,7 +224,7 @@ class MovieFileEditorRow extends Component { key={name} className={styles.audio} > - @@ -238,7 +238,7 @@ class MovieFileEditorRow extends Component { key={name} className={styles.audioLanguages} > - @@ -252,7 +252,7 @@ class MovieFileEditorRow extends Component { key={name} className={styles.subtitles} > - @@ -266,7 +266,7 @@ class MovieFileEditorRow extends Component { key={name} className={styles.video} > - @@ -280,7 +280,7 @@ class MovieFileEditorRow extends Component { key={name} className={styles.videoDynamicRangeType} > - diff --git a/frontend/src/MovieFile/FileDetailsModal.js b/frontend/src/MovieFile/FileDetailsModal.js index dd19b31375..2917d1bc70 100644 --- a/frontend/src/MovieFile/FileDetailsModal.js +++ b/frontend/src/MovieFile/FileDetailsModal.js @@ -8,7 +8,7 @@ import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { sizes } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; -import MediaInfoPopover from './Editor/MediaInfoPopover'; +import MediaInfo from './Editor/MediaInfo'; function FileDetailsModal(props) { const { @@ -31,7 +31,7 @@ function FileDetailsModal(props) { - + diff --git a/frontend/src/MovieFile/MediaInfo.js b/frontend/src/MovieFile/MediaInfo.js deleted file mode 100644 index e45e4b472a..0000000000 --- a/frontend/src/MovieFile/MediaInfo.js +++ /dev/null @@ -1,104 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React from 'react'; -import getLanguageName from 'Utilities/String/getLanguageName'; -import translate from 'Utilities/String/translate'; -import * as mediaInfoTypes from './mediaInfoTypes'; - -function formatLanguages(languages) { - if (!languages) { - return null; - } - - const splitLanguages = _.uniq(languages.split('/')).map((l) => { - const simpleLanguage = l.split('_')[0]; - - if (simpleLanguage === 'und') { - return translate('Unknown'); - } - - return getLanguageName(simpleLanguage); - }); - - if (splitLanguages.length > 3) { - return ( - - {splitLanguages.slice(0, 2).join(', ')}, {splitLanguages.length - 2} more - - ); - } - - return ( - - {splitLanguages.join(', ')} - - ); -} - -function MediaInfo(props) { - const { - type, - audioChannels, - audioCodec, - audioLanguages, - subtitles, - videoCodec, - videoDynamicRangeType - } = props; - - if (type === mediaInfoTypes.AUDIO) { - return ( - - { - audioCodec ? audioCodec : '' - } - - { - audioCodec && audioChannels ? ' - ' : '' - } - - { - audioChannels ? audioChannels.toFixed(1) : '' - } - - ); - } - - if (type === mediaInfoTypes.AUDIO_LANGUAGES) { - return formatLanguages(audioLanguages); - } - - if (type === mediaInfoTypes.SUBTITLES) { - return formatLanguages(subtitles); - } - - if (type === mediaInfoTypes.VIDEO) { - return ( - - {videoCodec} - - ); - } - - if (type === mediaInfoTypes.VIDEO_DYNAMIC_RANGE_TYPE) { - return ( - - {videoDynamicRangeType} - - ); - } - - return null; -} - -MediaInfo.propTypes = { - type: PropTypes.string.isRequired, - audioChannels: PropTypes.number, - audioCodec: PropTypes.string, - audioLanguages: PropTypes.string, - subtitles: PropTypes.string, - videoCodec: PropTypes.string, - videoDynamicRangeType: PropTypes.string -}; - -export default MediaInfo; diff --git a/frontend/src/MovieFile/MediaInfo.tsx b/frontend/src/MovieFile/MediaInfo.tsx new file mode 100644 index 0000000000..0e94b15a3c --- /dev/null +++ b/frontend/src/MovieFile/MediaInfo.tsx @@ -0,0 +1,92 @@ +import React from 'react'; +import getLanguageName from 'Utilities/String/getLanguageName'; +import translate from 'Utilities/String/translate'; +import useMovieFile from './useMovieFile'; + +function formatLanguages(languages: string | undefined) { + if (!languages) { + return null; + } + + const splitLanguages = [...new Set(languages.split('/'))].map((l) => { + const simpleLanguage = l.split('_')[0]; + + if (simpleLanguage === 'und') { + return translate('Unknown'); + } + + return getLanguageName(simpleLanguage); + }); + + if (splitLanguages.length > 3) { + return ( + + {splitLanguages.slice(0, 2).join(', ')}, {splitLanguages.length - 2}{' '} + more + + ); + } + + return {splitLanguages.join(', ')}; +} + +export type MediaInfoType = + | 'audio' + | 'audioLanguages' + | 'subtitles' + | 'video' + | 'videoDynamicRangeType'; + +interface MediaInfoProps { + movieFileId?: number; + type: MediaInfoType; +} + +function MediaInfo({ movieFileId, type }: MediaInfoProps) { + const movieFile = useMovieFile(movieFileId); + + if (!movieFile?.mediaInfo) { + return null; + } + + const { + audioChannels, + audioCodec, + audioLanguages, + subtitles, + videoCodec, + videoDynamicRangeType, + } = movieFile.mediaInfo; + + if (type === 'audio') { + return ( + + {audioCodec ? audioCodec : ''} + + {audioCodec && audioChannels ? ' - ' : ''} + + {audioChannels ? audioChannels.toFixed(1) : ''} + + ); + } + + if (type === 'audioLanguages') { + return formatLanguages(audioLanguages); + } + + if (type === 'subtitles') { + return formatLanguages(subtitles); + } + + if (type === 'video') { + return {videoCodec}; + } + + if (type === 'videoDynamicRangeType') { + return {videoDynamicRangeType}; + } + + return null; +} + +export default MediaInfo; diff --git a/frontend/src/MovieFile/MediaInfoConnector.js b/frontend/src/MovieFile/MediaInfoConnector.js deleted file mode 100644 index ce955c8aa5..0000000000 --- a/frontend/src/MovieFile/MediaInfoConnector.js +++ /dev/null @@ -1,21 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import createMovieFileSelector from 'Store/Selectors/createMovieFileSelector'; -import MediaInfo from './MediaInfo'; - -function createMapStateToProps() { - return createSelector( - createMovieFileSelector(), - (movieFile) => { - if (movieFile) { - return { - ...movieFile.mediaInfo - }; - } - - return {}; - } - ); -} - -export default connect(createMapStateToProps)(MediaInfo); diff --git a/frontend/src/MovieFile/MovieFileLanguageConnector.js b/frontend/src/MovieFile/MovieFileLanguageConnector.js deleted file mode 100644 index 4bbd412366..0000000000 --- a/frontend/src/MovieFile/MovieFileLanguageConnector.js +++ /dev/null @@ -1,17 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import MovieLanguages from 'Movie/MovieLanguages'; -import createMovieFileSelector from 'Store/Selectors/createMovieFileSelector'; - -function createMapStateToProps() { - return createSelector( - createMovieFileSelector(), - (movieFile) => { - return { - languages: movieFile ? movieFile.languages : undefined - }; - } - ); -} - -export default connect(createMapStateToProps)(MovieLanguages); diff --git a/frontend/src/MovieFile/MovieFileLanguages.tsx b/frontend/src/MovieFile/MovieFileLanguages.tsx new file mode 100644 index 0000000000..2880417878 --- /dev/null +++ b/frontend/src/MovieFile/MovieFileLanguages.tsx @@ -0,0 +1,15 @@ +import React from 'react'; +import MovieLanguages from 'Movie/MovieLanguages'; +import useMovieFile from './useMovieFile'; + +interface MovieFileLanguagesProps { + movieFileId: number; +} + +function MovieFileLanguages({ movieFileId }: MovieFileLanguagesProps) { + const movieFile = useMovieFile(movieFileId); + + return ; +} + +export default MovieFileLanguages; diff --git a/frontend/src/MovieFile/useMovieFile.ts b/frontend/src/MovieFile/useMovieFile.ts new file mode 100644 index 0000000000..143415db80 --- /dev/null +++ b/frontend/src/MovieFile/useMovieFile.ts @@ -0,0 +1,18 @@ +import { useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; + +function createMovieFileSelector(movieFileId?: number) { + return createSelector( + (state: AppState) => state.movieFiles.items, + (movieFiles) => { + return movieFiles.find(({ id }) => id === movieFileId); + } + ); +} + +function useMovieFile(movieFileId: number | undefined) { + return useSelector(createMovieFileSelector(movieFileId)); +} + +export default useMovieFile; diff --git a/frontend/src/Utilities/Object/getEntries.ts b/frontend/src/Utilities/Object/getEntries.ts new file mode 100644 index 0000000000..ca540c5dae --- /dev/null +++ b/frontend/src/Utilities/Object/getEntries.ts @@ -0,0 +1,9 @@ +export type Entries = { + [K in keyof T]: [K, T[K]]; +}[keyof T][]; + +function getEntries(obj: T): Entries { + return Object.entries(obj) as Entries; +} + +export default getEntries; diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js index d0b8ff8eae..eb83e34dd2 100644 --- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js +++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js @@ -8,7 +8,7 @@ import movieEntities from 'Movie/movieEntities'; import MovieSearchCell from 'Movie/MovieSearchCell'; import MovieStatusConnector from 'Movie/MovieStatusConnector'; import MovieTitleLink from 'Movie/MovieTitleLink'; -import MovieFileLanguageConnector from 'MovieFile/MovieFileLanguageConnector'; +import MovieFileLanguages from 'MovieFile/MovieFileLanguages'; import styles from './CutoffUnmetRow.css'; function CutoffUnmetRow(props) { @@ -104,7 +104,7 @@ function CutoffUnmetRow(props) { key={name} className={styles.languages} > - From f1d7c56d94d550ecf810f1826524f7def78b1d65 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Fri, 6 Dec 2024 20:27:11 -0800 Subject: [PATCH 145/579] Fixed: Custom Format score bypassing upgrades not being allowed (cherry picked from commit ebe23104d4b29a3c900a982fb84e75c27ed531ab) Co-authored-by: CeruleanRed --- .../UpgradeDiskSpecificationFixture.cs | 38 +++++++++++++++++++ .../UpgradeSpecificationFixture.cs | 2 +- .../Specifications/QueueSpecification.cs | 12 +----- .../RssSync/HistorySpecification.cs | 3 ++ .../Specifications/UpgradableSpecification.cs | 9 ++++- .../UpgradeDiskSpecification.cs | 3 ++ .../DecisionEngine/UpgradeableRejectReason.cs | 3 +- 7 files changed, 57 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs index 6a56e98516..19d1ec5924 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeDiskSpecificationFixture.cs @@ -5,6 +5,7 @@ using Moq; using NUnit.Framework; using NzbDrone.Common.Serializer; +using NzbDrone.Core.Configuration; using NzbDrone.Core.CustomFormats; using NzbDrone.Core.DecisionEngine.Specifications; using NzbDrone.Core.MediaFiles; @@ -337,5 +338,42 @@ public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_f Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); } + + [Test] + public void should_return_false_if_quality_profile_does_not_allow_upgrades_but_format_cutoff_is_above_current_score_and_is_revision_upgrade() + { + var customFormat = new CustomFormat("My Format", new ResolutionSpecification { Value = (int)Resolution.R1080p }) { Id = 1 }; + + Mocker.GetMock() + .SetupGet(s => s.DownloadPropersAndRepacks) + .Returns(ProperDownloadTypes.DoNotPrefer); + + GivenProfile(new QualityProfile + { + Cutoff = Quality.SDTV.Id, + MinFormatScore = 0, + CutoffFormatScore = 10000, + Items = Qualities.QualityFixture.GetDefaultQualities(), + FormatItems = CustomFormatsTestHelpers.GetSampleFormatItems("My Format"), + UpgradeAllowed = false + }); + + _parseResultSingle.Movie.QualityProfile.FormatItems = new List + { + new ProfileFormatItem + { + Format = customFormat, + Score = 50 + } + }; + + GivenFileQuality(new QualityModel(Quality.WEBDL1080p, new Revision(version: 1))); + GivenNewQuality(new QualityModel(Quality.WEBDL1080p, new Revision(version: 2))); + + GivenOldCustomFormats(new List()); + GivenNewCustomFormats(new List { customFormat }); + + Subject.IsSatisfiedBy(_parseResultSingle, null).Accepted.Should().BeFalse(); + } } } diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs index a3116aaf96..f9de729b0b 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs @@ -121,7 +121,7 @@ public void should_return_false_if_release_and_existing_file_are_the_same() new List(), new QualityModel(Quality.HDTV720p, new Revision(version: 1)), new List()) - .Should().Be(UpgradeableRejectReason.CustomFormatScore); + .Should().Be(UpgradeableRejectReason.UpgradesNotAllowed); } [Test] diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs index d67c79c0f2..f4d96eb763 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs @@ -96,17 +96,9 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit case UpgradeableRejectReason.MinCustomFormatScore: return Decision.Reject("Release in queue has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); - } - _logger.Debug("Checking if profiles allow upgrading. Queued: {0}", remoteMovie.ParsedMovieInfo.Quality); - - if (!_upgradableSpecification.IsUpgradeAllowed(subject.Movie.QualityProfile, - remoteMovie.ParsedMovieInfo.Quality, - remoteMovie.CustomFormats, - subject.ParsedMovieInfo.Quality, - subject.CustomFormats)) - { - return Decision.Reject("Another release is queued and the Quality profile does not allow upgrades"); + case UpgradeableRejectReason.UpgradesNotAllowed: + return Decision.Reject("Release in queue and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); } if (_upgradableSpecification.IsRevisionUpgrade(remoteMovie.ParsedMovieInfo.Quality, subject.ParsedMovieInfo.Quality)) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index 93444ed847..48b0709723 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -107,6 +107,9 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se case UpgradeableRejectReason.MinCustomFormatScore: return Decision.Reject("{0} grab event in history has Custom Format score within Custom Format score increment: {1}", rejectionSubject, qualityProfile.MinUpgradeFormatScore); + + case UpgradeableRejectReason.UpgradesNotAllowed: + return Decision.Reject("{0} grab event in history and Quality Profile '{1}' does not allow upgrades", rejectionSubject, qualityProfile.Name); } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs index 157848517a..5fc5152f15 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradableSpecification.cs @@ -57,6 +57,13 @@ public UpgradeableRejectReason IsUpgradable(QualityProfile qualityProfile, Quali return UpgradeableRejectReason.None; } + if (!qualityProfile.UpgradeAllowed) + { + _logger.Debug("Quality profile '{0}' does not allow upgrading. Skipping.", qualityProfile.Name); + + return UpgradeableRejectReason.UpgradesNotAllowed; + } + // Reject unless the user does not prefer propers/repacks and it's a revision downgrade. if (downloadPropersAndRepacks != ProperDownloadTypes.DoNotPrefer && qualityRevisionCompare < 0) @@ -86,7 +93,7 @@ public UpgradeableRejectReason IsUpgradable(QualityProfile qualityProfile, Quali return UpgradeableRejectReason.CustomFormatScore; } - if (qualityProfile.UpgradeAllowed && currentFormatScore >= qualityProfile.CutoffFormatScore) + if (currentFormatScore >= qualityProfile.CutoffFormatScore) { _logger.Debug("Existing item meets cut-off for custom formats, skipping. Existing: [{0}] ({1}). Cutoff score: {2}", currentCustomFormats.ConcatToString(), diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs index f44249d341..ac864b0b39 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs @@ -83,6 +83,9 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se case UpgradeableRejectReason.MinCustomFormatScore: return Decision.Reject("Existing file on disk has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); + + case UpgradeableRejectReason.UpgradesNotAllowed: + return Decision.Reject("Existing file on disk and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); } return Decision.Accept(); diff --git a/src/NzbDrone.Core/DecisionEngine/UpgradeableRejectReason.cs b/src/NzbDrone.Core/DecisionEngine/UpgradeableRejectReason.cs index 2b1b1cfe97..ccf696d82f 100644 --- a/src/NzbDrone.Core/DecisionEngine/UpgradeableRejectReason.cs +++ b/src/NzbDrone.Core/DecisionEngine/UpgradeableRejectReason.cs @@ -8,6 +8,7 @@ public enum UpgradeableRejectReason QualityCutoff, CustomFormatScore, CustomFormatCutoff, - MinCustomFormatScore + MinCustomFormatScore, + UpgradesNotAllowed } } From 6b4259757c519c4c18a4efa574f8443e78006d08 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 20 Dec 2024 20:22:14 +0200 Subject: [PATCH 146/579] Add test for do not prefer repacks/propers --- .../UpgradeSpecificationFixture.cs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs index f9de729b0b..6b8b9beee3 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/UpgradeSpecificationFixture.cs @@ -107,6 +107,25 @@ public void should_return_true_if_proper_and_download_propers_is_do_not_download .Should().Be(UpgradeableRejectReason.None); } + [Test] + public void should_return_false_if_proper_and_autoDownloadPropers_is_do_not_prefer() + { + GivenAutoDownloadPropers(ProperDownloadTypes.DoNotPrefer); + + var profile = new QualityProfile + { + Items = Qualities.QualityFixture.GetDefaultQualities(), + }; + + Subject.IsUpgradable( + profile, + new QualityModel(Quality.DVD, new Revision(version: 1)), + new List(), + new QualityModel(Quality.DVD, new Revision(version: 2)), + new List()) + .Should().Be(UpgradeableRejectReason.UpgradesNotAllowed); + } + [Test] public void should_return_false_if_release_and_existing_file_are_the_same() { From 88d9c08f1a6d89de9ef3ab94fcef5c6592c2ffd7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 21 Dec 2024 11:15:14 +0200 Subject: [PATCH 147/579] Bump MailKit to 4.8.0 and Microsoft.Data.SqlClient to 2.1.7 Closes #10790 --- src/NzbDrone.Core/Radarr.Core.csproj | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index fe9167364f..945e84e321 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -6,14 +6,15 @@ - + + + - From e5419f6f06fbc59f2064669122a6465fe3a0cf50 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 21 Dec 2024 11:20:28 +0200 Subject: [PATCH 148/579] Bump System.Memory Closes #10791 --- src/NzbDrone.Core/Radarr.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 945e84e321..8590c401e6 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -13,7 +13,7 @@ - + From 0a0da42543fa77e872eea7ed432f7f7e51ad7d16 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 22 Dec 2024 13:23:52 +0200 Subject: [PATCH 149/579] Bump version to 5.17.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e065c33f0c..68fe72aa2f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.17.0' + majorVersion: '5.17.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From d34d23a052ee11c525edbda4a582e711e5221446 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 21 Dec 2024 15:12:20 -0800 Subject: [PATCH 150/579] Fixed: Movies updated during Import List Sync not reflected in the UI (cherry picked from commit 1c30ecd66dd0fd1dafaf9ab0e41a11a54eaac132) Closes #10794 --- .../Movies/Events/MoviesBulkEditedEvent.cs | 15 +++++++++++++++ src/NzbDrone.Core/Movies/MovieService.cs | 3 +++ src/Radarr.Api.V3/Movies/MovieController.cs | 10 ++++++++++ 3 files changed, 28 insertions(+) create mode 100644 src/NzbDrone.Core/Movies/Events/MoviesBulkEditedEvent.cs diff --git a/src/NzbDrone.Core/Movies/Events/MoviesBulkEditedEvent.cs b/src/NzbDrone.Core/Movies/Events/MoviesBulkEditedEvent.cs new file mode 100644 index 0000000000..3100d2a4ba --- /dev/null +++ b/src/NzbDrone.Core/Movies/Events/MoviesBulkEditedEvent.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using NzbDrone.Common.Messaging; + +namespace NzbDrone.Core.Movies.Events +{ + public class MoviesBulkEditedEvent : IEvent + { + public IReadOnlyCollection Movies { get; private set; } + + public MoviesBulkEditedEvent(IReadOnlyCollection movies) + { + Movies = movies; + } + } +} diff --git a/src/NzbDrone.Core/Movies/MovieService.cs b/src/NzbDrone.Core/Movies/MovieService.cs index c2df5bed79..e5248df2b7 100644 --- a/src/NzbDrone.Core/Movies/MovieService.cs +++ b/src/NzbDrone.Core/Movies/MovieService.cs @@ -279,6 +279,7 @@ public List UpdateMovie(List movies, bool useExistingRelativeFolde _movieRepository.UpdateMany(movies); _logger.Debug("{0} movies updated", movies.Count); + _eventAggregator.PublishEvent(new MoviesBulkEditedEvent(movies)); return movies; } @@ -331,6 +332,8 @@ public bool UpdateTags(Movie movie) return true; } + _logger.Debug("Tags not updated for '{0}'", movie.Title); + return false; } diff --git a/src/Radarr.Api.V3/Movies/MovieController.cs b/src/Radarr.Api.V3/Movies/MovieController.cs index 4392185476..33c35988f7 100644 --- a/src/Radarr.Api.V3/Movies/MovieController.cs +++ b/src/Radarr.Api.V3/Movies/MovieController.cs @@ -39,6 +39,7 @@ public class MovieController : RestControllerWithSignalR, IHandle, IHandle, IHandle, + IHandle, IHandle { private readonly IMovieService _moviesService; @@ -370,6 +371,15 @@ public void Handle(MovieRenamedEvent message) BroadcastResourceChange(ModelAction.Updated, MapToResource(message.Movie)); } + [NonAction] + public void Handle(MoviesBulkEditedEvent message) + { + foreach (var movie in message.Movies) + { + BroadcastResourceChange(ModelAction.Updated, MapToResource(movie)); + } + } + [NonAction] public void Handle(MediaCoversUpdatedEvent message) { From af60cca9ae47c9d4d47f327fa2e2d32cbde50691 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 23 Dec 2024 10:33:08 +0200 Subject: [PATCH 151/579] Fixed: Advanced settings for Metadata consumers --- .../Settings/Metadata/Metadata/EditMetadataModal.tsx | 11 +++++++++-- frontend/src/Settings/Metadata/Metadata/Metadata.tsx | 1 - 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx b/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx index 6dd30ca785..9731a39ab9 100644 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModal.tsx @@ -1,5 +1,6 @@ import React, { useCallback } from 'react'; -import { useDispatch } from 'react-redux'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; import Modal from 'Components/Modal/Modal'; import { sizes } from 'Helpers/Props'; import { clearPendingChanges } from 'Store/Actions/baseActions'; @@ -7,7 +8,8 @@ import EditMetadataModalContent, { EditMetadataModalContentProps, } from './EditMetadataModalContent'; -interface EditMetadataModalProps extends EditMetadataModalContentProps { +interface EditMetadataModalProps + extends Omit { isOpen: boolean; } @@ -18,6 +20,10 @@ function EditMetadataModal({ }: EditMetadataModalProps) { const dispatch = useDispatch(); + const advancedSettings = useSelector( + (state: AppState) => state.settings.advancedSettings + ); + const handleModalClose = useCallback(() => { dispatch(clearPendingChanges({ section: 'metadata' })); onModalClose(); @@ -27,6 +33,7 @@ function EditMetadataModal({ diff --git a/frontend/src/Settings/Metadata/Metadata/Metadata.tsx b/frontend/src/Settings/Metadata/Metadata/Metadata.tsx index 52797218df..bb988d0d9e 100644 --- a/frontend/src/Settings/Metadata/Metadata/Metadata.tsx +++ b/frontend/src/Settings/Metadata/Metadata/Metadata.tsx @@ -95,7 +95,6 @@ function Metadata({ id, name, enable, fields }: MetadataProps) { ) : null} Date: Thu, 26 Dec 2024 12:37:45 -0800 Subject: [PATCH 152/579] Don't send session information to Sentry (cherry picked from commit fae24e98fb9230c2f3701caef457332952c6723f) --- src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs index d02e1d3032..fd2fef61f0 100644 --- a/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs +++ b/src/NzbDrone.Common/Instrumentation/Sentry/SentryTarget.cs @@ -119,7 +119,7 @@ public SentryTarget(string dsn, IAppFolderInfo appFolderInfo) o.Environment = BuildInfo.Branch; // Crash free run statistics (sends a ping for healthy and for crashes sessions) - o.AutoSessionTracking = true; + o.AutoSessionTracking = false; // Caches files in the event device is offline // Sentry creates a 'sentry' sub directory, no need to concat here From f0a9e76cfc753378d041e2882a2c9ae92f89f0d5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 30 Dec 2024 00:58:56 +0200 Subject: [PATCH 153/579] Bump version to 5.17.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 68fe72aa2f..c26ecb5020 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.17.1' + majorVersion: '5.17.2' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From a64d931904cd6c465d5e612d8837c9933c7c3e25 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 28 Dec 2024 15:32:04 +0200 Subject: [PATCH 154/579] Suggest adding IP to RPC whitelist for on failed Transmission auth (cherry picked from commit f05e552e8e6dc02cd26444073ab9a678dcb36492) --- .../Clients/Transmission/TransmissionProxy.cs | 35 ++++++++++--------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs index 2de2b26e74..ce5f720249 100644 --- a/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs +++ b/src/NzbDrone.Core/Download/Clients/Transmission/TransmissionProxy.cs @@ -7,6 +7,7 @@ using Newtonsoft.Json.Linq; using NLog; using NzbDrone.Common.Cache; +using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; @@ -261,7 +262,7 @@ private HttpRequestBuilder BuildRequest(TransmissionSettings settings) private void AuthenticateClient(HttpRequestBuilder requestBuilder, TransmissionSettings settings, bool reauthenticate = false) { - var authKey = string.Format("{0}:{1}", requestBuilder.BaseUrl, settings.Password); + var authKey = $"{requestBuilder.BaseUrl}:{settings.Password}"; var sessionId = _authSessionIdCache.Find(authKey); @@ -273,24 +274,26 @@ private void AuthenticateClient(HttpRequestBuilder requestBuilder, TransmissionS authLoginRequest.SuppressHttpError = true; var response = _httpClient.Execute(authLoginRequest); - if (response.StatusCode == HttpStatusCode.MovedPermanently) - { - var url = response.Headers.GetSingleValue("Location"); - throw new DownloadClientException("Remote site redirected to " + url); - } - else if (response.StatusCode == HttpStatusCode.Conflict) + switch (response.StatusCode) { - sessionId = response.Headers.GetSingleValue("X-Transmission-Session-Id"); + case HttpStatusCode.MovedPermanently: + var url = response.Headers.GetSingleValue("Location"); - if (sessionId == null) - { - throw new DownloadClientException("Remote host did not return a Session Id."); - } - } - else - { - throw new DownloadClientAuthenticationException("Failed to authenticate with Transmission."); + throw new DownloadClientException("Remote site redirected to " + url); + case HttpStatusCode.Forbidden: + throw new DownloadClientException($"Failed to authenticate with Transmission. It may be necessary to add {BuildInfo.AppName}'s IP address to RPC whitelist."); + case HttpStatusCode.Conflict: + sessionId = response.Headers.GetSingleValue("X-Transmission-Session-Id"); + + if (sessionId == null) + { + throw new DownloadClientException("Remote host did not return a Session Id."); + } + + break; + default: + throw new DownloadClientAuthenticationException("Failed to authenticate with Transmission."); } _logger.Debug("Transmission authentication succeeded."); From 410870d21ec3442502f794966e2e68ec02e6f575 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 30 Dec 2024 04:09:48 +0200 Subject: [PATCH 155/579] Check if backup folder is writable on backup (cherry picked from commit 8aad79fd3e14eb885724a5e5790803c289be2f25) Closes #10806 --- src/NzbDrone.Common/ArchiveService.cs | 19 ++++++++++--------- src/NzbDrone.Core/Backup/BackupService.cs | 11 +++++++++-- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Common/ArchiveService.cs b/src/NzbDrone.Common/ArchiveService.cs index 800d240ab8..d420bbbc0a 100644 --- a/src/NzbDrone.Common/ArchiveService.cs +++ b/src/NzbDrone.Common/ArchiveService.cs @@ -42,17 +42,18 @@ public void Extract(string compressedFile, string destination) public void CreateZip(string path, IEnumerable files) { - using (var zipFile = ZipFile.Create(path)) + _logger.Debug("Creating archive {0}", path); + + using var zipFile = ZipFile.Create(path); + + zipFile.BeginUpdate(); + + foreach (var file in files) { - zipFile.BeginUpdate(); - - foreach (var file in files) - { - zipFile.Add(file, Path.GetFileName(file)); - } - - zipFile.CommitUpdate(); + zipFile.Add(file, Path.GetFileName(file)); } + + zipFile.CommitUpdate(); } private void ExtractZip(string compressedFile, string destination) diff --git a/src/NzbDrone.Core/Backup/BackupService.cs b/src/NzbDrone.Core/Backup/BackupService.cs index 7a94ddab95..e6639e6f54 100644 --- a/src/NzbDrone.Core/Backup/BackupService.cs +++ b/src/NzbDrone.Core/Backup/BackupService.cs @@ -66,12 +66,19 @@ public void Backup(BackupType backupType) { _logger.ProgressInfo("Starting Backup"); + var backupFolder = GetBackupFolder(backupType); + _diskProvider.EnsureFolder(_backupTempFolder); - _diskProvider.EnsureFolder(GetBackupFolder(backupType)); + _diskProvider.EnsureFolder(backupFolder); + + if (!_diskProvider.FolderWritable(backupFolder)) + { + throw new UnauthorizedAccessException($"Backup folder {backupFolder} is not writable"); + } var dateNow = DateTime.Now; var backupFilename = $"radarr_backup_v{BuildInfo.Version}_{dateNow:yyyy.MM.dd_HH.mm.ss}.zip"; - var backupPath = Path.Combine(GetBackupFolder(backupType), backupFilename); + var backupPath = Path.Combine(backupFolder, backupFilename); Cleanup(); From 0e25b2708c2d73d8830df5cebba94fca3e5e8144 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 31 Dec 2024 18:19:34 +0200 Subject: [PATCH 156/579] Fixed: Sending Manual Interaction Required notifications to Discord for unknown movies --- src/NzbDrone.Core/Notifications/Discord/Discord.cs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index 85b874fdb1..a3ac651ce6 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -646,13 +646,19 @@ private string GetTitle(Movie movie) return title.Length > 256 ? $"{title.AsSpan(0, 253)}..." : title; } - private IEnumerable GetTagLabels(Movie movie) + private List GetTagLabels(Movie movie) { - return movie.Tags? - .Select(t => _tagRepository.Find(t)?.Label) + if (movie == null) + { + return null; + } + + return _tagRepository.GetTags(movie.Tags) + .Select(t => t.Label) .Where(l => l.IsNotNullOrWhiteSpace()) .OrderBy(l => l) - .Take(5); + .Take(5) + .ToList(); } } } From 25f66a3029b6b7e590829d4b3f0385ee40b62c28 Mon Sep 17 00:00:00 2001 From: Siddhant Naik Date: Tue, 31 Dec 2024 14:32:41 +0530 Subject: [PATCH 157/579] New: Add Marathi language --- src/NzbDrone.Core.Test/Languages/LanguageFixture.cs | 6 ++++-- .../ParserTests/IsoLanguagesFixture.cs | 9 +++++++++ .../ParserTests/LanguageParserFixture.cs | 8 ++++++++ src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs | 4 +++- src/NzbDrone.Core/Languages/Language.cs | 2 ++ src/NzbDrone.Core/Parser/IsoLanguages.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs index fae2caa6d6..51248dc675 100644 --- a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs +++ b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs @@ -63,7 +63,8 @@ public class LanguageFixture : CoreTest new object[] { 48, Language.Malayalam }, new object[] { 49, Language.Kannada }, new object[] { 50, Language.Albanian }, - new object[] { 51, Language.Afrikaans } + new object[] { 51, Language.Afrikaans }, + new object[] { 52, Language.Marathi } }; public static object[] ToIntCases = @@ -121,7 +122,8 @@ public class LanguageFixture : CoreTest new object[] { Language.Malayalam, 48 }, new object[] { Language.Kannada, 49 }, new object[] { Language.Albanian, 50 }, - new object[] { Language.Afrikaans, 51 } + new object[] { Language.Afrikaans, 51 }, + new object[] { Language.Marathi, 52 } }; [Test] diff --git a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs index 63d8fa4234..a9f37710fc 100644 --- a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs @@ -62,5 +62,14 @@ public void should_return_afrikaans(string isoCode) var result = IsoLanguages.Find(isoCode); result.Language.Should().Be(Language.Afrikaans); } + + [TestCase("mr")] + [TestCase("mar")] + [TestCase("mr-IN")] + public void should_return_marathi(string isoCode) + { + var result = IsoLanguages.Find(isoCode); + result.Language.Should().Be(Language.Marathi); + } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 145099911b..490abd7cc0 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -460,6 +460,14 @@ public void should_parse_language_afrikaans(string postTitle) result.Should().Contain(Language.Afrikaans); } + [TestCase("Movie Title 2015 Marathi 1080p WebRip x264 AC3 5.1 ESubs [TMB]")] + [TestCase("Movie.Title.(2018).720p.CensorRip.Marathi.x264.AAC.-.LHDm@Telly")] + public void should_parse_language_marathi(string postTitle) + { + var result = LanguageParser.ParseLanguages(postTitle); + result.Should().Contain(Language.Marathi); + } + [TestCase("Movie.Title.en.sub")] [TestCase("Movie Title.eng.sub")] [TestCase("Movie.Title.eng.forced.sub")] diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs index f562feb02d..1109fb6bce 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs @@ -65,6 +65,8 @@ public enum TMDbLanguageCodes [FieldOption(Hint = "Albanian")] sq, [FieldOption(Hint = "Afrikaans")] - af + af, + [FieldOption(Hint = "Marathi")] + mr } } diff --git a/src/NzbDrone.Core/Languages/Language.cs b/src/NzbDrone.Core/Languages/Language.cs index 94b9e4e681..e1bb5f2f04 100644 --- a/src/NzbDrone.Core/Languages/Language.cs +++ b/src/NzbDrone.Core/Languages/Language.cs @@ -122,6 +122,7 @@ public override bool Equals(object obj) public static Language Kannada => new Language(49, "Kannada"); public static Language Albanian => new Language(50, "Albanian"); public static Language Afrikaans => new Language(51, "Afrikaans"); + public static Language Marathi => new Language(52, "Marathi"); public static Language Any => new Language(-1, "Any"); public static Language Original => new Language(-2, "Original"); @@ -183,6 +184,7 @@ public static List All Kannada, Albanian, Afrikaans, + Marathi, Any, Original }; diff --git a/src/NzbDrone.Core/Parser/IsoLanguages.cs b/src/NzbDrone.Core/Parser/IsoLanguages.cs index af59c3b951..54dbcc5e68 100644 --- a/src/NzbDrone.Core/Parser/IsoLanguages.cs +++ b/src/NzbDrone.Core/Parser/IsoLanguages.cs @@ -61,6 +61,7 @@ public static class IsoLanguages new IsoLanguage("kn", "", "kan", "Kannada", Language.Kannada), new IsoLanguage("sq", "", "sqi", "Albanian", Language.Albanian), new IsoLanguage("af", "", "afr", "Afrikaans", Language.Afrikaans), + new IsoLanguage("mr", "", "mar", "Marathi", Language.Marathi), }; private static readonly Dictionary AlternateIsoCodeMappings = new () diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index dea8b80dce..9e4460e036 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -239,6 +239,11 @@ public static List ParseLanguages(string title) languages.Add(Language.Afrikaans); } + if (lowerTitle.Contains("marathi")) + { + languages.Add(Language.Marathi); + } + // Case sensitive var caseSensitiveMatches = CaseSensitiveLanguageRegex.Matches(title); From 2f26974ecc9ea5d01b60666a4d1b57963f240cf1 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 2 Jan 2025 19:55:12 +0200 Subject: [PATCH 158/579] New: Add Tagalog language --- src/NzbDrone.Core.Test/Languages/LanguageFixture.cs | 6 ++++-- .../ParserTests/IsoLanguagesFixture.cs | 9 +++++++++ .../ParserTests/LanguageParserFixture.cs | 8 ++++++++ src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs | 4 +++- src/NzbDrone.Core/Languages/Language.cs | 2 ++ src/NzbDrone.Core/Parser/IsoLanguages.cs | 1 + src/NzbDrone.Core/Parser/LanguageParser.cs | 5 +++++ 7 files changed, 32 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs index 51248dc675..19fdae72e9 100644 --- a/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs +++ b/src/NzbDrone.Core.Test/Languages/LanguageFixture.cs @@ -64,7 +64,8 @@ public class LanguageFixture : CoreTest new object[] { 49, Language.Kannada }, new object[] { 50, Language.Albanian }, new object[] { 51, Language.Afrikaans }, - new object[] { 52, Language.Marathi } + new object[] { 52, Language.Marathi }, + new object[] { 53, Language.Tagalog }, }; public static object[] ToIntCases = @@ -123,7 +124,8 @@ public class LanguageFixture : CoreTest new object[] { Language.Kannada, 49 }, new object[] { Language.Albanian, 50 }, new object[] { Language.Afrikaans, 51 }, - new object[] { Language.Marathi, 52 } + new object[] { Language.Marathi, 52 }, + new object[] { Language.Tagalog, 53 }, }; [Test] diff --git a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs index a9f37710fc..901bfe8743 100644 --- a/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/IsoLanguagesFixture.cs @@ -71,5 +71,14 @@ public void should_return_marathi(string isoCode) var result = IsoLanguages.Find(isoCode); result.Language.Should().Be(Language.Marathi); } + + [TestCase("tl")] + [TestCase("tgl")] + [TestCase("tl-PH")] + public void should_return_tagalog(string isoCode) + { + var result = IsoLanguages.Find(isoCode); + result.Language.Should().Be(Language.Tagalog); + } } } diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 490abd7cc0..ecbdfef12f 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -468,6 +468,14 @@ public void should_parse_language_marathi(string postTitle) result.Should().Contain(Language.Marathi); } + [TestCase("Movie Title 2024 1080p Tagalog WEB-DL HEVC x265 BONE")] + [TestCase("Movie.Title.2022.720p.Tagalog.WEB-DL.AAC.x264-Mkvking")] + public void should_parse_language_tagalog(string postTitle) + { + var result = LanguageParser.ParseLanguages(postTitle); + result.Should().Contain(Language.Tagalog); + } + [TestCase("Movie.Title.en.sub")] [TestCase("Movie Title.eng.sub")] [TestCase("Movie.Title.eng.forced.sub")] diff --git a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs index 1109fb6bce..b26e5ae634 100644 --- a/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs +++ b/src/NzbDrone.Core/ImportLists/TMDb/TMDbLanguageCodes.cs @@ -67,6 +67,8 @@ public enum TMDbLanguageCodes [FieldOption(Hint = "Afrikaans")] af, [FieldOption(Hint = "Marathi")] - mr + mr, + [FieldOption(Hint = "Tagalog")] + tl, } } diff --git a/src/NzbDrone.Core/Languages/Language.cs b/src/NzbDrone.Core/Languages/Language.cs index e1bb5f2f04..1c04dc367d 100644 --- a/src/NzbDrone.Core/Languages/Language.cs +++ b/src/NzbDrone.Core/Languages/Language.cs @@ -123,6 +123,7 @@ public override bool Equals(object obj) public static Language Albanian => new Language(50, "Albanian"); public static Language Afrikaans => new Language(51, "Afrikaans"); public static Language Marathi => new Language(52, "Marathi"); + public static Language Tagalog => new Language(53, "Tagalog"); public static Language Any => new Language(-1, "Any"); public static Language Original => new Language(-2, "Original"); @@ -185,6 +186,7 @@ public static List All Albanian, Afrikaans, Marathi, + Tagalog, Any, Original }; diff --git a/src/NzbDrone.Core/Parser/IsoLanguages.cs b/src/NzbDrone.Core/Parser/IsoLanguages.cs index 54dbcc5e68..cd1af26e31 100644 --- a/src/NzbDrone.Core/Parser/IsoLanguages.cs +++ b/src/NzbDrone.Core/Parser/IsoLanguages.cs @@ -62,6 +62,7 @@ public static class IsoLanguages new IsoLanguage("sq", "", "sqi", "Albanian", Language.Albanian), new IsoLanguage("af", "", "afr", "Afrikaans", Language.Afrikaans), new IsoLanguage("mr", "", "mar", "Marathi", Language.Marathi), + new IsoLanguage("tl", "", "tgl", "Tagalog", Language.Tagalog), }; private static readonly Dictionary AlternateIsoCodeMappings = new () diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 9e4460e036..60cbda36db 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -244,6 +244,11 @@ public static List ParseLanguages(string title) languages.Add(Language.Marathi); } + if (lowerTitle.Contains("tagalog")) + { + languages.Add(Language.Tagalog); + } + // Case sensitive var caseSensitiveMatches = CaseSensitiveLanguageRegex.Matches(title); From 9876ed64e24bde902d65f477a6fa86592ff057f4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 2 Jan 2025 17:41:16 +0000 Subject: [PATCH 159/579] Multiple Translations updated by Weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ignore-downstream Co-authored-by: 1 <1228553526@qq.com> Co-authored-by: Alexander Balya Co-authored-by: Ano10 Co-authored-by: Fixer Co-authored-by: GkhnGRBZ Co-authored-by: Matti Meikäläinen Co-authored-by: Oskari Lavinto Co-authored-by: Tommy Au Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: marapavelka Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/cs.json | 80 +- src/NzbDrone.Core/Localization/Core/fi.json | 858 ++++++++++-------- src/NzbDrone.Core/Localization/Core/fr.json | 30 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 5 +- src/NzbDrone.Core/Localization/Core/ru.json | 5 +- src/NzbDrone.Core/Localization/Core/tr.json | 170 ++-- .../Localization/Core/zh_TW.json | 38 +- 8 files changed, 657 insertions(+), 531 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 50fb0b2ce5..4efa5cf10c 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -2,20 +2,20 @@ "EditDelayProfile": "Upravit profil zpoždění", "AcceptConfirmationModal": "Přijměte potvrzovací modální okno", "Automatic": "Automatický", - "CertificateValidation": "Ověření certifikátu", + "CertificateValidation": "Ověřování certifikátu", "CertificateValidationHelpText": "Změňte přísnost ověřování certifikátů HTTPS. Neměňte, pokud nerozumíte rizikům.", "Cast": "Obsazení", "CheckDownloadClientForDetails": "zkontrolujte klienta pro stahování pro více informací", "CheckForFinishedDownloadsInterval": "Zkontrolujte interval dokončených stahování", "AddRemotePathMapping": "Přidat mapování vzdálených cest", - "Date": "datum", + "Date": "Datum", "About": "O aplikaci", "AddIndexer": "Přidat indexer", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Filmy odstraněné z disku jsou automaticky sledovány v {appName}u", "AvailabilityDelay": "Zpoždění dostupnosti", "Certification": "Osvědčení", "CleanLibraryLevel": "Čistá úroveň knihovny", - "Clear": "Vyčistit", + "Clear": "Vymazat", "CreateEmptyMovieFolders": "Vytvořte prázdné složky s filmy", "MovieIsRecommend": "Film se doporučuje na základě nedávného přidání", "NegateHelpText": "Pokud je zaškrtnuto, vlastní formát se nepoužije, pokud se tato podmínka {0} shoduje.", @@ -31,7 +31,7 @@ "RecyclingBinCleanupHelpTextWarning": "Soubory v koši starší než vybraný počet dní budou automaticky vyčištěny", "Backup": "Záloha", "Username": "Uživatelské jméno", - "BackupFolderHelpText": "Relativní cesty budou v adresáři AppData společnosti {appName}", + "BackupFolderHelpText": "Relativní cesty budou v adresáři AppData {appName}u", "Peers": "Vrstevníci", "Real": "Nemovitý", "ClickToChangeMovie": "Kliknutím změníte film", @@ -152,18 +152,18 @@ "AddDownloadClient": "Přidat klienta pro stahování", "AddRootFolder": "Přidat kořenový adresář", "Always": "Vždy", - "AnalyticsEnabledHelpText": "Odesílejte anonymní informace o použití a chybách na servery {appName}u. To zahrnuje informace o vašem prohlížeči, které stránky {appName} WebUI používáte, hlášení chyb a také verzi operačního systému a běhového prostředí. Tyto informace použijeme k upřednostnění funkcí a oprav chyb.", - "AptUpdater": "K instalaci aktualizace použijte apt", + "AnalyticsEnabledHelpText": "Odesílejte anonymní informace o použití a chybách na servery {appName}u. To zahrnuje informace o vašem prohlížeči, které stránky webového rozhraní {appName}u používáte, hlášení chyb a také verzi operačního systému a běhového prostředí. Tyto informace použijeme k určení priorit funkcí a oprav chyb.", + "AptUpdater": "K instalaci aktualizace používat apt", "AudioInfo": "Audio informace", "ICalShowAsAllDayEventsHelpText": "Události se ve vašem kalendáři zobrazí jako celodenní události", "AuthBasic": "Základní (vyskakovací okno prohlížeče)", "Authentication": "Ověřování", - "AuthenticationMethodHelpText": "Vyžadovat uživatelské jméno a heslo pro přístup k {appName}", + "AuthenticationMethodHelpText": "Vyžadovat uživatelské jméno a heslo pro přístup k {appName}u", "AuthForm": "Formuláře (přihlašovací stránka)", "AutoRedownloadFailedHelpText": "Automatické vyhledání a pokus o stažení jiného vydání", "BackupIntervalHelpText": "Interval mezi automatickými zálohami", - "BackupNow": "Ihned zálohovat", - "AutomaticSearch": "Vyhledat automaticky", + "BackupNow": "Zálohovat nyní", + "AutomaticSearch": "Automatické vyhledávání", "BuiltIn": "Vestavěný", "CalendarOptions": "Možnosti kalendáře", "CancelProcessing": "Zrušit zpracování", @@ -184,7 +184,7 @@ "Connection": "Spojení", "AddQualityProfile": "Přidat profil kvality", "CustomFormatUnknownCondition": "Neznámá podmínka vlastního formátu „{implementation}“", - "Dates": "Termíny", + "Dates": "Data", "Day": "Den", "DeleteBackup": "Odstranit zálohu", "DeleteCustomFormat": "Odstranit vlastní formát", @@ -202,7 +202,7 @@ "NoEventsFound": "Nebyly nalezeny žádné události", "NoLinks": "Žádné odkazy", "None": "Žádný", - "ApplyTags": "Použít značky", + "ApplyTags": "Použít štítky", "BackupRetentionHelpText": "Automatické zálohy starší než doba uchovávání budou automaticky vyčištěny", "Backups": "Zálohy", "AddImportListExclusion": "Přidat vyloučení seznamu", @@ -281,7 +281,7 @@ "MinutesSixty": "60 minut: {0}", "Small": "Malý", "Calendar": "Kalendář", - "CancelPendingTask": "Opravdu chcete zrušit tento nevyřízený úkol?", + "CancelPendingTask": "Opravdu chcete zrušit tento úkol čekající na vyřízení?", "Tomorrow": "Zítra", "OnGrab": "Chyť", "OnHealthIssue": "K otázce zdraví", @@ -364,11 +364,11 @@ "MovieInfoLanguageHelpTextWarning": "Vyžaduje se opětovné načtení prohlížeče", "MovieIsDownloading": "Film se stahuje", "MovieIsMonitored": "Film je sledován", - "BeforeUpdate": "Před zálohováním", + "BeforeUpdate": "Před aktualizací", "BindAddress": "Vázat adresu", - "BindAddressHelpText": "Platná IP adresa, localhost nebo '*' pro všechna rozhraní", - "BranchUpdate": "Pobočka, která se má použít k aktualizaci {appName}", - "BranchUpdateMechanism": "Větev používaná externím aktualizačním mechanismem", + "BindAddressHelpText": "Platná IP adresa, localhost nebo ‚*‘ pro všechna rozhraní", + "BranchUpdate": "Větev použitá k aktualizaci {appName}u", + "BranchUpdateMechanism": "Větev použitá externím aktualizačním mechanismem", "BypassProxyForLocalAddresses": "Obcházení proxy serveru pro místní adresy", "MovieIsUnmonitored": "Film není sledován", "Movies": "Filmy", @@ -394,7 +394,7 @@ "Overview": "Přehled", "Failed": "Selhalo", "AddMovies": "Přidat filmy", - "AddingTag": "Přidání značky", + "AddingTag": "Přidávání štítku", "AlternativeTitle": "Alternativní název", "AnalyseVideoFiles": "Analyzujte video soubory", "Age": "Stáří", @@ -471,12 +471,12 @@ "CloneIndexer": "Klonovat indexátor", "CloneProfile": "Klonovat profil", "Close": "Zavřít", - "CloseCurrentModal": "Zavřít aktuální modální", + "CloseCurrentModal": "Zavřít aktuální modální okno", "Collection": "Sbírka", "ColonReplacement": "Nahrazení dvojtečky", "Columns": "Sloupce", "CompletedDownloadHandling": "Zpracování stahování bylo dokončeno", - "ConnectionLost": "Spojení ztraceno", + "ConnectionLost": "Ztráta spojení", "Connections": "Připojení", "ConnectSettingsSummary": "Oznámení, připojení k mediálním serverům/přehrávačům a vlastní skripty", "ConsideredAvailable": "Považováno za dostupné", @@ -486,7 +486,7 @@ "CreateGroup": "Vytvořit skupinu", "Crew": "Osádka", "CurrentlyInstalled": "Aktuálně nainstalováno", - "Custom": "Zvyk", + "Custom": "Vlastní", "CustomFilters": "Vlastní filtry", "CustomFormat": "Vlastní formát", "CustomFormatHelpText": "{appName} skóre každé vydání pomocí součtu skóre pro odpovídající vlastní formáty. Pokud by nová verze zlepšila skóre ve stejné nebo lepší kvalitě, pak ji chytí {appName}.", @@ -974,26 +974,26 @@ "ShowCinemaReleaseHelpText": "Zobrazit datum vydání pod plakátem", "DeleteRemotePathMapping": "Upravit vzdálené mapování cesty", "DeleteRemotePathMappingMessageText": "Opravdu chcete toto vzdálené mapování cesty odstranit?", - "ApplyTagsHelpTextReplace": "Nahradit: Nahradit značky zadanými značkami (prázdné pole vymaže všechny značky)", + "ApplyTagsHelpTextReplace": "Nahradit: Nahradit štítky zadanými štítky (prázdné pole vymaže všechny štítky)", "DeleteConditionMessageText": "Opravdu chcete odstranit podmínku '{name}'?", "DeleteCustomFormatMessageText": "Opravdu chcete odstranit indexer „{name}“?", "DeleteDelayProfileMessageText": "Opravdu chcete smazat tento profil zpoždění?", "DeleteFormatMessageText": "Opravdu chcete smazat značku formátu {0}?", "RemoveSelectedItemQueueMessageText": "Opravdu chcete odebrat {0} položku {1} z fronty?", "RemoveSelectedItemsQueueMessageText": "Opravdu chcete odebrat {0} položku {1} z fronty?", - "ApplyTagsHelpTextAdd": "Přidat: Přidá značky k již existujícímu seznamu", - "ApplyTagsHelpTextHowToApplyIndexers": "Jak použít značky na vybrané indexery", - "ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané značky", + "ApplyTagsHelpTextAdd": "Přidat: Přidat štítky do existujícího seznamu štítků", + "ApplyTagsHelpTextHowToApplyIndexers": "Jak použít štítky na vybrané indexery", + "ApplyTagsHelpTextRemove": "Odebrat: Odebrat zadané štítky", "DeleteImportListExclusionMessageText": "Opravdu chcete toto vyloučení importního seznamu smazat?", "DeleteSelectedDownloadClients": "Odstranit klienta pro stahování", "DeleteSelectedIndexers": "Odstranit indexer", "ResetAPIKeyMessageText": "Opravdu chcete resetovat klíč API?", "AddConditionImplementation": "Přidat podmínku - {implementationName}", "AddConnection": "Přidat spojení", - "AddConnectionImplementation": "Přidat spojení - {implementationName}", - "AddDownloadClientImplementation": "Přidat klienta pro stahování - {implementationName}", + "AddConnectionImplementation": "Přidat spojení – {implementationName}", + "AddDownloadClientImplementation": "Přidat klienta pro stahování – {implementationName}", "AddImportList": "Přidat importované položky", - "AddIndexerImplementation": "Přidat indexer - {implementationName}", + "AddIndexerImplementation": "Přidat indexer – {implementationName}", "AddAutoTag": "Přidat automatickou značku", "AddCondition": "Přidat podmínku", "AllTitles": "Všechny názvy", @@ -1003,15 +1003,15 @@ "BypassDelayIfHighestQuality": "Obejít v případě nejvyšší kvality", "BypassDelayIfHighestQualityHelpText": "Obejít zpoždění, když má vydání nejvyšší povolenou kvalitu v profilu kvality s preferovaným protokolem", "ApplyChanges": "Použít změny", - "ApplicationUrlHelpText": "Externí adresa URL této aplikace včetně http(s)://, portu a základní adresy URL", + "ApplicationUrlHelpText": "Externí adresa URL této aplikace včetně http(s)://, portu a základu URL", "AutoTagging": "Automatické označování", "AutomaticAdd": "Přidat automaticky", "ApplyTagsHelpTextHowToApplyDownloadClients": "Jak použít značky na vybrané klienty pro stahování", "ApplyTagsHelpTextHowToApplyImportLists": "Jak použít značky na vybrané seznamy k importu", "AutomaticUpdatesDisabledDocker": "Automatické aktualizace nejsou při použití aktualizačního mechanismu Docker přímo podporovány. Obraz kontejneru je nutné aktualizovat mimo {appName} nebo použít skript", "BypassDelayIfAboveCustomFormatScore": "Obejít, pokud je vyšší než skóre vlastního formátu", - "AuthenticationRequired": "Vyžadované ověření", - "AuthenticationRequiredHelpText": "Změnit, pro které požadavky je vyžadováno ověření. Pokud nerozumíte rizikům, neměňte je.", + "AuthenticationRequired": "Vyžadováno ověření", + "AuthenticationRequiredHelpText": "Změnit, pro které požadavky je vyžadováno ověření. Neměňte, pokud nerozumíte rizikům.", "BypassDelayIfAboveCustomFormatScoreHelpText": "Povolit obcházení, pokud má vydání vyšší skóre, než je nakonfigurované minimální skóre vlastního formátu", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimální skóre vlastního formátu", "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Minimální skóre vlastního formátu požadované pro obejití zpoždění preferovaného protokolu", @@ -1037,8 +1037,8 @@ "ClearBlocklistMessageText": "Určitě chcete smazat všechny položky z blocklistu?", "CollectionShowPostersHelpText": "Zobrazit plakáty položek v kolekci", "ConnectionLostReconnect": "{appName} se pokusí připojit automaticky, nebo můžete kliknout na tlačítko znovunačtení níže.", - "ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude třebaho znovu načíst.", - "CountDownloadClientsSelected": "{count} vybraných klientů ke stahování", + "ConnectionLostToBackend": "{appName} ztratil spojení s backendem a pro obnovení funkčnosti bude potřeba ho znovu načíst.", + "CountDownloadClientsSelected": "{count} vybraných klientů pro stahování", "DefaultNameCopiedProfile": "{name} - Kopírovat", "DefaultNameCopiedSpecification": "{name} - Kopírovat", "DelayingDownloadUntil": "Odložení stahování do {date} v {time}", @@ -1097,10 +1097,10 @@ "EditSelectedMovies": "Upravit vybrané filmy", "EditSelectedDownloadClients": "Upravit vybrané klienty pro stahování", "AuthenticationMethod": "Metoda ověřování", - "AuthenticationMethodHelpTextWarning": "Prosím vyberte platnou metodu ověřování", - "AuthenticationRequiredPasswordHelpTextWarning": "Vložte nové heslo", - "AuthenticationRequiredUsernameHelpTextWarning": "Vložte nové uživatelské jméno", - "AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName} povolení ověření. Ověřování z místních adres můžete volitelně zakázat.", + "AuthenticationMethodHelpTextWarning": "Vyberte platnou metodu ověřování", + "AuthenticationRequiredPasswordHelpTextWarning": "Zadejte nové heslo", + "AuthenticationRequiredUsernameHelpTextWarning": "Zadejte nové uživatelské jméno", + "AuthenticationRequiredWarning": "Aby se zabránilo vzdálenému přístupu bez ověření, vyžaduje nyní {appName}, aby bylo povoleno ověřování. Volitelně můžete zakázat ověřování z místních adres.", "DeleteCondition": "Odstranit podmínku", "EnableProfile": "Povolit profil", "AutoRedownloadFailedFromInteractiveSearchHelpText": "Automaticky vyhledat a pokusit se o stažení jiného vydání, pokud bylo neúspěšné vydání zachyceno z interaktivního vyhledávání", @@ -1147,7 +1147,7 @@ "ReleaseProfiles": "profil vydání", "MovieSearchResultsLoadError": "Nelze načíst výsledky pro toto hledání filmu. Zkuste to později", "NotificationsSimplepushSettingsEvent": "Událost", - "CustomFilter": "Vlastní filtry", + "CustomFilter": "Vlastní filtr", "DelayMinutes": "{delay} Minuty", "DelayProfileMovieTagsHelpText": "Platí pro filmy s alespoň jednou shodnou značkou", "EditReleaseProfile": "Přidat profil vydání", @@ -1175,7 +1175,7 @@ "DeleteMovieFoldersHelpText": "Odstraňte složku filmu a její obsah", "DeleteSelectedMovies": "Odstranit vybrané filmové soubory", "BlocklistAndSearch": "Seznam blokovaných a vyhledávání", - "BlackholeFolderHelpText": "Složka do které {appName} uloží {extension} soubor", + "BlackholeFolderHelpText": "Složka, do které {appName} uloží soubor {extension}", "BlackholeWatchFolder": "Složka sledování", "BlackholeWatchFolderHelpText": "Složka ze které {appName} má importovat stažené soubory", "BlocklistMultipleOnlyHint": "Blokovat a nehledat náhradu", @@ -1203,5 +1203,7 @@ "DefaultNotFoundMessage": "Asi jsi se ztratil, není tu nic k vidění.", "Completed": "Dokončit", "Delay": "Zpoždění", - "DownloadClientUnavailable": "Stahovací klient není k dispozici" + "DownloadClientUnavailable": "Stahovací klient není k dispozici", + "NotificationsDiscordSettingsAuthor": "Autor", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Pokud je torrent blokován pomocí hash, nemusí být u některých indexerů správně odmítnut během RSS/vyhledávání. Povolení této funkce umožní jeho odmítnutí po zachycení torrentu, ale před jeho odesláním klientovi." } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 76a358940d..ade44ac50b 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -5,24 +5,24 @@ "None": "Ei mitään", "QualitySettings": "Laatuasetukset", "About": "Tietoja", - "ImportNotForDownloads": "Älä käytä tätä latausten tuontiin lataustyökalulta. Tämä on vain olemassa oleville, järjestetyille kirjastoille, ei lajittelemattomille tiedostoille.", + "ImportNotForDownloads": "Älä käytä tätä latausten tuontiin latauspalvelulta. Tämä on tarkoitettu vain olemassa olevien ja järjestettyjen kirjastojen, eikä lajittelemattomien tiedostojen tuontiin.", "DeleteTag": "Poista tunniste", "IndexerLongTermStatusCheckAllClientMessage": "Mikään tietolähde ei ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi.", - "MaximumSizeHelpText": "Kaapattavien julkaisujen enimmäiskoko megatavuina. Arvo \"0\" (nolla) poistaa rajoituksen.", + "MaximumSizeHelpText": "Kaapattavien julkaisujen enimmäiskoko megatavuina. Poista rajoitus asettamalla arvoksi 0.", "Tomorrow": "Huomenna", "MovieFolderFormat": "Elokuvakansioiden kaava", - "SupportedDownloadClients": "Monet torrent- ja Usenet-lataajat ovat tuettuja.", + "SupportedDownloadClients": "{appName} tukee monia torrent- ja Usenet-lataajia.", "Timeleft": "Aikaa jäljellä", - "UpdateCheckStartupNotWritableMessage": "Päivitystä ei voida asentaa, koska käyttäjällä \"{userName}\" ei ole kirjoitusoikeutta käynnistyskansioon \"{startupFolder}\".", - "UiSettingsLoadError": "Virhe ladattaesssa käyttöliittymän asetuksia", + "UpdateCheckStartupNotWritableMessage": "Päivitystä ei voida asentaa, koska käyttäjällä {userName} ei ole kirjoitusoikeutta käynnistyskansioon \"{startupFolder}\".", + "UiSettingsLoadError": "Käyttöliittymäasetusten lataus epäonnistui", "NotAvailable": "Ei saatavilla", "AddingTag": "Tunniste lisätään", - "AutoRedownloadFailedHelpText": "Etsi ja pyri lataamaan eri julkaisu automaattisesti.", + "AutoRedownloadFailedHelpText": "Etsi ja pyri lataamaan korvaava julkaisu automaattisesti.", "CertificateValidation": "Varmenteen vahvistus", "Agenda": "Agenda", "AgeWhenGrabbed": "Ikä (kaappaushetkellä)", "All": "Kaikki", - "UpgradeUntilMovieHelpText": "Kun tämä laatu on saavutettu, {appName} ei enää lataa elokuvia.", + "UpgradeUntilMovieHelpText": "Kun tämä laatutaso on saavutettu, ei {appName} enää kaappaa elokuvia kun mukautetun muodon katkaisutaso on saavutettu tai ylitetty.", "DeleteQualityProfile": "Poista laatuprofiili", "DeleteSelectedMovieFiles": "Poista valitut elokuvatiedostot", "DestinationPath": "Kohdesijainti", @@ -31,28 +31,28 @@ "ExistingTag": "Tunniste on jo olemassa", "ExtraFileExtensionsHelpText": "Pilkuin eroteltu listaus tuotavista oheistiedostoista (.nfo-tiedostot tuodaan \".nfo-orig\"-nimellä).", "Filter": "Suodatus", - "SupportedDownloadClientsMoreInfo": "Saat tietoja yksittäisistä lataustyökaluista painamalla niiden ohessa olevia lisätietopainikkeita.", + "SupportedDownloadClientsMoreInfo": "Saat lisätietoja yksittäisistä latauspalveluista painamalla niiden ohessa olevia lisätietopainikkeita.", "FreeSpace": "Vapaa tila", "Genres": "Lajityypit", - "GrabReleaseMessageText": "{appName} ei tunnista mille elokuvalle julkaisu kuuluu, eikä sen automaattinen tuonti onnistu. Haluatko kaapata julkaisun \"{0}\"?", + "GrabReleaseMessageText": "{appName} ei tunnistanut julkaisun elokuvaa, eikä sen vuoksi voi tuoda sitä automaattisesti. Haluatko kaapata julkaisun \"{0}\"?", "HardlinkCopyFiles": "Hardlink/tiedostojen kopiointi", "HideAdvanced": "Piilota lisäasetukset", "IgnoreDeletedMovies": "Lopeta poistettujen elokuvien valvonta", "InCinemasDate": "Teatterijulkaisu", "Interval": "Ajoitus", "IncludeUnmonitored": "Sisällytä valvomattomat", - "IndexerSearchCheckNoInteractiveMessage": "Manuaalihaulle ei ole määritetty tietolähteitä, eikä se sen vuoksi löydä tuloksia.", + "IndexerSearchCheckNoInteractiveMessage": "Manuaalihaulle ei ole määritetty tietolähteitä, eikä {appName} sen vuoksi löydä sillä tuloksia.", "Large": "Suuri", "LinkHere": "tässä", "ListSyncLevelHelpText": "Kirjaston elokuvia käsitellään valinnan perusteella, jos ne poistuvat tai niitä ei löydy tuontilistoilta.", - "ManualImportSelectMovie": "Manuaalinen tuonti - Valitse elokuva", - "MappedNetworkDrivesWindowsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä kun sovellus suoritetaan Windows-palveluna. Saat lisätietoja UKK:sta.", + "ManualImportSelectMovie": "Manuaalituonti – Valitse elokuva", + "MappedNetworkDrivesWindowsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä kun sovellus suoritetaan Windows-palveluna. Saat lisätietoja UKK:sta ({url}).", "MinimumAgeHelpText": "Vain Usenet: NZB:n vähimmäisikä minuutteina, ennen niiden kaappausta. Tämän avulla uusille julkaisuille voidaan antaa aikaa levitä Usenet-palveluntarjoajalle.", "MinimumFreeSpaceHelpText": "Estä tuonti, jos sen jälkeinen vapaa levytila olisi tässä määritettyä pienempi.", "MonitoredHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.", "MoveFolders1": "Haluatko siirtää elokuvakansiot kohteeseen \"{0}\"?", "MovieChat": "Elokuvakeskustelu", - "MultiLanguage": "Monikielinen", + "MultiLanguage": "Useita kieliä", "PosterOptions": "Julistenäkymän asetukset", "PreviewRenameHelpText": "Vihje: Esikatsellaksesi uudelleennimeämistä, valitse 'Peruuta' ja paina jonkin elokuvan otsikkoa ja käytä", "ProxyCheckResolveIpMessage": "Määritetyn välityspalvelimen \"{proxyHostName}\" IP-osoitteen selvitys epäonnistui.", @@ -65,21 +65,21 @@ "SearchCutoffUnmet": "Haun raja-arvo ei täytetty", "SearchFiltered": "Etsi suodatetuista", "SetPermissionsLinuxHelpTextWarning": "Jollet ole varma mitä nämä asetukset tekevät, älä muuta niitä.", - "RemotePathMappingRemotePathHelpText": "Lataustyökalun käyttämän hakemiston juurisijainti", + "RemotePathMappingRemotePathHelpText": "Latauspalvelun käyttämän kansion juurisijainti.", "ShowRelativeDatesHelpText": "Korvaa absoluuttiset päiväykset suhteellisilla päiväyksillä (tänään/eilen/yms.).", "TableOptionsColumnsMessage": "Valitse näytettävät sarakkeet ja niiden järjestys.", "Time": "Aika", - "BrowserReloadRequired": "Selaimen sivupäivitys vaaditaan", + "BrowserReloadRequired": "Vaatii selaimen sivupäivityksen (F5).", "UiSettingsSummary": "Kalenterin, päiväyksen ja kellonajan, sekä kielen ja heikentyneelle värinäölle sopivan tilan asetukset.", "AddCustomFormatError": "Mukautetun muodon lisäys epäonnistui. Yritä uudelleen.", - "UpdateCheckUINotWritableMessage": "Päivityksen asennus ei onnistu, koska käyttäjällä \"{userName}\" ei ole kirjoitusoikeutta käyttöliittymäkansioon \"{uiFolder}\".", + "UpdateCheckUINotWritableMessage": "Päivityksen asennus ei onnistu, koska käyttäjällä {userName} ei ole kirjoitusoikeutta käyttöliittymäkansioon \"{uiFolder}\".", "UpdateScriptPathHelpText": "Polku komentosarjaan, joka käsittelee puretun päivitystiedoston ja hoitaa asennuksen loppuosuuden.", "Version": "Versio", "AddExclusion": "Lisää poikkeussääntö", "AddNew": "Lisää uusi", "AudioInfo": "Äänitiedot", "BeforeUpdate": "Ennen päivitystä", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Käytä 'Älä suosi' -valintaa suosiaksesi mukautettujen muotojen pisteytystä Proper- ja Repack-merkintöjä enemmän.", + "DownloadPropersAndRepacksHelpTextCustomFormat": "\"Älä suosi\" käyttää Proper-/Repack-julkaisujen sijaan mukautettujen muotojen pisteytystä.", "Day": "Päivä", "DatabaseMigration": "Tietokannan siirto", "ApiKey": "Rajapinnan avain", @@ -110,8 +110,8 @@ "ImportExtraFilesMovieHelpText": "Tuo elokuvatiedostojen tuonnin yhteydessä havaitut, sääntöjä vastaavat tiedostot, kuten tekstitykset, .nfo-tiedostot, yms.", "Cast": "Lähetä", "ImportFailed": "Tuonti epäonnistui: {sourceTitle}", - "CouldNotConnectSignalR": "SignalR-kirjastoa ei tavoitettu, eikä käyttöliittymää päivitetä", - "ImportIncludeQuality": "Varmista, että tiedostojesi nimissä mainitaan videon laatu, esim. '{0}'.", + "CouldNotConnectSignalR": "SignalR-kirjastoa ei tavoitettu, eikä käyttöliittymä päivity.", + "ImportIncludeQuality": "Varmista, että tiedostojesi nimissä mainitaan videon laatu, esim. \"{0}\".", "ChmodFolder": "chmod-kansio", "ImportLibrary": "Kirjastoon tuonti", "ImportListStatusCheckSingleClientMessage": "Listat eivät ole virheiden vuoksi käytettävissä: {importListNames}", @@ -119,10 +119,10 @@ "DeleteCustomFormat": "Poista mukautettu muoto", "DeletedMovieDescription": "Elokuva poistettiin TMDB:stä.", "DeleteMovieFolder": "Poista elokuvakansio", - "DockerUpdater": "päivitä Docker-säiliö vastaanottaaksesi päivityksen", + "DockerUpdater": "Hanki päivitys päivittämällä Docker-säiliö", "Enabled": "Käytössä", - "ExcludeMovie": "Lisää elokuva pokkeuksiin", - "ExcludeTitle": "Luodaanko elokuvalle '{0}' poikkeussääntö? Tämä estää {appName}ia lisäämästä sitä tuontilistoilta automaattisesti.", + "ExcludeMovie": "Älä huomioi elokuvaa", + "ExcludeTitle": "Luodaanko elokuvalle '{0}' ohitussääntö? Tämä estää {appName}ia lisäämästä sitä tuontilistoilta automaattisesti.", "FileNameTokens": "Tiedostonimimuuttujat", "HaveNotAddedMovies": "Et ole vielä lisännyt yhtään elokuvaa. Haluatko tuoda ensin osan elokuvistasi tai ne kaikki?", "HomePage": "Verkkosivusto", @@ -136,8 +136,8 @@ "Add": "Lisää", "AddCustomFormat": "Lisää mukautettu muoto", "AddDelayProfile": "Lisää viiveprofiili", - "AddDownloadClient": "Lisää lataustyökalu", - "AddedToDownloadQueue": "Lisätty latausjonoon", + "AddDownloadClient": "Lisää latauspalvelu", + "AddedToDownloadQueue": "Lisättiin latausjonoon", "AddQualityProfile": "Lisää laatuprofiili", "AddRootFolder": "Lisää juurikansio", "AddToDownloadQueue": "Lisää latausjonoon", @@ -150,25 +150,25 @@ "AnalyticsEnabledHelpText": "Lähetä nimettömiä käyttö- ja virhetietoja {appName}in palvelimille. Tämä sisältää tietoja selaimestasi, käyttöliittymän sivujen käytöstä, virheraportoinnista, käyttöjärjestelmästä ja suoritusalustasta. Käytämme näitä tietoja ominaisuuksien ja vikakorjausten painotukseen.", "AptUpdater": "Asenna päivitys APT-työkalun avulla", "ApplyTags": "Tunnistetoimenpide", - "AuthBasic": "Perus (ponnahdusikkuna)", - "AuthenticationMethodHelpText": "Vaadi {appName}in käyttöön käyttäjätunnus ja salasana", + "AuthBasic": "Perus (selaimen ponnahdus)", + "AuthenticationMethodHelpText": "Vaadi {appName}in käyttöön käyttäjätunnus ja salasana.", "AuthForm": "Lomake (kirjautumissivu)", "Automatic": "Automaattinen", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "{appName} lopettaa levyltä poistettujen elokuvien valvonan automaattisesti.", - "BackupRetentionHelpText": "Säilytysjaksoa vanhemmat varmuuskopiot siivotaan automaattisesti.", + "BackupRetentionHelpText": "Säilytysaikaa vanhemmat varmuuskopiot siivotaan automaattisesti.", "Backups": "Varmuuskopiot", "BindAddress": "Sidososoite", "CancelProcessing": "Peru käsittely", "CantFindMovie": "Miksi en löydä elokuvaani?", "CertificateValidationHelpText": "Määritä HTTPS-varmennevahvistuksen tiukkuus. Älä muta, jos et ymmärrä riskejä.", - "CertValidationNoLocal": "Ei käytetä paikallisille osoitteille", - "CheckDownloadClientForDetails": "katso lisätietoja lataustyökalusta", + "CertValidationNoLocal": "Ei käytössä paikallisissa osoitteissa", + "CheckDownloadClientForDetails": "katso lisätietoja latauspalvelusta", "ChmodFolderHelpText": "Octal, sovelletaan tuonnin/nimeämisen yhteydessä mediakansioihin ja -tiedostoihin (ilman suoritusbittejä).", - "ChmodFolderHelpTextWarning": "Tämä toimii vain, jos käyttäjä suorittaa {appName}in tiedoston omistajana. Parempi vaihtoehto on varmistaa, että lataustyökalu asettaa oikeudet oikein.", + "ChmodFolderHelpTextWarning": "Toimii vain, jos käyttäjä suorittaa {appName}in tiedoston omistajana. Parempi vaihtoehto on varmistaa, että latauspalvelu asettaa oikeudet oikein.", "ChownGroupHelpText": "Ryhmän nimi tai GID. Käytä GID:tä etätiedostojärjestelmille.", - "ChownGroupHelpTextWarning": "Toimii vain, jos {appName}in suorittava käyttäjä on tiedoston omistaja. On parempi varmistaa, että lataustyökalu käyttää samaa ryhmää kuin {appName}.", + "ChownGroupHelpTextWarning": "Toimii vain, jos {appName}in suorittava käyttäjä on tiedoston omistaja. On parempi varmistaa, että latauspalvelu käyttää samaa ryhmää kuin {appName}.", "Dates": "Päiväykset", - "ClientPriority": "Lataustyökalun painotus", + "ClientPriority": "Latauspalvelun painotus", "Component": "Komponentti", "ColonReplacement": "Kaksoispisteen korvaus", "ColonReplacementFormatHelpText": "Määritä, mitä {appName} tekee tiedostonimien kaksoispisteille.", @@ -177,16 +177,16 @@ "Connection": "Yhteys", "CopyToClipboard": "Kopioi leikepöydälle", "CopyUsingHardlinksHelpTextWarning": "Tiedostojen käsittelystä johtuvat lukitukset saattavat joskus estää jaettavien tiedostojen uudelleennimeämisen. Voit keskeyttää jakamisen väliaikaisesti ja käyttää {appName}in nimeämistoimintoa.", - "DownloadClientStatusCheckAllClientMessage": "Lataustyökaluja ei ole ongelmien vuoksi käytettävissä", + "DownloadClientStatusCheckAllClientMessage": "Latauspalveluita ei ole ongelmien vuoksi käytettävissä", "EditGroups": "Muokkaa ryhmiä", "ListTagsHelpText": "Tunnisteet, joilla tältä tuontilistalta lisätyt kohteet merkitään.", - "Max": "Korkein", + "Max": "Suurin", "EnableSsl": "SSL-salaus", "EnableMetadataHelpText": "Luo metatietotiedostot tälle metatietotyypille.", "EnableInteractiveSearch": "Käytä manuaalihakua", "EnableInteractiveSearchHelpText": "Profiilia käytetään manuaalihakuun.", - "EnableSslHelpText": " Käyttöönotto vaatii uudelleenkäynnistyksen järjestelmänvavojan oikeuksilla.", - "Medium": "Keskikoko", + "EnableSslHelpText": " Käyttöönotto vaatii uudelleenkäynnistyksen järjestelmänvalvojan oikeuksilla.", + "Medium": "Keskikokoinen", "MinimumCustomFormatScoreHelpText": "Mukautetun muodon vähimmäispisteytys, jolla lataus sallitaan.", "MinimumAge": "Vähimmäisikä", "MinimumFreeSpace": "Vapaan tilan vähimmäismäärä", @@ -204,12 +204,12 @@ "NoMoveFilesSelf": " Ei, siirrän tiedostot itse", "NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.", "NoResultsFound": "Tuloksia ei löytynyt.", - "BranchUpdate": "{appName}in versiopäivityksiin käytettävä kehityshaara", + "BranchUpdate": "{appName}in versiopäivityksiin käytettävä kehityshaara.", "BranchUpdateMechanism": "Ulkoisen päivitysratkaisun käyttämä kehityshaara.", "BypassProxyForLocalAddresses": "Ohjaa paikalliset osoitteet välityspalvelimen ohi", "Calendar": "Kalenteri", "Cancel": "Peruuta", - "CancelPendingTask": "Haluatko varmasti perua tämän odottavan tehtävän?", + "CancelPendingTask": "Haluatko varmasti perua odottavan tehtävän?", "MovieFilesTotaling": "Elokuvatiedostot yhteensä", "OnGrab": "Kun julkaisu kaapataan", "OnHealthIssue": "Vakausongelmat", @@ -219,8 +219,8 @@ "OnRename": "Uudelleennimeäminen", "OpenThisModal": "Avaa tämä ikkuna", "PendingChangesDiscardChanges": "Hylkää muutokset ja poistu", - "PreferTorrent": "Mieluummin Torrent", - "PreferUsenet": "Mieluummin Usenet", + "PreferTorrent": "Suosi torrentia", + "PreferUsenet": "Suosi Usenetiä", "Presets": "Esiasetukset", "Profiles": "Profiilit", "ProxyType": "Välityspalvelimen tyyppi", @@ -242,7 +242,7 @@ "SuggestTranslationChange": "Ehdota käännösmuutosta", "Queued": "Lisätty jonoon", "TMDb": "TMDB", - "AlternativeTitlesLoadError": "Vaihtoehtoisten nimikkeiden lataus epäonnistui.", + "AlternativeTitlesLoadError": "Vaihtoehtoisten nimien lataus epäonnistui", "Released": "Julkaistu", "ReleasedMovieDescription": "Elokuva julkaistaan", "ReplaceWithDash": "Korvaa yhdysmerkillä", @@ -257,7 +257,7 @@ "DetailedProgressBarHelpText": "Näytä teksti tilapalkissa", "Failed": "Epäonnistui", "InCinemas": "Teatterijulkaisu", - "IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimetessä", + "IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimettäessä", "IndexerFlags": "Tietolähteen liput", "IndexerLongTermStatusCheckSingleClientMessage": "Tietolähteet eivät ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi: {indexerNames}", "IndexerStatusCheckAllClientMessage": "Tietolähteet eivät ole käytettävissä virheiden vuoksi", @@ -267,13 +267,13 @@ "LoadingMovieFilesFailed": "Elokuvatiedostojen lataus epäonnistui", "Location": "Sijainti", "Manual": "Manuaalinen", - "ManualImport": "Manuaalinen tuonti", + "ManualImport": "Manuaalituonti", "MarkAsFailed": "Merkitse epäonnistuneeksi", "Mechanism": "Mekanismi", "MediaInfo": "Median tiedot", "MediaManagement": "Median hallinta", "MediaManagementSettings": "Medianhallinnan asetukset", - "MediaManagementSettingsSummary": "Tiedostojen nimeämisen, hallinnan ja juurikansioiden asetukset.", + "MediaManagementSettingsSummary": "Tiedostojen nimeämis- ja hallinta-asetukset, sekä kirjaston juurikansiot.", "Hostname": "Osoite", "MinutesSixty": "60 minuuttia: {sixty}", "Missing": "Puuttuu", @@ -283,13 +283,13 @@ "MovieID": "Elokuvan tunnus", "MovieIndex": "Elokuvakirjasto", "MovieInfoLanguageHelpText": "{appName}in käyttöliittymässä näkyvien elokuvatietojen kieli.", - "MovieInfoLanguageHelpTextWarning": "Selaimen sivupäivitys vaaditaan", + "MovieInfoLanguageHelpTextWarning": "Vaatii selaimen sivupäivityksen (F5).", "MovieIsDownloading": "Elokuvaa ladataan", "CustomFormatUnknownCondition": "Tuntematon mukautetun muodon ehto \"{implementation}\".", "FailedDownloadHandling": "Latauksen käsittely epäonnistui", "ImportErrors": "Tuotinvirheet", "Imported": "Tuotu", - "InvalidFormat": "Väärä muoto", + "InvalidFormat": "Virheellinen muoto", "LastDuration": "Edellinen kesto", "LastExecution": "Edellinen suoritus", "ListSyncLevelHelpTextWarning": "Elokuvatiedostot poistetaan pysyvästi, mikä voi johtaa kirjaston pyyhkimiseen, jos luettelosi ovat tyhjät", @@ -297,13 +297,13 @@ "Indexer": "Tietolähde", "MovieIsMonitored": "Elokuvaa valvotaan", "Updates": "Päivitykset", - "AddImportListExclusion": "Lisää listapoikkeus", + "AddImportListExclusion": "Lisää tuontilistapoikkeus", "AddMovies": "Lisää elokuvia", "ChangeHasNotBeenSavedYet": "Muutosta ei ole vielä tallennettu", "CreateEmptyMovieFoldersHelpText": "Luo puuttuvat elokuvakansiot kirjastotarkistusten yhteydessä.", - "DeleteDownloadClient": "Poista lataustyökalu", + "DeleteDownloadClient": "Poista latauspalvelu", "ImportHeader": "Lisää {appName}iin elokuvia tuomalla olemassa oleva, järjestetty kirjasto.", - "ImportMechanismHealthCheckMessage": "Käytä valmiiden latausten käsittelyä", + "ImportMechanismHealthCheckMessage": "Käytä valmistuneiden latausten käsittelyä", "MinAvailability": "Pienin saatavuus", "MovieIsUnmonitored": "Elokuvaa ei valvota", "MovieNaming": "Elokuvien nimeäminen", @@ -317,17 +317,17 @@ "RefreshMovie": "Päivitä elokuva", "RejectionCount": "Hylkäysmäärä", "RelativePath": "Suhteellinen sijainti", - "ReleaseRejected": "Vapautus hylätty", + "ReleaseRejected": "Julkaisu hylättiin", "MovieTitle": "Elokuvan nimi", - "MovieTitleToExcludeHelpText": "Poissuljettava elokuvan nimi (voi olla mikä tahansa mielekäs)", + "MovieTitleToExcludeHelpText": "Ohitettavan elokuvan nimi (voi olla miktä tahansa merkityksellistä).", "MovieYear": "Elokuvan vuosi", - "TestAllClients": "Lataustyökalujen testaus", + "TestAllClients": "Koesta latauspalvelut", "TestAllIndexers": "Tietolähteiden testaus", "TestAllLists": "Kaikkien listojen testaus", "AddRemotePathMapping": "Lisää etäsijainnin kohdistus", "Apply": "Käytä", "Analytics": "Analytiikka", - "MovieYearToExcludeHelpText": "Elokuvan vuosi, joka suljetaan pois", + "MovieYearToExcludeHelpText": "Elokuvan ohitettava vuosi.", "Date": "Päiväys", "MustContain": "Täytyy sisältää", "MustNotContain": "Ei voi sisältää", @@ -347,8 +347,8 @@ "Ok": "Ok", "Events": "Tapahtumat", "IncludeCustomFormatWhenRenamingHelpText": "Mahdollista tämän muodon käyttö \"{Custom Formats}\" -nimeämiskaavan kanssa.", - "Overview": "Yleiskatsaus", - "OverviewOptions": "Yleiskatsauksen asetukset", + "Overview": "Tiivistelmä", + "OverviewOptions": "Tiivistelmänäkymän asetukset", "PackageVersion": "Paketin versio", "AddMovie": "Lisää elokuva", "AddRestriction": "Lisää rajoitus", @@ -381,7 +381,7 @@ "RequiredHelpText": "Tämän \"{implementationName}\" -ehdon on täsmättävä mukautetun muodon käyttämiseksi. Muutoin riittää yksi \"{implementationName}\" -vastaavuus.", "AddNewRestriction": "Lisää rajoitus", "AppDataLocationHealthCheckMessage": "Päivityksiä ei sallita, jotta AppData-kansion poistaminen päivityksen yhteydessä voidaan estää", - "RestartRequiredHelpTextWarning": "Käyttöönotto vaatii in uudelleenkäynnistyksen.", + "RestartRequiredHelpTextWarning": "Käyttöönotto vaatii sovelluksen uudelleenkäynnistyksen.", "Restore": "Palauta", "RestoreBackup": "Palauta varmuuskopio", "RootFolder": "Juurikansio", @@ -393,10 +393,10 @@ "FileBrowserPlaceholderText": "Aloita kirjoitus tai valitse sijainti alta", "StartupDirectory": "Käynnistyskansio", "System": "Järjestelmä", - "SystemTimeHealthCheckMessage": "Järjestelmän ajassa on ainakin vuorokauden heitto eivätkä ajoitetut tehtävät tämän vuoksi toimi oikein ennen kuin se on korjattu.", + "SystemTimeHealthCheckMessage": "Järjestelmän aika on ainakin vuorokauden pielessä, eivätkä ajoitetut tehtävät toimi oikein ennen kuin se on korjattu.", "Posters": "Julisteet", "PosterSize": "Julisteiden koko", - "TagCannotBeDeletedWhileInUse": "Tunnistetta ei voi poistaa, koska se on käytössä", + "TagCannotBeDeletedWhileInUse": "Tunnistetta ei voida poistaa kun se on käytössä.", "TimeFormat": "Kellonajan esitys", "TotalFileSize": "Kokonaistiedostokoko", "TotalSpace": "Kokonaistila", @@ -413,7 +413,7 @@ "NoChanges": "Muutoksia ei ole", "NoLeaveIt": "Ei, anna olla", "NoLimitForAnyRuntime": "Ei toistoajan rajoitusta", - "NotificationTriggers": "Laukaisimet", + "NotificationTriggers": "Ilmoituksen laukaisijat", "Real": "Todellinen", "ChooseAnotherFolder": "Valitse toinen kansio", "ClickToChangeLanguage": "Vaihda kieli painamalla tästä", @@ -426,15 +426,15 @@ "CloseCurrentModal": "Sulje nykyinen ikkuna", "Collection": "Kokoelma", "Conditions": "Ehdot", - "Connect": "Kytkökset", - "ConnectionLost": "Ei yhteyttä", + "Connect": "Ilmoituspalvelut", + "ConnectionLost": "Yhteys menetettiin", "Backup": "Varmuuskopiointi", - "AddNewMessage": "Uuden elokuvan lisäys on helppoa. Aloita vain haluamasi elokuvan nimen kirjoitus.", - "AddNewTmdbIdMessage": "Voit etsiä myös elokuvien TMDB ID-tunnisteilla (esim. \"tmdb:71663\").", + "AddNewMessage": "Uuden elokuvan lisääminen on helppoa. Aloita vain haluamasi elokuvan nimen kirjoittaminen.", + "AddNewTmdbIdMessage": "Voit etsiä myös elokuvien TMDB-tunnisteilla (esim. \"tmdb:71663\").", "BackupFolderHelpText": "Suhteelliset tiedostosijainnit ovat {appName}in AppData-kansiossa.", - "Connections": "Yhteydet", - "ConnectSettings": "Kytkösasetukset", - "ConnectSettingsSummary": "Ilmoitukset, kuten viestintä mediapalvelimille ja soittimille, sekä omat komentosarjat.", + "Connections": "Ilmoituspalvelut", + "ConnectSettings": "Ilmoituspavelun asetukset", + "ConnectSettingsSummary": "Yhteydet ilmoituspalveluihin, mediapalvelimiin ja soittimiin, sekä mukautetut komentosarjat.", "ConsideredAvailable": "Tulkitaan olevan saatavilla", "CopyUsingHardlinksMovieHelpText": "Hardlink-kytkösten avulla {appName} voi tuoda jaettavat torrentit ilman niiden täyttä kopiointia ja levytilan kaksinkertaista varausta. Tämä toimii vain lähde- ja kohdesijaintien ollessa samalla tallennusmedialla.", "Local": "Paikalliset", @@ -442,7 +442,7 @@ "CreateEmptyMovieFolders": "Luo elokuville tyhjät kansiot", "CreateGroup": "Luo ryhmä", "Crew": "Ryhmä", - "CurrentlyInstalled": "Nykyinen asennettu versio", + "CurrentlyInstalled": "Tällä hetkellä asennettu versio", "Custom": "Mukautettu", "CustomFilters": "Omat suodattimet", "CustomFormat": "Mukautettu muoto", @@ -453,7 +453,7 @@ "CustomFormatsSettingsSummary": "Mukautetut muodot ja niiden asetukset.", "CustomFormatUnknownConditionOption": "Tuntematon valinta \"{key}\" ehdolle \"{implementation}\".", "Cutoff": "Katkaisutaso", - "UpgradeUntilCustomFormatScoreMovieHelpText": "Kun elokuva saavuttaa laaturajoituksen tai tämän mukautetun muodon pisteytyksen, ei siihen enää kaapata uusia julkaisuja tai tuoda päivityksiä.", + "UpgradeUntilCustomFormatScoreMovieHelpText": "Kun laaturajoitus on saavutettu tai ylitetty, ja tämän mukautetun muodon pisteytys saavutetaan, ei {appName} enää kaappaa uusia julkaisuja tai tuo päivityksiä näihin elokuviin.", "CutoffUnmet": "Katkaisutasoa ei saavutettu", "Days": "Päivää", "Debug": "Vianselvitys", @@ -465,18 +465,18 @@ "DeleteBackupMessageText": "Haluatko varmasti poistaa varmuuskopion \"{name}\"?", "Deleted": "Poistettu", "DeleteDelayProfile": "Poista viiveprofiili", - "DeleteDownloadClientMessageText": "Haluatko varmasti poistaa lataustyökalun \"{name}\"?", + "DeleteDownloadClientMessageText": "Haluatko varmasti poistaa latauspalvelun \"{name}\"?", "DeleteEmptyFolders": "Poista tyhjät kansiot", "DeleteEmptyFoldersHelpText": "Poista tyhjät elokuvakansiot kirjastotarkistuksen ja elokuvatiedostojen poiston yhteydessä.", "DeleteFile": "Poista tiedosto", "DeleteMovieFilesHelpText": "Poista elokuvatiedostot ja -kansio", - "DeleteMovieFiles": "Poista {0} elokuvatiedostoa", - "DeleteHeader": "Poista - {0}", + "DeleteMovieFiles": "Poista {movieFileCount} elokuvatiedostoa", + "DeleteHeader": "Poistetaan – {0}", "DeleteImportListExclusion": "Poista tuontilistapoikkeus", "DeleteIndexer": "Poista tietolähde", "DeleteIndexerMessageText": "Haluatko varmasti poistaa tietolähteen '{name}'?", "DeleteMovieFolderHelpText": "Poista elokuvakansio ja sen sisältö", - "DeleteNotification": "Poista ilmoitus", + "DeleteNotification": "Poista ilmoituspalvelu", "DeleteNotificationMessageText": "Haluatko varmasti poistaa ilmoituspalvelun \"{name}\"?", "DeleteRestriction": "Poista rajoitus", "DeleteRestrictionHelpText": "Haluatko varmasti poistaa rajoituksen?", @@ -494,14 +494,14 @@ "DoneEditingGroups": "Lopeta ryhmien muokkaus", "DoNotPrefer": "Älä suosi", "DoNotUpgradeAutomatically": "Älä päivitä automaattisesti", - "DownloadClient": "Lataustyökalu", - "DownloadClientCheckNoneAvailableMessage": "Lataustyökaluja ei ole käytettävissä", - "DownloadClientCheckUnableToCommunicateMessage": "Viestintä lataustyökalun \"{downloadClientName}\" kanssa ei onnistu. {errorMessage}", - "DownloadClients": "Lataustyökalut", - "DownloadClientSettings": "Lataustyökalujen asetukset", + "DownloadClient": "Latauspalvelu", + "DownloadClientCheckNoneAvailableMessage": "Latauspalveluita ei ole käytettävissä", + "DownloadClientCheckUnableToCommunicateMessage": "Viestintä latauspalvelun \"{downloadClientName}\" kanssa epäonnistui. {errorMessage}", + "DownloadClients": "Latauspalvelut", + "DownloadClientSettings": "Latauspalveluasetukset", "EditCustomFormat": "Muokkaa mukautettua muotoa", - "DownloadClientsSettingsSummary": "Lataustyökalut, latausten käsittely ja etäsijaintien kohdistukset.", - "DownloadClientStatusCheckSingleClientMessage": "Lataustyökaluja ei ole ongelmien vuoksi käytettävissä: {downloadClientNames}", + "DownloadClientsSettingsSummary": "Latauspalvelut, latausten käsittely ja etäsijaintien kohdistukset.", + "DownloadClientStatusCheckSingleClientMessage": "Latauspalveluita ei ole ongelmien vuoksi käytettävissä: {downloadClientNames}", "Downloaded": "Ladattu", "DownloadedAndMonitored": "Ladattu (valvottu)", "DownloadedButNotMonitored": "Ladattu (valvomaton)", @@ -509,8 +509,8 @@ "EditMovie": "Muokkaa elokuvaa", "Downloading": "Ladataan", "DownloadPropersAndRepacks": "Proper- ja repack-julkaisut", - "DownloadPropersAndRepacksHelpText": "Määrittää päivitetäänkö tiedostot automaattisesti Proper- ja Repack-julkaisuihin (kunnollinen/uudelleenpaketoitu).", - "DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin Proper- ja Repack-päivityksiin.", + "DownloadPropersAndRepacksHelpText": "Määrittää päivitetäänkö tiedostot automaattisesti Proper-/Repack-julkaisuihin.", + "DownloadPropersAndRepacksHelpTextWarning": "Käytä mukautettuja muotoja automaattisiin Proper-/Repack-päivityksiin.", "DownloadWarning": "Latausvaroitus: {warningMessage}", "Edition": "Painos", "EditMovieFile": "Muokkaa elokuvatiedostoa", @@ -524,10 +524,10 @@ "EnableAutomaticSearchHelpText": "Profiilia käytetään automaattihauille, jotka suoritetaan käyttöliittymästä tai {appName}in toimesta.", "EnableColorImpairedMode": "Heikentyneen värinäön tila", "EnableColorImpairedModeHelpText": "Vaihtoehtoinen tyyli, joka auttaa erottamaan värikoodatut tiedot paremmin.", - "EnableCompletedDownloadHandlingHelpText": "Tuo valmistuneet lataukset lataustyökalusta automaattisesti.", - "ListEnabledHelpText": "Käytä listaa {appName}issa valitsemalla tämä.", + "EnableCompletedDownloadHandlingHelpText": "Tuo valmistuneet lataukset latauspalvelusta automaattisesti.", + "ListEnabledHelpText": "Käytä listaa valitsemalla tämä.", "SearchIsNotSupportedWithThisIndexer": "Tämä tietolähde ei tue hakua.", - "AnalyseVideoFilesHelpText": "Pura videotiedostoista resoluution, keston ja koodekkien kaltaisia tietoja. Tätä varten {appName}in on luettava osia tiedostoista, joka saattaa kasvattaa levyn ja/tai verkon kuormitusta tarkistusten aikana.", + "AnalyseVideoFilesHelpText": "Pura videotiedostoista resoluution, keston ja koodekkien kaltaisia tietoja. Tätä varten {appName}in on luettava osia tiedostoista, joka saattaa kasvattaa levyn tai verkon kuormitusta tarkistusten aikana.", "EnableRss": "RSS-syöte", "Ended": "Päättynyt", "Error": "Virhe", @@ -535,13 +535,13 @@ "ErrorRestoringBackup": "Virhe palautettaessa varmuuskopiota", "EventType": "Tapahtuman tyyppi", "Exception": "Poikkeus", - "Excluded": "Lisätty poikkeuksiin", + "Excluded": "Ohitettu", "Existing": "On jo olemassa", "ExistingMovies": "Olemassa olevat elokuva(t)", "ExportCustomFormat": "Vie mukautettu muoto", "Extension": "Laajennus", "ExternalUpdater": "{appName} on määritetty käyttämään ulkoista päivitysratkaisua.", - "ExtraFileExtensionsHelpTextsExamples": "Esimerkiksi '\"sub, .nfo\" tai \"sub,nfo\".", + "ExtraFileExtensionsHelpTextsExamples": "Esimerkiksi \"sub, .nfo\" tai \"sub,nfo\".", "FailedLoadingSearchResults": "Hakutulosten lataus epäonnistui. Yritä uudelleen.", "FailedToLoadMovieFromAPI": "Elokuvan lataus rajapinnasta epäonnistui", "FeatureRequests": "Kehitysehdotukset", @@ -587,21 +587,21 @@ "Import": "Tuo", "ImportCustomFormat": "Tuo mukautettu muoto", "ImportedTo": "Tuontikohde", - "ImportRootPath": "Osoita {appName}ille kansio, joka sisältää kaikki tuotavat elokuvat, ei vain yksittäistä elokuvaa (esim. '{0}' ei '{1}'). Lisäksi jokaisen elokuvan on oltava omissa kansioissaan juuri-/kirjastokansion alla.", + "ImportRootPath": "Osoita {appName}ille kansio, joka sisältää kaikki tuotavat elokuvat, ei vain yksittäistä elokuvaa (esim. \"{0}\" ei \"{1}\"). Lisäksi jokaisen elokuvan on oltava omissa kansioissaan juuri-/kirjastokansion alla.", "ImportTipsMessage": "Joitakin vinkkejä, joiden avulla homma sujuu:", "InCinemasMovieDescription": "Elokuva on elokuvateattereissa", "IncludeRadarrRecommendations": "Sisällytä {appName}-suositukset", "IncludeRecommendationsHelpText": "Sisällytä {appName}in suosittelemat elokuvat etsintänäkymään", "ImportMovies": "Tuo elokuvia", "IndexerPriority": "Tietolähteiden painotus", - "IndexerPriorityHelpText": "Tietolähteen painotus, 1– 50 (korkein-alin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen kaappauspäätökseen. Kaikkia käytössä olevia tietolähteitä käytetään edelleen RSS-synkronointiin ja hakuun.", - "IndexerRssHealthCheckNoAvailableIndexers": "Kaikki RSS-tietolähteet ovat tilapaisesti tavoittamattomissa viimeaikaisten tietolähdevirheiden vuoksi.", + "IndexerPriorityHelpText": "Tietolähteen painotus, 1– 50 (korkein-alin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen kaappauspäätökseen. {appName} käyttää edelleen kaikkia käytössä olevia tietolähteitä RSS-synkronointiin ja hakuun.", + "IndexerRssHealthCheckNoAvailableIndexers": "RSS-syötteitä tukevat tietolähteet eivät ole hiljattaisten tietolähdevirheiden vuoksi tilapaisesti käytettävissä.", "IndexerRssHealthCheckNoIndexers": "RSS-synkronointia varten ei ole määritetty tietolähteitä ja tämän vuoksi {appName} ei kaappaa uusia julkaisuja automaattisesti.", "Indexers": "Tietolähteet", "IndexerSearchCheckNoAutomaticMessage": "Automaattihakua varten ei ole määritetty tietolähteitä ja tämän vuoksi {appName}in automaattihaku ei löydä tuloksia.", - "IndexerSearchCheckNoAvailableIndexersMessage": "Kaikki hakukelpoiset tietolähteet ovat tilapaisesti tavoittamattomissa viimeaikaisten tietolähdevirheiden vuoksi.", + "IndexerSearchCheckNoAvailableIndexersMessage": "Hakua tukevat tietolähteet eivät ole hiljattaisten tietolähdevirheiden vuoksi tilapaisesti käytettävissä.", "IndexerSettings": "Tietolähdeasetukset", - "IndexerStatusCheckSingleClientMessage": "Tietolähteet eivät ole käytettävissä virheiden vuoksi: {indexerNames}", + "IndexerStatusCheckSingleClientMessage": "Tietolähteet eivät ole virheiden vuoksi käytettävissä: {indexerNames}", "InstallLatest": "Asenna uusin", "InteractiveImport": "Manuaalituonti", "InteractiveSearch": "Etsi manuaalisesti", @@ -615,8 +615,8 @@ "LaunchBrowserHelpText": " Avaa {appName}in verkkokäyttöliittymä verkkoselaimeen käynnistyksen yhteydessä.", "Links": "Linkit", "ImportLists": "Tuontilistat", - "ImportListSettings": "Listojen asetukset", - "ImportListsSettingsSummary": "Sisällön tuonti muista {appName}-instansseista tai Trakt-listoilta, ja listapoikkeusten hallinta.", + "ImportListSettings": "Tuontilistojen yleisasetukset", + "ImportListsSettingsSummary": "Sisällön tuonti muista {appName}-instansseista tai palveluista, ja poikkeuslistojen hallinta.", "LogFiles": "Lokitiedostot", "Logging": "Lokikirjaus", "LogLevel": "Lokikirjauksen laajuus", @@ -626,8 +626,8 @@ "LookingForReleaseProfiles1": "Etsitkö julkaisuprofiileja? Kokeile", "LookingForReleaseProfiles2": "-sivua sen sijaan.", "Lowercase": "Pienet kirjaimet", - "ManualImportSelectLanguage": "Manuaalinen tuonti - Valitse kieli", - "ManualImportSelectQuality": " Manuaalinen tuonti - Valitse laatu", + "ManualImportSelectLanguage": "Manuaalituonti – Valitse kieli", + "ManualImportSelectQuality": " Manuaalituonti – Valitse laatu", "MarkAsFailedMessageText": "Haluatko varmasti merkitä kohteen {0} epäonnistuneeksi?", "MassMovieSearch": "Elokuvien massahaku", "MaximumLimits": "Enimmäisrajoitukset", @@ -638,8 +638,8 @@ "MetadataSettings": "Metatietoasetukset", "MetadataSettingsMovieSummary": "Luo metatietotiedostot, kun elokuvia tuodaan tai niiden tietoja päivitetään.", "MIA": "Puuttuu", - "Min": "Alin", - "MinimumAvailability": "Pienin saatavuus", + "Min": "Pienin", + "MinimumAvailability": "Vähimmäissaatavuus", "MinimumCustomFormatScore": "Mukautetun muodon vähimmäispisteytys", "MinutesHundredTwenty": "120 minuuttia: {hundredTwenty}", "MinutesNinety": "90 minuuttia: {ninety}", @@ -652,7 +652,7 @@ "Months": "Kuukaudet", "MoreInfo": "Lisätietoja", "Movie": "Elokuva", - "MovieAlreadyExcluded": "Elokuva on jo suljettu pois", + "MovieAlreadyExcluded": "Elokuva on jo määritetty ohitettavaksi", "MovieDetailsNextMovie": "Elokuvan tiedot: Seuraava elokuva", "MovieIndexScrollBottom": "Elokuvakirjasto: vieritä alas", "MovieIndexScrollTop": "Elokuvakirjasto: vieritä ylös", @@ -666,14 +666,14 @@ "Options": "Asetukset", "Organize": "Järjestä", "OrganizeConfirm": "Haluatko varmasti järjestellä {count} valitun elokuvan tiedostot?", - "OrganizeSelectedMovies": "Järjestä valitut elokuvat", + "OrganizeSelectedMovies": "Järjestele valitut elokuvat", "Original": "Alkuperäiset", "OutputPath": "Tallennussijainti", "PhysicalReleaseDate": "Fyysinen julkaisu", "PreferAndUpgrade": "Suosi ja päivitä", - "PreferIndexerFlags": "Suosi tietolähteiden lippuja", - "PreferIndexerFlagsHelpText": "Painota erityislippujen mukaisia julkaisuja", - "Preferred": "Tavoite", + "PreferIndexerFlags": "Painotettavat tietolähdeliput", + "PreferIndexerFlagsHelpText": "Painota tietolähteen erityislipuilla merkittyjä julkaisuja.", + "Preferred": "Suosittu", "PreviewRename": "Nimeämisen esikatselu", "Priority": "Painotus", "PrioritySettings": "Painotus: {priority}", @@ -682,17 +682,17 @@ "ProxyCheckFailedToTestMessage": "Välityspalvelintesti epäonnistui: {url}", "ProxyPasswordHelpText": "Käyttäjätunnus ja salasana tulee täyttää vain tarvittaessa. Mikäli näitä ei ole, tulee kentät jättää tyhjiksi.", "PublishedDate": "Julkaisupäivä", - "Qualities": "Ominaisuudet", + "Qualities": "Laadut", "Quality": "Laatu", "QualityDefinitions": "Laatumääritykset", "QualityLimitsMovieRuntimeHelpText": "Rajoitukset suhteutetaan automaattisesti elokuvan kestoon.", "QualitySettingsSummary": "Laatukoot ja nimeäminen", - "SupportedIndexers": "{appName} tukee Newznab- ja Torznab-yhteensopivien tietolähteiden ohella myös monia muita alla lueteltuja tietolähteitä.", - "SupportedCustomConditions": "{appName} tukee mukautettuja ehtoja perustuen julkaisujen alla oleviin ominaisuuksiin.", + "SupportedIndexers": "{appName} tukee kaikkien Newznab-yhteensopivien tietolähteiden ohella myös monia muita alla listattuja tietolähteitä.", + "SupportedCustomConditions": "{appName} tukee alla oleviin julkaisujen ominaisuuksiin perustuvia mukautettuja ehtoja.", "Ratings": "Arviot", "RecentChanges": "Uusimmat muutokset", "RecentFolders": "Viimeisimmät kansiot", - "RecyclingBinCleanupHelpText": "Arvo \"0\" (nolla) poistaa automaattisen tyhjennyksen käytöstä.", + "RecyclingBinCleanupHelpText": "Poista automaattinen tyhjennys käytöstä asettamalla arvoksi 0.", "RecyclingBin": "Roskakori", "RefreshInformationAndScanDisk": "Päivitä tiedot ja tarkista levy", "RefreshLists": "Päivitä listat", @@ -703,28 +703,28 @@ "Reload": "Lataa uudelleen", "RemotePathMappings": "Etäsijaintien kohdistukset", "Remove": "Poista", - "RemoveCompletedDownloadsHelpText": "Poista tuodut lataukset lataustyökalun historiasta", + "RemoveCompletedDownloadsHelpText": "Poista tuodut lataukset latauspalvelun historiasta", "RemovedFromTaskQueue": "Poistettu tehtäväjonosta", "RemovedMovieCheckMultipleMessage": "Elokuvat {movies} poistettiin TMDB:stä.", "RemovedMovieCheckSingleMessage": "Elokuva {movie} poistettiin TMDB:stä.", - "RemoveFailedDownloadsHelpText": "Poista epäonnistuneet lataukset lataustyökalun historiasta.", + "RemoveFailedDownloadsHelpText": "Poista epäonnistuneet lataukset latauspalvelun historiasta.", "RemoveFilter": "Poista suodatin", - "RemoveFromDownloadClient": "Poista lataustyökalusta", + "RemoveFromDownloadClient": "Poista latauspalvelusta", "RemoveFromQueue": "Poista jonosta", - "RemoveHelpTextWarning": "Poistaminen poistaa latauksen ja sen sisältämät tiedostot lataustyökalusta.", + "RemoveHelpTextWarning": "Poistaminen poistaa latauksen ja sen sisältämät tiedostot latauspalvelusta.", "RemoveMovieAndDeleteFiles": "Poista elokuva ja poista tiedostot", "RemoveMovieAndKeepFiles": "Poista elokuva ja säilytä tiedostot", "RemoveRootFolder": "Poista juurikansio", "RemoveSelected": "Poista valitut", "RemovingTag": "Tunniste poistetaan", "Renamed": "Nimetty uudelleen", - "RenameFiles": "Nimeä tiedostot", + "RenameFiles": "Nimeä tiedostot uudelleen", "RenameMovies": "Nimeä elokuvat uudelleen", - "RenameMoviesHelpText": "Jos uudelleennimeäminen ei ole käytössä, käytetään nykyistä tiedostonimeä.", + "RenameMoviesHelpText": "Jos uudelleennimeäminen ei ole käytössä, {appName} käyttää nykyistä tiedostonimeä.", "Reorder": "Järjestä uudelleen", "Replace": "Korvaa", "ReplaceIllegalCharacters": "Korvaa kielletyt merkit", - "ReplaceIllegalCharactersHelpText": "Korvaa laittomat merkit vaihtoehtoisella merkinnällä. Jos ei valittu, ne poistetaan.", + "ReplaceIllegalCharactersHelpText": "Korvaa laittomat merkit vaihtoehtoisella merkinnällä. Jos ei valittu, {appName} poistaa ne.", "ReplaceWithSpaceDashSpace": "Korvaa yhdistelmällä \"välilyönti yhdysmerkki välilyönti\"", "Required": "Pakollinen", "RequiredRestrictionHelpText": "Julkaisun on sisällettävä ainakin yksi näistä termeistä (kirjainkoolla ei ole merkitystä).", @@ -739,19 +739,19 @@ "Restrictions": "Rajoitukset", "Result": "Tulos", "Retention": "Säilytys", - "RetentionHelpText": "Vain Usenet: Aseta nollaan asettamaan rajoittamaton säilytys", + "RetentionHelpText": "Vain Usenet: määritä rajoittamaton säilytys asettamalla arvoksi 0.", "RootFolderCheckSingleMessage": "Juurikansio puuttuu: {rootFolderPath}.", "RootFolders": "Juurikansiot", "Rss": "RSS", - "RssIsNotSupportedWithThisIndexer": "RSS-syötettä ei ole käytettävissä tälle tietolähteelle", + "RssIsNotSupportedWithThisIndexer": "Tämän tietolähteen kanssa ei voida käyttää RSS-syötettä.", "RssSyncInterval": "RSS-synkronoinnin ajoitus", "RssSyncIntervalHelpTextWarning": "Tämä koskee kaikkia tietolähteitä. Noudata niiden asettamia sääntöjä.", "Save": "Tallenna", "SaveChanges": "Tallenna muutokset", "SaveSettings": "Tallenna asetukset", "Scheduled": "Ajoitukset", - "Score": "Pisteet", - "Script": "Skripti", + "Score": "Pisteytys", + "Script": "Komentosarja", "ScriptPath": "Komentosarjan sijainti", "SearchAll": "Etsi kaikkia", "SearchFailedPleaseTryAgainLater": "Haku epäonnistui, yritä myöhemmin uudelleen.", @@ -775,8 +775,8 @@ "SetTags": "Tunnisteiden määritys", "Settings": "Asetukset", "LongDateFormat": "Pitkän päiväyksen esitys", - "RemotePathMappingHostHelpText": "Sama osoite, joka on määritty etälataustyökalulle.", - "RemotePathMappingLocalPathHelpText": "Polku, jonka kautta etäsijaintia tulee käyttää paikallisesti.", + "RemotePathMappingHostHelpText": "Sama osoite, joka on määritetty etälatauspalvelulle.", + "RemotePathMappingLocalPathHelpText": "Sijainti, jonka kautta {appName}in tulee käyttää etäsijaintia paikallisesti.", "RuntimeFormat": "Keston esitys", "ShortDateFormat": "Lyhyen päiväyksen esitys", "ShowRelativeDates": "Suhteellisten päiväysten esitys", @@ -789,7 +789,7 @@ "ShowDateAdded": "Näytä lisäyspäivä", "ShowMonitored": "Näytä valvontatila", "ShowPath": "Näytä tiedostosijainti", - "ShowMonitoredHelpText": "Näytä valvonnan tila julisteen alla.", + "ShowMonitoredHelpText": "Näytä valvontatila julisteen alla.", "ShowMovieInformation": "Näytä elokuvan tiedot", "ShowMovieInformationHelpText": "Näytä elokuvien lajutyypit ja ikäluokitukset.", "ShownClickToHide": "Näytetään, piilota painamalla tästä", @@ -813,14 +813,14 @@ "SomeResultsHiddenFilter": "Aktiivinen suodatin piilottaa joitakin tuloksia.", "SorryThatMovieCannotBeFound": "Valitettavasti elokuvaa ei löydy.", "Sort": "Järjestys", - "Source": "Lähdekoodi", + "Source": "Lähde", "SourcePath": "Lähdesijainti", "SourceRelativePath": "Lähteen suhteellinen sijainti", "SourceTitle": "Lähteen nimike", "SslCertPassword": "SSL-varmenteen salasana", "SslCertPasswordHelpText": "PFX-tiedoston salasana", "SslCertPath": "SSL-varmenteen sijainti", - "SslCertPathHelpText": "PFX-tiedoston sijainti", + "SslCertPathHelpText": "Pfx-tiedoston sijainti", "SslPort": "SSL-portti", "StandardMovieFormat": "Tavallisten elokuvien kaava", "StartImport": "Aloita tuonti", @@ -833,10 +833,10 @@ "Sunday": "Sunnuntai", "Table": "Taulukko", "TableOptions": "Taulukkonäkymän asetukset", - "TagDetails": "Tunnisteen \"{label}\" tiedot", - "TagIsNotUsedAndCanBeDeleted": "Tunnistetta ei ole määritetty millekään kohteelle, joten sen voi poistaa.", + "TagDetails": "Tunnisteen tiedot – {label}", + "TagIsNotUsedAndCanBeDeleted": "Tunniste ei ole käytössä ja voidaan poistaa.", "Tags": "Tunnisteet", - "ICalTagsMoviesHelpText": "Käytetään vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", + "ICalTagsMoviesHelpText": "Käytetään vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville.", "TagsSettingsSummary": "Täältä näet kaikki tunnisteet käyttökohteineen ja voit poistaa käyttämättömät tunnisteet.", "Tasks": "Tehtävät", "Test": "Testaa", @@ -852,9 +852,9 @@ "TorrentDelayHelpText": "Minuuttiviive, joka odotetaan ennen julkaisun Torrent-kaappausta.", "TorrentDelayTime": "Torrent-viive: {torrentDelay}", "Torrents": "Torrentit", - "TorrentsDisabled": "Torrentit pois käytöstä", + "TorrentsDisabled": "Torrentit on poistettu käytöstä", "Trace": "Jäljitys", - "Trailer": "Perävaunu", + "Trailer": "Traileri", "Trakt": "Trakt", "Trigger": "Laukaisija", "Type": "Tyyppi", @@ -863,37 +863,37 @@ "UiLanguageHelpText": "{appName}in käyttöliittymän kieli.", "UiSettings": "Käyttöliittymän asetukset", "AddConditionError": "Ehdon lisäys epäonnistui. Yritä uudelleen.", - "AddDownloadClientError": "Uuden lataustyökalun lisäys epäonnistui. Yitä uudelleen.", + "AddDownloadClientError": "Latauspalvelun lisääminen epäonnistui. Yritä uudelleen.", "AddIndexerError": "Uuden tietolähteen lisäys epäonnistui. Yritä uudelleen.", "AddImportListExclusionError": "Poikkeussäännön lisäys epäonnistui. Yritä uudelleen.", "AddListError": "Tuontilistan lisäys epäonnistui. Yritä uudelleen.", - "AddNotificationError": "Kytköksen lisäys epäonnistui. Yritä uudelleen.", + "AddNotificationError": "Ilmoituspalvelun lisääminen epäonnistui. Yritä uudelleen.", "AddQualityProfileError": "Laatuprofiilin lisäys epäonnistui. Yritä uudelleen.", "AddRemotePathMappingError": "Etäsijainnin kartoituksen lisäys epäonnistui. Yritä uudelleen.", - "BackupsLoadError": "Virhe ladattaessa varmuuskopioita", - "CustomFormatsLoadError": "Virhe ladattaessa mukautettuja muotoja", - "DelayProfilesLoadError": "Virhe ladattaessa viiveprofiileja", + "BackupsLoadError": "Varmuuskopioinnin lataus epäonnistui", + "CustomFormatsLoadError": "Mukautettujen muotojen lataus epäonnistui", + "DelayProfilesLoadError": "Viiveprofiilien lataus epäonnistui", "Unlimited": "Rajoittamaton", - "DownloadClientOptionsLoadError": "Lataustyökalun asetusten lataus epäonnistui", - "GeneralSettingsLoadError": "Virhe ladattaessa yleisiä asetuksia", - "IndexerOptionsLoadError": "Tietolähdeasetusten lataus ei onnistu", + "DownloadClientOptionsLoadError": "Latauspalveluasetusten lataus epäonnistui", + "GeneralSettingsLoadError": "Yleisasetusten lataus epäonnistui", + "IndexerOptionsLoadError": "Tietolähdeasetusten lataus epäonnistui", "IndexersLoadError": "Tietolähteiden lataus epäonnistui", "ImportListExclusionsLoadError": "Tuontilistapoikkeusten lataus epäonnistui", - "ListOptionsLoadError": "Tuontilista-asetusten lataus ei onnistu.", + "ListOptionsLoadError": "Lista-asetusten lataus epäonnistui", "ImportListsLoadError": "Tuontilistojen lataus epäonnistui", - "UnableToLoadManualImportItems": "Virhe ladattaessa manuaalituonnin kohteita.", - "MediaManagementSettingsLoadError": "Virhe ladattaessa mediatiedostojen hallinta-asetuksia", - "MetadataLoadError": "Virhe ladattaessa metatietoja", - "UnableToLoadMovies": "Elokuvien lataus epäonnistui.", - "NamingSettingsLoadError": "Virhe ladattaessa nimeämisasetuksia", - "NotificationsLoadError": "Virhe ladattaessa kytköksiä", - "QualityDefinitionsLoadError": "Virhe ladattaessa laatumäärityksiä", - "QualityProfilesLoadError": "Virhe ladattaessa laatuprofiileja", - "RemotePathMappingsLoadError": "Etäsijaintien kartoitusten lataus epäonnistui", - "UnableToLoadRestrictions": "Rajoitusten lataus epäonnistui.", - "UnableToLoadRootFolders": "Juurikansioiden lataus epäonnistui.", - "TagsLoadError": "Tunnisteiden lataus ei onnistu", - "CalendarLoadError": "Kalenterin lataus epäonnistui.", + "UnableToLoadManualImportItems": "Manuaalituonnin kohteiden lataus epäonnistui", + "MediaManagementSettingsLoadError": "Mediatiedostojen hallinta-asetusten lataus epäonnistui", + "MetadataLoadError": "Metatietojen lataus epäonnistui", + "UnableToLoadMovies": "Elokuvien lataus epäonnistui", + "NamingSettingsLoadError": "Nimeämisasetusten lataus epäonnistui", + "NotificationsLoadError": "Ilmoituspalveluiden lataus epäonnistui", + "QualityDefinitionsLoadError": "Laatumääritysten lataus epäonnistui", + "QualityProfilesLoadError": "Laatuprofiilien lataus epäonnistui", + "RemotePathMappingsLoadError": "Etäsijaintien kohdistusten lataus epäonnistui", + "UnableToLoadRestrictions": "Rajoitusten lataus epäonnistui", + "UnableToLoadRootFolders": "Juurikansioiden lataus epäonnistui", + "TagsLoadError": "Tunnisteiden lataus epäonnistui", + "CalendarLoadError": "Kalenterin lataus epäonnistui", "UpdateAppDirectlyLoadError": "{appName}ia ei voida päivittää suoraan,", "Ungroup": "Pura ryhmä", "UnmappedFilesOnly": "Vain kohdistamattomat tiedostot", @@ -908,8 +908,8 @@ "UpdateCheckStartupTranslocationMessage": "Päivitystä ei voida asentaa, koska käynnistyskansio \"{startupFolder}\" sijaitsee \"App Translocation\" -kansiossa.", "UpdateMechanismHelpText": "Käytä {appName}in sisäänrakennettua päivitystoimintoa tai komentosarjaa.", "UpdateSelected": "Päivitä valitut", - "UpgradeUntilCustomFormatScore": "Päivitä mukautetun muodon pistetytykseen saakka", - "UpgradeUntil": "Päivitä laatuun asti", + "UpgradeUntilCustomFormatScore": "Päivitä kunnes mukautetun muodon pisteytys on", + "UpgradeUntil": "Päivitä kunnes", "UpgradeUntilThisQualityIsMetOrExceeded": "Päivitä kunnes tämä laatu on savutettu tai ylitetty", "Uppercase": "Isot kirjaimet", "UrlBase": "URL-perusta", @@ -918,12 +918,12 @@ "UsenetDelay": "Usenet-viive", "UsenetDelayHelpText": "Minuuttiviive, joka odotetaan ennen julkaisun Usenet-kaappausta.", "UsenetDelayTime": "Usenet-viive: {usenetDelay}", - "UsenetDisabled": "Usenet poistettu käytöstä", + "UsenetDisabled": "Usenet on poistettu käytöstä", "UseProxy": "Käytä välityspalvelinta", "VisitTheWikiForMoreDetails": "Wikistä voit lukea lisää: ", "WaitingToProcess": "Odottaa käsittelyä", "Wanted": "Halutut", - "Warn": "Varoitus", + "Warn": "Varoita", "Week": "Viikko", "Weeks": "Viikkoa", "WhitelistedHardcodedSubsHelpText": "Tässä määritettyillä tageilla merkittyjä tekstityksiä ei luokitella poltetuiksi", @@ -934,66 +934,66 @@ "YesCancel": "Kyllä, peru", "YesMoveFiles": "Kyllä, siirrä tiedostot", "Yesterday": "Eilen", - "YouCanAlsoSearch": "Voit etsiä myös elokuvien TMDB tai IMDb ID-tunnisteilla (esim. \"tmdb:71663\").", + "YouCanAlsoSearch": "Voit etsiä myös elokuvien TMDB- tai IMDb-tunnisteilla (esim. \"tmdb:71663\").", "MaintenanceRelease": "Huoltojulkaisu: korjauksia ja muita parannuksia. Lue lisää Githubin muutoshistoriasta.", "MissingMonitoredAndConsideredAvailable": "Puuttuu (valvotaan)", "MissingNotMonitored": "Puuttuu (valvomattomat)", "MoveFolders2": "Haluatko siirtää elokuvatiedostot kansiosta {0} kansioon {1}?", "MovieDetailsPreviousMovie": "Elokuvan tiedot: Edellinen elokuva", "MovieEditor": "Elokuvaeditori", - "MovieExcludedFromAutomaticAdd": "Elokuva ei sisälly automaattiseen lisäykseen", + "MovieExcludedFromAutomaticAdd": "Elokuvaa ei huomioida automaattisessa lisäyksessä.", "Edit": "Muokkaa", "SqliteVersionCheckUpgradeRequiredMessage": "Tällä hetkellä asennettua SQLite-versiota {0} ei enää tueta. Päivitä SQLite vähintään versioon {1}.", - "ShowCinemaRelease": "Näytä teatterijulkaisu", - "ShowReleaseDate": "Näytä fyysinen julkaisu", - "ShowReleaseDateHelpText": "Näytä fyysisen julkaisun päivä julisteen alla.", + "ShowCinemaRelease": "Näytä julkaisupäivä (teatteri)", + "ShowReleaseDate": "Näytä julkaisupäivä", + "ShowReleaseDateHelpText": "Näytä vähimmäissaatavuuteen perustuva julkaisupäivä julisteen alla.", "OnMovieDelete": "Kun elokuva poistetaan", "OnMovieFileDelete": "Kun elokuvatiedosto poistetaan", "OnMovieFileDeleteForUpgrade": "Kun elokuvatiedosto poistetaan päivitystä varten", "Reddit": "Reddit", "More": "Lisää", "Download": "Lataa", - "DownloadClientRootFolderHealthCheckMessage": "Lataustyökalu \"{downloadClientName}\" tallentaa lataukset juurikansioon \"{rootFolderPath}\", mutta ne tulisi tallentaa muualle.", + "DownloadClientRootFolderHealthCheckMessage": "Latauspalvelu {downloadClientName} tallentaa lataukset juurikansioon \"{rootFolderPath}\", mutta niitä ei tulisi tallentaa sinne.", "Blocklist": "Estolista", "BlocklistRelease": "Lisää julkaisu estolistalle", "RemoveFromBlocklist": "Poista estolistalta", "Blocklisted": "Estolistalla", "BlocklistReleases": "Lisää julkaisut estolistalle", "BypassDelayIfHighestQualityHelpText": "Ohitusviive kun julkaisun laatu vastaa laatuprofiilin korkeinta käytössä olevaa laatua halutulla protokollalla.", - "RemotePathMappingCheckBadDockerPath": "Käytät Dockeria ja lataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja lataustyökalun asetukset.", - "RemotePathMappingCheckFilesGenericPermissions": "Lataustyökalu \"{downloadClientName}\" ilmoitti tiedostosijainniksi \"{path}\", mutta {appName} ei näe sitä. Kansion käyttöoikeuksia on ehkä muokattava.", - "RemotePathMappingCheckFilesWrongOSPath": "Etälataustyökalu \"{0}\" ilmoitti tiedostosijainniksi \"{1}\", mutta se ei ole kelvollinen {2}-sijainti. Tarkista etsijaintien kohdistukset lataustyökalun asetukset.", - "RemotePathMappingCheckImportFailed": "{appName} ei voinut tuoda julkaisua. Katso tarkemmat tiedot lokista.", - "RemotePathMappingCheckLocalFolderMissing": "Etälataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta sitä ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kohdistus.", - "RemotePathMappingCheckWrongOSPath": "Etälataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja lataustyökalun asetukset.", + "RemotePathMappingCheckBadDockerPath": "Käytät Dockeria ja latauspalvelu {downloadClientName} tallentaa lataukset kohteeseen \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja latauspalvelun asetukset.", + "RemotePathMappingCheckFilesGenericPermissions": "Latauspalvelu {downloadClientName} ilmoitti tiedostosijainniksi \"{path}\", mutta {appName} ei näe sitä. Kansion käyttöoikeuksia on ehkä muokattava.", + "RemotePathMappingCheckFilesWrongOSPath": "Etälatauspalvelu {downloadClientName} ilmoitti tiedostosijainniksi \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista määritetyt etäsijainnit ja latauspalvelun asetukset.", + "RemotePathMappingCheckImportFailed": "{appName} ei voinut tuoda musiikkia. Näet lisätietoja lokista.", + "RemotePathMappingCheckLocalFolderMissing": "Etälatauspalvelu {downloadClientName} tallentaa lataukset kohteeseen \"{path}\", mutta sitä ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kohdistus.", + "RemotePathMappingCheckWrongOSPath": "Etälatauspalvelu {downloadClientName} tallentaa lataukset kohteeseen \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja latauspalvelun asetukset.", "From": "lähteestä", "ImportListMissingRoot": "Tuontilistalta tai -listoilta puuttuu juurikansio: {rootFolderInfo}.", "ImportListMultipleMissingRoots": "Tuontilistoilta puuttuu useita juurikansioita: {rootFoldersInfo}", "IndexerTagMovieHelpText": "Tietolähdettä käytetään vain vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", "Letterboxd": "Letterboxd", - "NotificationTriggersHelpText": "Valitse tämän ilmoituksen laukaisevat tapahtumat.", - "RemotePathMappingCheckDownloadPermissions": "{appName} näkee ladatun elokuvan \"{path}\", mutta ei voi avata sitä. Tämä johtuu todennäköisesti liian rajallisista käyttöoikeuksista.", + "NotificationTriggersHelpText": "Valitse ilmoituksen laukaisevat tapahtumat.", + "RemotePathMappingCheckDownloadPermissions": "{appName} näkee ladatun elokuvan \"{path}\", muttei voi avata sitä. Tämä johtuu todennäköisesti liian rajallisista käyttöoikeuksista.", "RemotePathMappingCheckFileRemoved": "Tiedosto \"{path}\" poistettiin kesken käsittelyn.", - "RemotePathMappingCheckFilesLocalWrongOSPath": "Paikallinen lataustyökalu \"{downloadClientName}\" ilmoitti tiedostosijainniksi \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista lataustyökalun asetukset.", + "RemotePathMappingCheckFilesLocalWrongOSPath": "Paikallinen latauspalvelu {downloadClientName} ilmoitti tiedostosijainniksi \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista latauspalvelun asetukset.", "RemotePathMappingCheckFolderPermissions": "{appName} näkee ladatun latauskansion \"{path}\", mutta ei voi avata sitä. Tämä johtuu todennäköisesti liian rajallisista käyttöoikeuksista.", - "RemotePathMappingCheckGenericPermissions": "Lataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta {appName} ei näe sitä. Kansion käyttöoikeuksia on ehkä muokattava.", - "RemotePathMappingCheckDockerFolderMissing": "Käytät Dockeria ja lataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta sitä ei löydy Docker-säiliöstä. Tarkista etäsijaintien kohdistukset ja säiliön tallennusmedian asetukset.", - "RemotePathMappingCheckFilesBadDockerPath": "Käytät Dockeria ja lataustyökalu \"{downloadClientName}\" ilmoitti tiedostosijainniksi \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja lataustyökalun asetukset.", - "RemotePathMappingCheckRemoteDownloadClient": "Etälataustyökalu \"{downloadClientName}\" ilmoitti tiedostosijainniksi \"{path}\", mutta sitä ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kohdistus.", + "RemotePathMappingCheckGenericPermissions": "Latauspalvelu {downloadClientName} tallentaa lataukset kohteeseen \"{path}\", mutta {appName} ei näe sitä. Kansion käyttöoikeuksia on ehkä muokattava.", + "RemotePathMappingCheckDockerFolderMissing": "Käytät Dockeria ja latauspalvelu {downloadClientName} tallentaa lataukset kohteeseen \"{path}\", mutta sitä ei löydy Docker-säiliöstä. Tarkista etäsijaintien kohdistukset ja säiliön tallennusmedian asetukset.", + "RemotePathMappingCheckFilesBadDockerPath": "Käytät Dockeria ja latauspalvelu {downloadClientName} ilmoitti tiedostosijainniksi \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista etäsijaintien kohdistukset ja latauspalvelun asetukset.", + "RemotePathMappingCheckRemoteDownloadClient": "Etälatauspalvelu {downloadClientName} ilmoitti tiedostosijainniksi \"{path}\", mutta sitä ei näytä olevan olemassa. Todennäköinen syy on puuttuva tai virheellinen etäsijainnin kohdistus.", "RemoveSelectedItem": "Poista valittu kohde", "RemoveSelectedItems": "Poista valitut kohteet", - "RemotePathMappingCheckLocalWrongOSPath": "Paikallinen lataustyökalu \"{downloadClientName}\" tallentaa lataukset kohteeseen \"{path}\", mutta se ei ole kelvollinen {osName}-sijainti. Tarkista lataustyökalun asetukset.", + "RemotePathMappingCheckLocalWrongOSPath": "Paikallinen latauspalvelu {downloadClientName} tallentaa lataukset sijaintiin \"{path}\", mutta tämä ei ole kelvollinen {osName}-sijainti. Tarkista latauspalvelun asetukset.", "TaskUserAgentTooltip": "User-Agent-tiedon ilmoitti rajapinnan kanssa viestinyt sovellus.", - "UpdateAvailableHealthCheckMessage": "Uusi päivitys on saatavilla", + "UpdateAvailableHealthCheckMessage": "Uusi päivitys on saatavilla: {version}", "BypassDelayIfHighestQuality": "Ohita, jos korkein laatu", "RemoveFailed": "Poisto epäonnistui", "RemoveCompleted": "Poisto on suoritettu", - "RemoveDownloadsAlert": "Poistoasetukset on siirretty yllä olevan taulukon lataustyökalukohtaisiin asetuksiin.", + "RemoveDownloadsAlert": "Poistoasetukset on siirretty yllä olevan taulukon latauspalvelukohtaisiin asetuksiin.", "OnApplicationUpdate": "Kun sovellus päivitetään", - "DiscordUrlInSlackNotification": "Olet määrittänyt Discord-ilmoituksen Slack-ilmoitukseksi. Määritä se Discord-ilmoitukseksi parempaa toiminnallisuutta varten. Koskee seuraavia ilmoituksia: {0}", - "ManualImportSetReleaseGroup": "Manuaalinen tuonti - Määritä julkaisuryhmä", + "DiscordUrlInSlackNotification": "Olet määrittänyt Discordin Slack-ilmoituksena. Määritä se Discord-ilmoituksena parempaa toiminnallisuutta varten. Koskee seuraavia: {0}.", + "ManualImportSetReleaseGroup": "Manuaalituonti – Aseta julkaisuryhmä", "AnnouncedMovieDescription": "Elokuva on julkistettu", - "IndexerDownloadClientHelpText": "Määritä tämän tietolähteen kanssa käytettävä lataustyökalu.", + "IndexerDownloadClientHelpText": "Määritä tämän tietolähteen kanssa käytettävä latauspalvelu.", "SelectLanguages": "Valitse kielet", "SelectReleaseGroup": "Aseta julkaisuryhmä", "SetReleaseGroup": "Aseta julkaisuryhmä", @@ -1001,13 +1001,13 @@ "ClickToChangeReleaseGroup": "Vaihda julkaisuryhmää painamalla tästä", "Filters": "Suodattimet", "TmdbRating": "TMDB-arvio", - "IndexerJackettAll": "Jackettin ei-tuettua 'all'-päätettä käyttävät tietolähteet: {indexerNames}", + "IndexerJackettAll": "Jackettin ei-tuettua \"all\"-päätettä käyttävät tietolähteet: {indexerNames}.", "TmdbVotes": "TMDB-äänet", "ImdbRating": "IMDb-arvio", "ImdbVotes": "IMDb-äänet", "Auto": "Automaattinen", "Duration": "Kesto", - "ImportList": "Lista", + "ImportList": "Tuontilista", "Never": "Ei koskaan", "Rating": "Arvio", "Started": "Alkoi", @@ -1015,8 +1015,8 @@ "OriginalTitle": "Alkuperäinen nimi", "OriginalLanguage": "Alkuperäinen kieli", "Database": "Tietokanta", - "RefreshMonitoredIntervalHelpText": "Miten usein valvottujen latausten tiedot päivitetään lataustyökaluilta (vähimmäisaika on 1 minuutti).", - "RssSyncIntervalHelpText": "Aikaväli minuutteina. Arvo \"0\" (nolla) kytkee toiminnon pois käytöstä pysäyttäen automaattisen julkaisukaappauksen täysin.", + "RefreshMonitoredIntervalHelpText": "Määrittää miten usein valvottujen latausten tiedot päivitetään latauspalveluilta (vähimmäisaika on 1 minuutti).", + "RssSyncIntervalHelpText": "Aikaväli minuutteina. Poista toiminto käytöstä asettamalla arvoksi 0, joka pysäyttää automaattisen julkaisukaappauksen täysin.", "InstanceName": "Instanssin nimi", "InstanceNameHelpText": "Instanssin nimi välilehdellä ja järjestelmälokissa.", "AllCollectionsHiddenDueToFilter": "Kaikki kokoelmat on piilotettu aktiivisen suodattimen johdosta.", @@ -1036,8 +1036,8 @@ "RefreshCollections": "Päivitä kokoelmat", "ScrollMovies": "Vieritä elokuvia", "ShowCollectionDetails": "Näytä kokoelman tila", - "ShowOverview": "Näytä kuvausteksti.", - "UnableToLoadCollections": "Kokoelmia ei voitu ladata", + "ShowOverview": "Näytä kuvaus", + "UnableToLoadCollections": "Kokoelmien lataus epäonnistui", "OnMovieAdded": "Kun elokuva lisätään", "ShowPosters": "Näytä julisteet", "CollectionShowOverviewsHelpText": "Näytä kokoelmien kuvaustekstit.", @@ -1059,8 +1059,8 @@ "EditMovies": "Muokkaa elokuvia", "ShowCinemaReleaseHelpText": "Näytä teatterijulkaisun päiväys julisteen alla.", "DeleteRemotePathMapping": "Poista etäsijainnin kohdistus", - "RecycleBinUnableToWriteHealthCheck": "Määritettyyn roskakorikansioon ei voi tallentaa: {path}. Varmista, että sijainti on olemassa ja että käyttäjällä on kirjoitusoikeus kansioon.", - "DownloadClientMovieTagHelpText": "Lataustyökalua käytetään vain vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", + "RecycleBinUnableToWriteHealthCheck": "Roskakoriksi määritettyyn sijaintiin ei voida tallentaa: {path}. Varmista, että se on olemassa ja että {appName}in suorittavalla käyttäjällä on kirjoitusoikeus kansioon.", + "DownloadClientMovieTagHelpText": "Latauspalvelua käytetään vain vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", "DeleteFormatMessageText": "Haluatko varmasti poistaa muototunnisteen \"{0}\"?", "ResetAPIKeyMessageText": "Haluatko varmasti korvata rajapinnan avaimen uudella?", "ResetDefinitionTitlesHelpText": "Palauta määritysten nimet ja arvot.", @@ -1073,45 +1073,45 @@ "DeleteSelectedImportLists": "Poista tuontilista(t)", "DeleteSelectedIndexers": "Poista tietoläh(de/teet)", "ApplyTagsHelpTextAdd": "– \"Lisää\" syötetyt tunnisteet aiempiin tunnisteisiin", - "ApplyTagsHelpTextHowToApplyIndexers": "Tunnisteiden käyttö valituissa tietolähteissä", + "ApplyTagsHelpTextHowToApplyIndexers": "Tunnisteiden käyttö valituille tietolähteille", "ApplyTagsHelpTextRemove": "- \"Poista\" tyhjentää syötetyt tunnisteet", "ApplyTagsHelpTextReplace": "- \"Korvaa\" nykyiset tunnisteet syötetyillä tai tyhjennä kaikki tunnisteet jättämällä tyhjäksi", - "DeleteSelectedDownloadClients": "Poista lataustyökalu(t)", + "DeleteSelectedDownloadClients": "Poista valitut latauspalvelu(t)", "RemoveSelectedItemQueueMessageText": "Haluatko varmasti poistaa jonosta 1 kohteen?", "RemoveSelectedItemsQueueMessageText": "Haluatko varmasti poistaa jonosta {selectedCount} kohdetta?", - "LanguagesLoadError": "Virhe ladattaessa kieliä", + "LanguagesLoadError": "Kielien lataus epäonnistui", "SubtitleLanguages": "Tekstityskielet", - "SelectLanguageModalTitle": "{modalTitle} - Valitse kieli", + "SelectLanguageModalTitle": "{modalTitle} – Valitse kieli", "AppUpdated": "{appName} on päivitetty", "AppUpdatedVersion": "{appName} on päivitetty versioon {version} ja muutosten käyttöönottamiseksi se on käynnistettävä uudelleen.", "InvalidUILanguage": "Käytöliittymän kielivalinta on virheellinen. Korjaa se ja tallenna asetukset.", "GrabId": "Kaappauksen tunniste", "OverrideGrabNoLanguage": "Ainakin yksi kieli on valittava.", "BlocklistReleaseHelpText": "Estää {appName}ia lataamasta tätä julkaisua uudelleen RSS-syötteen tai automaattihaun tuloksista.", - "AuthenticationRequiredWarning": "Etäkäytön estämiseksi ilman tunnistautumista {appName} vaatii nyt todennuksen käyttöönoton. Todennus voidaan poistaa käytöstä paikallisille osoitteille.", + "AuthenticationRequiredWarning": "Etäkäytön estämiseksi ilman tunnistautumista {appName} vaatii nyt tunnistautumisen käyttöönoton. Paikallisilta osoitteilta se voidaan valinnaisesti poistaa käytöstä.", "AudioLanguages": "Äänen kielet", - "AutomaticUpdatesDisabledDocker": "Automaattisia päivityksiä ei tueta suoraan käytettäessä Dockerin päivitysmekanismia. Docker-säiliö on päivitettävä {appName}in ulkopuolella tai päivitys on suoritettava komentosarjalla.", + "AutomaticUpdatesDisabledDocker": "Automaattisia päivityksiä ei tueta suoraan käytettäessä Dockerin päivitysmekanismia. Docker-säiliö on päivitettävä {appName}in ulkopuolella, tai päivitys on suoritettava komentosarjalla.", "ConnectionLostReconnect": "{appName} pyrkii ajoittain muodostamaan yhteyden automaattisesti tai voit painaa alta \"Lataa uudelleen\".", "ConnectionLostToBackend": "{appName} kadotti yhteyden taustajärjestelmään ja se on käynnistettävä uudelleen.", "InteractiveImportNoLanguage": "Jokaisen valitun tiedoston kieli on määritettävä.", "AddAutoTag": "Lisää automaattinen tunniste", "AddCondition": "Lisää ehto", - "AddConnection": "Lisää yhteys", - "AddDownloadClientImplementation": "Lisäätään lataustyökalua - {implementationName}", + "AddConnection": "Lisää ilmoituspavelu", + "AddDownloadClientImplementation": "Lisätään latauspalvelua – {implementationName}", "AddImportList": "Lisää tuontilista", - "AddIndexerImplementation": "Lisätään tietolähdettä - {implementationName}", + "AddIndexerImplementation": "Lisätään tietolähdettä – {implementationName}", "RemoveCompletedDownloads": "Poista valmistuneet lataukset", "RootFolderPath": "Juurikansion sijainti", "AutoTaggingRequiredHelpText": "Tämän \"{implementationName}\" -ehdon on täsmättävä automaattimerkinnän säännön käyttämiseksi. Muutoin yksittäinen \"{implementationName}\" -vastaavuus riittää.", - "BlocklistLoadError": "Virhe ladattaessa estolistaa", + "BlocklistLoadError": "Estolistan lataus epäonnistui", "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Mukautetun muodon vähimmäispisteytys, jolla ensisijaisen protokollan viiveen ohitus sallitaan.", "ClearBlocklist": "Tyhjennä estolista", "ClearBlocklistMessageText": "Haluatko varmasti tyhjentää kaikki estolistan kohteet?", - "DefaultNameCopiedSpecification": "{name} - Kopioi", - "DefaultNameCopiedProfile": "{name} - Kopioi", + "DefaultNameCopiedSpecification": "{name} (kopio)", + "DefaultNameCopiedProfile": "{name} (kopio)", "DeleteImportListMessageText": "Haluatko varmasti poistaa listan \"{name}\"?", "DeleteQualityProfileMessageText": "Haluatko varmasti poistaa laatuprofiilin \"{name}\"?", - "DeleteSelectedDownloadClientsMessageText": "Haluatko varmasti poistaa {count} valit(n/tua) lataustyökalu(n/a)?", + "DeleteSelectedDownloadClientsMessageText": "Haluatko varmasti poistaa {count} valittua latauspalvelua?", "DeleteSelectedIndexersMessageText": "Haluatko varmasti poistaa {count} valit(un/tua) tietoläh(teen/dettä)?", "DownloadIgnored": "Lataus ohitettiin", "FailedToFetchUpdates": "Päivitysten nouto epäonnistui", @@ -1125,52 +1125,52 @@ "FullColorEvents": "Täysin väritetyt tapahtumat", "InfoUrl": "Tietojen URL", "LogFilesLocation": "Lokitiedostojen tallennussijainti: {location}", - "ManageDownloadClients": "Hallitse lataustyökaluja", + "ManageDownloadClients": "Hallitse latauspalveluita", "ManageIndexers": "Hallitse tietolähteitä", - "MovieImportedTooltip": "Elokuva on ladattu ja poimittu lataustyökalulta", + "MovieImportedTooltip": "Elokuva ladattiin ja poimittiin latauspalvelulta.", "NoIndexersFound": "Tietolähteitä ei löytynyt", - "NotificationStatusSingleClientHealthCheckMessage": "Ilmoitukset eivät ole ongelmien vuoksi käytettävissä: {notificationNames}", - "OrganizeNothingToRename": "Valmis! Tuöni on tehty, eikä nimettäviä tiedostoja ole.", + "NotificationStatusSingleClientHealthCheckMessage": "Ilmoituspalvelut eivät ole ongelmien vuoksi käytettävissä: {notificationNames}.", + "OrganizeNothingToRename": "Valmis! Toiminto on suoritettu, eikä uudelleennimettäviä tiedostoja ole.", "PackageVersionInfo": "{packageVersion} julkaisijalta {packageAuthor}", "ParseModalErrorParsing": "Virhe jäsennettäessä. Yritä uudelleen.", - "ParseModalHelpText": "Syötä julkaisunimike yllä olevaan kenttään.", + "ParseModalHelpText": "Syötä julkaisun nimi yllä olevaan kenttään.", "PreviouslyInstalled": "Edellinen asennettu versio", - "QualitiesLoadError": "Virhe ladattaessa laatuja", - "SetReleaseGroupModalTitle": "{modalTitle} - Aseta julkaisuryhmä", + "QualitiesLoadError": "Laatujen lataus epäonnistui", + "SetReleaseGroupModalTitle": "{modalTitle} – Aseta julkaisuryhmä", "SkipRedownload": "Ohita uudelleenlataus", "TablePageSizeHelpText": "Sivukohtainen kohdemäärä.", "TablePageSize": "Sivun kohdemäärä", "AutoTaggingNegateHelpText": "Jos käytössä, ei automaattista merkintäsääntöä käytetä tämän \"{implementationName}\" -ehdon täsmätessä.", - "CountDownloadClientsSelected": "{count} lataustyökalu(a) on valittu", + "CountDownloadClientsSelected": "{count} latauspalvelu(a) on valittu", "EditSelectedIndexers": "Muokkaa valittuja sisältölähteitä", "RemoveTagsAutomaticallyHelpText": "Poista tunnisteet automaattisesti, jos ehdot eivät täyty.", "RemoveTagsAutomatically": "Poista tunnisteet automaattisesti", - "HistoryLoadError": "Virhe ladattaessa historiaa", - "AddConditionImplementation": "Lisätään ehtoa - {implementationName}", - "AddConnectionImplementation": "Lisätään kytköstä - {implementationName}", - "AddImportListImplementation": "Lisätään tuontilistaa - {implementationName}", + "HistoryLoadError": "Historian lataus epäonnistui", + "AddConditionImplementation": "Lisätään ehtoa – {implementationName}", + "AddConnectionImplementation": "Lisätään ilmoituspavelua – {implementationName}", + "AddImportListImplementation": "Lisätään tuontilistaa – {implementationName}", "AllTitles": "Kaikki nimikkeet", - "EditDownloadClientImplementation": "Muokataan lataustyökalua - {implementationName}", - "IndexerDownloadClientHealthCheckMessage": "Tietolähteet virheellisillä lataustyökaluilla: {indexerNames}.", - "RemoveQueueItem": "Poistetaan - {sourceTitle}", + "EditDownloadClientImplementation": "Muokataan latauspalvelua – {implementationName}", + "IndexerDownloadClientHealthCheckMessage": "Tietolähteet virheellisillä latauspalveluilla: {indexerNames}.", + "RemoveQueueItem": "Poistetaan – {sourceTitle}", "TablePageSizeMaximum": "Sivukohtainen kohdemäärä ei voi olla suurempi kuin {maximumValue}.", "TablePageSizeMinimum": "Sivukohtaisen kohdemäärän on oltava vähintään {minimumValue}.", - "ApplyTagsHelpTextHowToApplyDownloadClients": "Tunnisteiden käyttö valituissa lataustyökaluissa", - "ApplyTagsHelpTextHowToApplyImportLists": "Tunnisteiden käyttö valituissa tuontilistoissa", - "SelectFolderModalTitle": "{modalTitle} - Valitse kansio(t)", - "OverrideGrabModalTitle": "Ohita ja kaappaa - {title}", + "ApplyTagsHelpTextHowToApplyDownloadClients": "Tunnisteiden käyttö valituille latauspalveluille", + "ApplyTagsHelpTextHowToApplyImportLists": "Tunnisteiden käyttö valituille tuontilistoille", + "SelectFolderModalTitle": "{modalTitle} – Valitse kansio", + "OverrideGrabModalTitle": "Ohitetaan ja kaapataan – {title}", "OverrideAndAddToDownloadQueue": "Ohita ja lisää latausjonoon", "TestParsing": "Testaa jäsennystä", "DeleteRootFolder": "Poista juurikansio", "DeleteRootFolderMessageText": "Haluatko varmasti poistaa juurikansion \"{path}\"?", - "DisabledForLocalAddresses": "Ei käytössä paikallisille osoitteille", - "NoDownloadClientsFound": "Lataustyökaluja ei löytynyt", + "DisabledForLocalAddresses": "Ei käytössä paikallisissa osoitteissa", + "NoDownloadClientsFound": "Latauspalveluita ei löytynyt", "ManageFiles": "Hallitse tiedostoja", "OrganizeLoadError": "Virhe ladattaessa esikatseluita", "OrganizeModalHeader": "Järjestele ja uudelleennimeä", "RemoveQueueItemConfirmation": "Haluatko varmasti poistaa kohteen \"{sourceTitle}\" jonosta?", - "EditSelectedDownloadClients": "Muokkaa valittuja lataustyökaluja", - "DownloadClientSortingCheckMessage": "Lataustyökalun \"{downloadClientName}\" {sortingMode} on kytketty käyttöön {appName}in kategorialle ja tuontiongelmien välttämiseksi se tulisi poistaa käytöstä.", + "EditSelectedDownloadClients": "Muokkaa valittuja latauspalveluita", + "DownloadClientSortingCheckMessage": "Latauspalvelun \"{downloadClientName}\" {sortingMode} on kytketty käyttöön {appName}in kategorialle ja tuontiongelmien välttämiseksi se tulisi poistaa käytöstä.", "OrganizeRenamingDisabled": "Uudelleennimeäminen ei ole käytössä, eikä uudelleennimettävää ole", "QueueLoadError": "Jonon lataus epäonnistui", "StopSelecting": "Lopeta valitseminen", @@ -1179,24 +1179,24 @@ "OverrideGrabNoMovie": "Elokuva on valittava", "OverrideGrabNoQuality": "Laatu on valittava", "InteractiveSearchModalHeader": "Manuaalihaku", - "NotificationStatusAllClientHealthCheckMessage": "Mikään ilmoituspavelu ei ole ongelmien vuoksi käytettävissä.", + "NotificationStatusAllClientHealthCheckMessage": "Ilmoituspalvelut eivät ole ongelmien vuoksi käytettävissä.", "NoHistoryFound": "Historiaa ei löytynyt", - "RemotePathMappingsInfo": "Etäsijaintien kohdistuksia tarvitaan harvoin ja jos {appName} ja lataustyökalu suoritetaan samassa järjestelmässä, on parempi käyttää paikallisia polkuja. Lue lisää [wikistä]({wikiLink}).", + "RemotePathMappingsInfo": "Etäsijaintien kohdistuksia tarvitaan harvoin ja jos {appName} ja latauspalvelu suoritetaan samassa järjestelmässä, on parempi käyttää paikallisia sijainteja. Lue lisää [wikistä]({wikiLink}).", "RemoveFailedDownloads": "Poista epäonnistuneet lataukset", "UpdaterLogFiles": "Päivittäjän lokitiedostot", - "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Lataustyökalu \"{downloadClientName}\" on määritetty poistamaan valmistuneet lataukset, jonka seuraksena ne saatetaan poistaa ennen kuin {appName} ehtii tuoda niitä.", - "DownloadClientsLoadError": "Virhe ladattaessa lataustyökaluja", + "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Latauspalvelu {downloadClientName} on määritetty poistamaan valmistuneet lataukset, jonka seuraksena ne saatetaan poistaa ennen kuin {appName} ehtii tuoda niitä.", + "DownloadClientsLoadError": "Latauspalveluiden lataus epäonnistui", "RemoveSelectedBlocklistMessageText": "Haluatko varmasti poistaa valitut kohteet estolistalta?", "TableOptionsButton": "Taulukon asetuspainike", "AuthenticationRequiredUsernameHelpTextWarning": "Syötä uusi käyttäjätunnus", "FormatTimeSpanDays": "{days} pv {time}", "AutoRedownloadFailed": "Uudelleenlataus epäonnistui", - "EditConnectionImplementation": "Muokataan kytköstä - {implementationName}", + "EditConnectionImplementation": "Muokataan ilmoituspalvelua – {implementationName}", "EditAutoTag": "Muokkaa automaattimerkintää", - "EditConditionImplementation": "Muokataan ehtoa - {implementationName}", - "EditImportListImplementation": "Muokataan tuontilistaa - {implementationName}", - "EditIndexerImplementation": "Muokataan tietolähdettä - {implementationName}", - "PendingDownloadClientUnavailable": "Odottaa - Lataustyökalu ei ole käytettävissä", + "EditConditionImplementation": "Muokataan ehtoa – {implementationName}", + "EditImportListImplementation": "Muokataan tuontilistaa – {implementationName}", + "EditIndexerImplementation": "Muokataan tietolähdettä – {implementationName}", + "PendingDownloadClientUnavailable": "Odottaa – Latauspalvelu ei ole käytettävissä", "ApplyChanges": "Toteuta muutokset", "AddRootFolderError": "Virhe lisättäessä juurikansiota", "FormatAgeDay": "päivä", @@ -1205,17 +1205,17 @@ "FormatShortTimeSpanSeconds": "{seconds} sekunti(a)", "DownloadClientQbittorrentSettingsContentLayout": "Sisällön rakenne", "InteractiveImportNoImportMode": "Tuontitila on valittava.", - "InteractiveImportLoadError": "Virhe ladattaessa manuaalisen tuonnin kohteita.", - "ReleaseProfilesLoadError": "Virhe ladattaessa julkaisuprofiileita", - "SelectDownloadClientModalTitle": "{modalTitle} - Valitse lataustyökalu", + "InteractiveImportLoadError": "Manuaalituonnin kohteiden lataus epäonnistui", + "ReleaseProfilesLoadError": "Julkaisuprofiilien lataus epäonnistui", + "SelectDownloadClientModalTitle": "{modalTitle} – Valitse latauspalvelu", "VideoDynamicRange": "Videon dynaaminen alue", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Vahvista uusi salasana", - "AutoRedownloadFailedFromInteractiveSearchHelpText": "Etsi ja pyri lataamaan eri julkaisu automaattisesti vaikka epäonnistunut julkaisu oli kaapattu manuaalihaun tuloksista.", - "CountImportListsSelected": "{count} tuotilistaa on valittu", - "DeletedReasonManual": "Tiedosto poistettiin käyttöliittymän kautta", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "Etsi ja lataa uusi vastaava julkaisu, kun epäonnistunut lataus on valittu manuaalihaun tuloksista.", + "CountImportListsSelected": "{count} tuontilista(a) on valittu", + "DeletedReasonManual": "Tiedosto poistettiin {appName}illa, joko manuaalisesti tai rajapinnan välityksellä jonkin muun työkalun pyynnöstä.", "DeletedReasonUpgrade": "Tiedosto poistettiin päivitetyn version tuomiseksi", "InteractiveImportNoMovie": "Elokuva on valittava jokaiselle valitulle tiedostolle.", - "MovieGrabbedTooltip": "Elokuva kaapattiin lähteestä {indexer} ja välitettiin lataajalle {downloadClient}", + "MovieGrabbedTooltip": "Elokuva kaapattiin tietolähteestä {indexer} ja välitettiin latauspalvelulle {downloadClient}.", "CloneCondition": "Monista ehto", "AutomaticAdd": "Automaattinen lisäys", "AutoTagging": "Automaattinen tunnistemerkintä", @@ -1242,7 +1242,7 @@ "AuthenticationMethod": "Tunnistautumistapa", "AutoRedownloadFailedFromInteractiveSearch": "Uudelleenlataus manuaalihaun tuloksista epäonnistui", "InteractiveImportNoFilesFound": "Valitusta kansiosta ei löytynyt videotiedostoja.", - "ManualGrab": "Manuaalinen kaappaus", + "ManualGrab": "Manuaalikaappaus", "Complete": "Kokonaiset", "DeletedReasonMovieMissingFromDisk": "{appName} ei löytänyt tiedostoa levyltä, joten sen kytkös kirjaston elokuvaan poistettiin.", "ShowImdbRatingHelpText": "Näytä IMDb-arvio julisteen alla.", @@ -1256,7 +1256,7 @@ "BypassDelayIfAboveCustomFormatScore": "Ohita, jos ylittää mukautetun muodon pisteytyksen", "DeleteAutoTagHelpText": "Haluatko varmasti poistaa automaattitunnisteen '{name}'?", "DeleteAutoTag": "Poista automaattitunniste", - "DelayingDownloadUntil": "Lataus on siirretty alkamaan {date} klo {time}.", + "DelayingDownloadUntil": "Lataus on lykätty alkamaan {date} klo {time}", "ImportUsingScriptHelpText": "Kopioi tiedostot tuontia varten oman komentosarjan avulla (esim. transkoodausta varten).", "Implementation": "Toteutus", "PasswordConfirmation": "Salasanan vahvistus", @@ -1270,12 +1270,12 @@ "ManageImportLists": "Tuontilistojen hallinta", "SelectDropdown": "Valitse...", "Unknown": "Tuntematon", - "HealthMessagesInfoBox": "Saat lisätietoja näiden vakausviestien syistä painamalla rivin lopussa olevaa wikilinkkiä (kirjakuvake) tai tarkastelemalla [lokitietoja]({link}). Mikäli kohtaat ongelmia näiden viestien tulkinnassa, tavoitat tukemme alla olevilla linkkeillä.", + "HealthMessagesInfoBox": "Saat lisätietoja näiden vakausviestien syistä painamalla rivin lopussa olevaa wikilinkkiä (kirjakuvake) tai tarkastelemalla [lokitietoja]({link}). Mikäli et osaa tulkita näitä viestejä, tavoitat tukemme alla olevilla linkeillä.", "NotificationsNtfySettingsAccessTokenHelpText": "Valinnainen tunnistepohjainen todennus. Ensisijainen ennen käyttäjätunnusta ja salasanaa.", "NotificationsNtfySettingsPasswordHelpText": "Valinnainen salasana.", "NotificationsNtfySettingsUsernameHelpText": "Valinnainen käyttäjätunnus.", "NotificationsPlexSettingsAuthToken": "Todennustunniste", - "NotificationsPlexSettingsAuthenticateWithPlexTv": "Plex.tv-tunnistautuminen", + "NotificationsPlexSettingsAuthenticateWithPlexTv": "Tunnistaudu Plexillä", "NotificationsAppriseSettingsPasswordHelpText": "HTTP Basic Auth -todennuksen salasana.", "NotificationsAppriseSettingsUsernameHelpText": "HTTP Basic Auth -todennuksen käyttäjätunnus.", "NotificationsDiscordSettingsUsernameHelpText": "Julkaisussa käytettävä käyttäjätunnus. Oletusarvo on Discordin webhook-oletus.", @@ -1295,10 +1295,10 @@ "IgnoreDownloadsHint": "Estää {appName}ia käsittelemästä näitä latauksia jatkossa.", "NotificationsAppriseSettingsConfigurationKey": "Apprise-määritysavain", "NotificationsAppriseSettingsNotificationType": "Apprisen ilmoitustyyppi", - "NotificationsPushBulletSettingSenderIdHelpText": "Lähettävän laitteen ID. Käytä laitteen pushbullet.com-URL-osoitteen \"device_iden\"-arvoa (lähetä itseltäsi jättämällä tyhjäksi).", + "NotificationsPushBulletSettingSenderIdHelpText": "Lähettävän laitteen ID-tunniste. Käytä laitteen pushbullet.com-URL-osoitteen \"device_iden\"-arvoa. Lähetä itseltäsi jättämällä tyhjäksi.", "AutoTaggingLoadError": "Automaattimerkinnän lataus epäonnistui", - "NotificationsJoinSettingsDeviceIdsHelpText": "Vanhentunut, käytä tämän sijaan laitenimiä. Pilkuin eroteltu listaus laite-ID:istä, joihin ilmoitukset lähetetään. Jos ei määritetty, lähetetään kaikkiin laitteisiin.", - "NotificationsTelegramSettingsTopicIdHelpText": "Lähetä ilmoitus tiettyyn ketjuun määrittämällä ketjun ID. Käytä yleistä aihetta jättämällä tyhjäksi (vain superryhmille).", + "NotificationsJoinSettingsDeviceIdsHelpText": "Vanhentunut, käytä tämän sijaan laitteiden nimiä. Pilkuin eroteltu listaus laitteiden ID-tunnisteista, joihin ilmoitukset lähetetään. Jos ei määritetty, lähetetään kaikkiin laitteisiin.", + "NotificationsTelegramSettingsTopicIdHelpText": "Lähetä ilmoitus tiettyyn ketjuun määrittämällä ketjun ID-tunniste. Käytä yleistä aihetta jättämällä tyhjäksi (vain superryhmille).", "NotificationsNtfySettingsTopics": "Topikit", "BlocklistAndSearch": "Estolista ja haku", "BlocklistAndSearchMultipleHint": "Etsi korvaavia kohteita kun kohteita lisätään estolistalle.", @@ -1315,7 +1315,7 @@ "NotificationsGotifySettingsServer": "Gotify-palvelin", "NotificationsJoinSettingsDeviceNames": "Laitenimet", "NotificationsNtfySettingsTagsEmojis": "Ntfy-tunnisteet ja -emojit", - "NotificationsNtfyValidationAuthorizationRequired": "Tunnistautuminen vaaditaan", + "NotificationsNtfyValidationAuthorizationRequired": "Vaatii tunnistautumisen", "NotificationsPushBulletSettingsAccessToken": "Käyttötunniste", "NotificationsPushBulletSettingsChannelTags": "Kanavatunnisteet", "NotificationsPushBulletSettingsDeviceIdsHelpText": "Pilkuin eroteltu listaus laite-ID:istä, joihin ilmoitukset lähetetään (lähetä kaikille jättämällä tyhjäksi).", @@ -1325,28 +1325,28 @@ "NotificationsPushoverSettingsSound": "Ääni", "NotificationsPushoverSettingsRetryHelpText": "Hätäilmoituksen uudelleenyritysten välinen aika.", "NotificationsPushoverSettingsUserKey": "Käyttäjäavain", - "NotificationsPushoverSettingsSoundHelpText": "Ilmoituksen ääni. Käytä oletusta jättämällä tyhjäksi.", + "NotificationsPushoverSettingsSoundHelpText": "Ilmoitusääni. Käytä oletusta jättämällä tyhjäksi.", "NotificationsTwitterSettingsConsumerKey": "Kuluttajan avain", "NotificationsTwitterSettingsAccessTokenSecret": "Käyttötunniste-salaisuus", - "NotificationsTwitterSettingsConnectToTwitter": "Muodosta X (Twitter) -yhteys", - "NotificationsTwitterSettingsConsumerKeyHelpText": "Kuluttajan avain (consumer key) X (Twitter) -sovelluksesta.", + "NotificationsTwitterSettingsConnectToTwitter": "Yhdistä X:ään", + "NotificationsTwitterSettingsConsumerKeyHelpText": "Kuluttaja-avain (\"consumer key\") X-sovelluksesta.", "NotificationsTwitterSettingsConsumerSecret": "Kuluttajan salaisuus", "NotificationsTwitterSettingsDirectMessage": "Suora viesti", - "NotificationsTwitterSettingsConsumerSecretHelpText": "Kuluttajan salaisuus (consumer secret) X (Twitter) -sovelluksesta.", + "NotificationsTwitterSettingsConsumerSecretHelpText": "Kuluttajasalaisuus (\"consumer secret\") X-sovelluksesta.", "ParseModalUnableToParse": "Annetun nimikkeen jäsennys ei onnistunut. Yritä uudelleen.", - "RemoveFromDownloadClientHint": "Poistaa latauksen ja ladatut tiedostot lataustyökalusta.", - "RemoveMultipleFromDownloadClientHint": "Poistaa latauksen ja ladatut tiedostot lataustyökalusta.", + "RemoveFromDownloadClientHint": "Poistaa latauksen ja tiedostot latauspalvelusta.", + "RemoveMultipleFromDownloadClientHint": "Poistaa lataukset ja tiedostot latauspalvelusta.", "RemoveQueueItemRemovalMethod": "Poistotapa", - "RemoveQueueItemRemovalMethodHelpTextWarning": "\"Poista lataustyökalusta\" poistaa latauksen ja sen tiedostot.", - "RemoveQueueItemsRemovalMethodHelpTextWarning": "\"Poista lataustyökalusta\" poistaa lataukset ja niiden tiedostot.", - "RetryingDownloadOn": "Latausta yritetään uudelleen {date} klo {time}.", + "RemoveQueueItemRemovalMethodHelpTextWarning": "\"Poista latauspalvelusta\" poistaa latauksen ja sen tiedostot.", + "RemoveQueueItemsRemovalMethodHelpTextWarning": "\"Poista latauspalvelusta\" poistaa lataukset ja niiden tiedostot.", + "RetryingDownloadOn": "Yritetään latausta uudelleen {date} klo {time}", "NotificationsEmailSettingsUseEncryption": "Käytä salausta", "FormatDateTime": "{formattedDate} {formattedTime}", - "ListWillRefreshEveryInterval": "Lista päivitetään {0} välein", + "ListWillRefreshEveryInterval": "Lista päivittyy {refreshInterval} välein", "MovieFileRenamedTooltip": "Elokuvatiedosto nimettiin uudelleen", "MovieFileRenamed": "Elokuvatiedosto nimettiin uudelleen", "MovieImported": "Elokuva tuotiin", - "MovieSearchResultsLoadError": "Tämän elokuvahaun tulosten lataus ei onnistu. Yritä myöhemmin uudelleen.", + "MovieSearchResultsLoadError": "Elokuvahaun tulosten lataus epäonnistui. Yritä myöhemmin uudelleen.", "ShowUnknownMovieItemsHelpText": "Näytä jonossa elokuvattomat kohteet. Tämä voi sisältää elokuvia tai mitä tahansa muuta {appName}in kategoriaan kuuluvaa.", "ThereWasAnErrorLoadingThisPage": "Virhe ladattaessa sivua", "BlocklistAndSearchHint": "Etsi korvaavaa kohdetta kun kohde lisätään estolistalle.", @@ -1358,7 +1358,7 @@ "MatchedToMovie": "Kohdistettu elokuvaan", "ReleaseHash": "Julkaisun hajatusarvo", "ImportScriptPathHelpText": "Tuontiin käytettävän komentosarjan sijainti.", - "NotificationsNtfySettingsTagsEmojisHelpText": "Valinnainen pilkuin eroteltu listaus käytettävistä tunnisteista tai emjeista.", + "NotificationsNtfySettingsTagsEmojisHelpText": "Valinnainen pilkuin eroteltu listaus käytettävistä tunnisteista tai emojeista.", "EditSelectedMovies": "Muokkaa valittuja elokuvia", "IMDbId": "IMDb ID", "ImportScriptPath": "Tuontikomentosarjan sijainti", @@ -1371,27 +1371,27 @@ "NotificationsEmailSettingsRecipientAddress": "Vastaanottajien osoitteet", "NotificationsEmailSettingsName": "Sähköposti", "NotificationsEmailSettingsRecipientAddressHelpText": "Pilkuin eroteltu listaus sähköpostiosoitteista, joihin viestit lähetetään.", - "NotificationsEmbySettingsSendNotifications": "Lähetä ilmoitukset", + "NotificationsEmbySettingsSendNotifications": "Lähetä ilmoituksia", "NotificationsEmailSettingsServer": "Palvelin", "NotificationsEmailSettingsServerHelpText": "Sähköpostipalvelimen IP-osoite tai isäntänimi.", "NotificationsEmbySettingsUpdateLibraryHelpText": "Määrittää päivitetäänkö palvelimen kirjasto tuonnin, uudelleennimeämisen tai poiston yhteydessä.", "NotificationsGotifySettingsAppTokenHelpText": "Gotifyn luoma sovellustunniste.", - "NotificationsGotifySettingsPriorityHelpText": "Ilmoituksen painotus.", + "NotificationsGotifySettingsPriorityHelpText": "Ilmoituksen ensisijaisuus.", "NotificationsJoinSettingsDeviceIds": "Laite-ID:t", "NotificationsGotifySettingsServerHelpText": "Gotify-palvelimen URL-osoite. Sisällytä http(s):// ja portti (tarvittaessa).", "NotificationsJoinSettingsApiKeyHelpText": "Join-tilisi asetuksista löytyvä rajapinnan (API) avain (paina Join API -painiketta).", - "NotificationsJoinSettingsDeviceNamesHelpText": "Pilkuin eroteltu listaus täydellisistä tai osittaisista laitenimistä, joihin ilmoitukset lähetetään. Jos ei määritetty, lähetetään kaikkiin laitteisiin.", + "NotificationsJoinSettingsDeviceNamesHelpText": "Pilkuin eroteltu listaus laitteiden täydellisistä tai osittaisista nimistä, joihin ilmoitukset lähetetään. Jos ei määritetty, lähetetään kaikkiin laitteisiin.", "NotificationsJoinSettingsNotificationPriority": "Ilmoituksen painotus", "NotificationsJoinValidationInvalidDeviceId": "Laite-ID:issä näyttäisi olevan virheitä.", "NotificationsKodiSettingsDisplayTime": "Näytä aika", - "NotificationsKodiSettingsUpdateLibraryHelpText": "Määrittää päivitetäänkö Kodin kirjasto tuonnin tai uudelleennimeämisen yhteydessä.", + "NotificationsKodiSettingsUpdateLibraryHelpText": "Määrittää päivitetäänkö Kodin kirjasto tuonnin ja uudelleennimeämisen yhteydessä.", "NotificationsKodiSettingsDisplayTimeHelpText": "Määrittää ilmoituksen näyttöajan sekunteina.", "NotificationsKodiSettingsGuiNotification": "Ilmoita käyttöliittymässä", "NotificationsMailgunSettingsApiKeyHelpText": "MailGunissa luotu rajapinnan (API) avain.", - "NotificationsNtfySettingsClickUrl": "Painalluksen URL-osoite", - "NotificationsNtfySettingsServerUrl": "Palvelimen URL-osoite", - "NotificationsNtfySettingsServerUrlHelpText": "Käytä julkista palvelinta jättämällä tyhjäksi ({url}).", - "NotificationsNtfySettingsTopicsHelpText": "Pilkuin eroteltu listaus topikeista, joihin ilmoitukset lähetetään.", + "NotificationsNtfySettingsClickUrl": "Painalluksen URL", + "NotificationsNtfySettingsServerUrl": "Palvelimen URL", + "NotificationsNtfySettingsServerUrlHelpText": "Käytä julkista palvelinta ({url}) jättämällä tyhjäksi.", + "NotificationsNtfySettingsTopicsHelpText": "Pilkuin eroteltu listaus aiheista, joille ilmoitukset lähetetään.", "NotificationsPushBulletSettingSenderId": "Lähettäjän ID", "NotificationsPlexValidationNoMovieLibraryFound": "Ainakin yksi elokuvakirjasto tarvitaan.", "NotificationsPushBulletSettingsChannelTagsHelpText": "Pilkuin eroteltu listaus kanavatunnisteista, joille ilmoitukset lähetetään.", @@ -1399,16 +1399,16 @@ "NotificationsPushcutSettingsApiKeyHelpText": "Rajapinnan (API) avaimia voidaan hallita Puscut-sovelluksen tiliosiossa.", "NotificationsSettingsUpdateLibrary": "Päivitä kirjasto", "NotificationsSendGridSettingsApiKeyHelpText": "SendGridin luoma rajapinnan (API) avain.", - "NotificationsTraktSettingsAuthenticateWithTrakt": "Trakt-tunnistautuminen.", + "NotificationsTraktSettingsAuthenticateWithTrakt": "Tunnistaudu Traktilla", "NotificationsTraktSettingsAuthUser": "Todennettu käyttäjä", "NotificationsTraktSettingsExpires": "Erääntyy", "OnManualInteractionRequiredHelpText": "Kun tarvitaan manuaalisia toimenpiteitä", "Or": "tai", - "ParseModalHelpTextDetails": "{appName} pyrkii jäsentämään nimikkeen ja näyttämään sen tiedot.", + "ParseModalHelpTextDetails": "{appName} pyrkii jäsentämään nimen ja näyttämään sen tiedot.", "Umask": "Umask", - "WhySearchesCouldBeFailing": "Selvitä miksi haku saattaa epäonnistua painamalla tästä", + "WhySearchesCouldBeFailing": "Paina tästä selvittääksesi miksi haut saattavat epäonnistua", "OnManualInteractionRequired": "Kun tarvitaan manuaalisia toimenpiteitä", - "NotificationsValidationUnableToConnectToApi": "Palvelun {service} rajapintaa ei tavoiteta. Palvelinyhteys epäonnistui: ({responseCode}) {exceptionMessage}.", + "NotificationsValidationUnableToConnectToApi": "Palvelun {service} rajapintaan ei voitu muodostaa yhteyttä. Palvelinyhteys epäonnistui: ({responseCode}) {exceptionMessage}.", "SearchMoviesConfirmationMessageText": "Haluatko varmasti etsiä {count} elokuvaa?", "Parse": "Jäsennä", "CustomFormatsSpecificationRegularExpression": "Säännöllinen lauseke", @@ -1418,8 +1418,8 @@ "MovieFolderImportedTooltip": "Elokuva tuotiin elokuvakansiosta", "True": "Tosi", "SkipRedownloadHelpText": "Estää {appName}ia lataamasta kohteelle vaihtoehtoista julkaisua.", - "NotificationsDiscordSettingsOnImportFieldsHelpText": "Määritä tuonti-ilmoituksissa välitettävät tietueet.", - "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Määritä kaappausilmoituksissa välitettäviä tietueet.", + "NotificationsDiscordSettingsOnImportFieldsHelpText": "Muuta tuonti-ilmoituksiin sisällytettäviä tietoja.", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Muuta kaappausilmoituksiin sisällytettäviä tietoja.", "NotificationsDiscordSettingsOnImportFields": "Tuonti-ilmoitusten tietueet", "NotificationsDiscordSettingsOnGrabFields": "Kaappausilmoitusten tietueet", "NotificationsMailgunSettingsUseEuEndpointHelpText": "Käytä MailGunin EU-päätepistettä.", @@ -1433,30 +1433,30 @@ "NotificationsPushcutSettingsTimeSensitiveHelpText": "Merkitsee ilmoituksen kiireelliseksi (\"Time Sensitive\").", "NotificationsPushcutSettingsNotificationNameHelpText": "Ilmoituksen nimi Pushcut-sovelluksen ilmoitusvälilehdeltä.", "NotificationsSettingsUpdateMapPathsTo": "Kohdista sijainnit kohteeseen", - "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName}-sijainti, jonka perusteella elokuvien sijainteja muutetaan kun {serviceName} näkemä kirjastosijainti poikkeaa {appName}in sijainnista (vaatii \"Päivitä kirjasto\" -asetuksen).", "NotificationsSettingsUpdateMapPathsFrom": "Kohdista sijainnit lähteeseen", - "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName}-sijainti, jonka mukaisesti sarjasijainteja muutetaan kun {serviceName} näkee kirjastosijainnin eri tavalla kuin {appName} (vaatii \"Päivitä kirjasto\" -asetuksen).", - "NotificationsSignalSettingsSenderNumberHelpText": "Signal-API:n lähettäjärekisterin puhelinnumero.", - "NotificationsSignalSettingsGroupIdPhoneNumber": "Ryhmän iD/puhelinnumero", - "NotificationsSignalSettingsPasswordHelpText": "Salasana, jolla Signal-API:lle lähetettävät pyynnöt todennetaan.", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName}-sijainti, jonka perusteella elokuvien sijainteja muutetaan kun {serviceName} näkemä kirjastosijainti poikkeaa {appName}in sijainnista (vaatii \"Päivitä kirjasto\" -asetuksen).", + "NotificationsSignalSettingsSenderNumberHelpText": "Signalin rajapinnan lähettäjärekisterin puhelinnumero.", + "NotificationsSignalSettingsGroupIdPhoneNumber": "Ryhmän ID/puhelinnumero", + "NotificationsSignalSettingsPasswordHelpText": "Salasana, jolla Signalin rajapinnalle lähetettävät pyynnöt todennetaan.", "NotificationsSignalSettingsSenderNumber": "Lähettäjän numero", - "NotificationsSignalSettingsUsernameHelpText": "Käyttäjätunnus, jolla Signal-API:lle lähetettävät pyynnöt todennetaan.", + "NotificationsSignalSettingsUsernameHelpText": "Käyttäjätunnus, jolla Signalin rajapinnalle lähetettävät pyynnöt todennetaan.", "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "Vastaanottavan ryhmän ID tai vastaanottajan puhelinnumero.", "NotificationsSimplepushSettingsKey": "Avain", "NotificationsSynologyValidationTestFailed": "Ei ole Synology tai synoindex ei ole käytettävissä", - "NotificationsTelegramSettingsSendSilentlyHelpText": "Lähettää viestin äänettömästi, jolloin vastanottaja saa ilmoituksen ilman ääntä.", + "NotificationsTelegramSettingsSendSilentlyHelpText": "Lähettää viestin äänettömästi, jolloin vastaanottajat saavat ilmoituksen ilman ääntä.", "NotificationsTelegramSettingsChatIdHelpText": "Vastaanottaaksesi viestejä, sinun on aloitettava keskustelu botin kanssa tai lisättävä se ryhmääsi.", "NotificationsTwitterSettingsAccessToken": "Käyttötunniste", "NotificationsValidationInvalidHttpCredentials": "HTTP Auth -tunnistetiedot eivät kelpaa: {exceptionMessage}", "NotificationsTwitterSettingsMention": "Maininta", "NotificationsValidationInvalidAccessToken": "Käyttötunniste on virheellinen.", "NotificationsTwitterSettingsMentionHelpText": "Mainitse tämä käyttäjä lähetettävissä twiiteissä.", - "NotificationsValidationUnableToConnect": "Yhteydenmuodostus ei onnistu: {exceptionMessage}", + "NotificationsValidationUnableToConnect": "Yhteyttä ei voitu muodostaa: {exceptionMessage}.", "NotificationsValidationInvalidAuthenticationToken": "Todennustunniste on virheellinen", "NotificationsValidationInvalidApiKeyExceptionMessage": "Rajapinnan avain ei kelpaa: {exceptionMessage}", "NotificationsValidationInvalidApiKey": "Rajapinnan avain ei kelpaa", "NotificationsTwitterSettingsDirectMessageHelpText": "Lähetä julkisen viestin sijaan suora viesti.", - "NotificationsValidationUnableToConnectToService": "Palvelua {serviceName} ei tavoiteta.", + "NotificationsValidationUnableToConnectToService": "Palveluun {serviceName} ei voitu muodostaa yhteyttä.", "NotificationsValidationUnableToSendTestMessage": "Testiviestin lähetys ei onnistu: {exceptionMessage}", "NotificationsEmailSettingsUseEncryptionHelpText": "Määrittää suositaanko salausta, jos se on määritetty palvelimelle, käytetäänkö aina SSL- (vain portti 465) tai StartTLS-salausta (kaikki muut portit), voi käytetäänkö salausta lainkaan.", "DownloadFailedMovieTooltip": "Elokuvan lataus epäonnistui", @@ -1466,12 +1466,12 @@ "Rejections": "Hylkäykset", "CutoffNotMet": "Katkaisutasoa ei ole saavutettu", "IndexerSettingsRejectBlocklistedTorrentHashes": "Hylkää estetyt torrent-hajautusarvot kaapattaessa", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Jos torrent on estetty hajautusarvon perusteella sitä ei välttämättä hylätä oikein etsittäessä joiltakin tietolähteiltä RSS-syötteen tai haun välityksellä. Tämä mahdollistaa tällaisten torrentien hylkäämisen kaappauksen jälkeen, mutta ennen välitystä lataustyökalulle.", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Jos torrent on estetty hajautusarvon perusteella sitä ei välttämättä hylätä oikein joidenkin tietolähteiden RSS-syötteestä tai hausta. Tämän käyttöönotto mahdollistaa tällaisten torrentien hylkäämisen kaappauksen jälkeen, kuitenkin ennen kuin niitä välitetään latauspalvelulle.", "MovieFileMissingTooltip": "Elokuvatiedosto puuttuu", "NotificationsAppriseSettingsServerUrlHelpText": "Apprise-palvelimen URL-osoite. SIsällytä myös http(s):// ja portti (tarvittaessa).", - "NotificationsAppriseSettingsServerUrl": "Apprise-palvelimen URL-osoite", + "NotificationsAppriseSettingsServerUrl": "Apprise-palvelimen URL", "NotificationsCustomScriptSettingsArguments": "Argumentit", - "NotificationsAppriseSettingsStatelessUrls": "Apprisen tilaton URL-osoite", + "NotificationsAppriseSettingsStatelessUrls": "Apprisen tilattomat URL:t", "NotificationsAppriseSettingsTags": "Apprisen tunnisteet", "NotificationsAppriseSettingsTagsHelpText": "Ilmoita vain vastaavalla tavalla merkityille kohteille.", "NotificationsAppriseSettingsStatelessUrlsHelpText": "Yksi tai useita pilkuin eroteltuja URL-osoitteita ilmoitusten kohdistamiseen. Jätä tyhjäksi, jos käytetään pysyvää tallennustilaa.", @@ -1479,24 +1479,24 @@ "NotificationsCustomScriptSettingsArgumentsHelpText": "Komentosarjalle välitettävät argumentit.", "NotificationsCustomScriptSettingsProviderMessage": "Testaus suorittaa komentosarjan EventType-arvolla \"{eventTypeTest}\". Varmista, että komentosarjasi käsittelee tämän oikein.", "NotificationsDiscordSettingsAuthor": "Julkaisija", - "NotificationsDiscordSettingsAuthorHelpText": "Korvaa ilmoitukselle näytettävä upotettu julkaisijatieto. Jos tyhjä, käytetään instanssin nimeä.", + "NotificationsDiscordSettingsAuthorHelpText": "Korvaa ilmoituksessa näytettävä upotettu julkaisijatieto. Käytä instanssin nimeä jättämällä tyhjäksi.", "NotificationsCustomScriptSettingsName": "Oma komentosarja", "NotificationsDiscordSettingsOnManualInteractionFields": "Toimenpidetarveilmoitusten tietueet", - "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "Määritä toimenpidetarveilmoituksissa välitettäviä tietueet.", + "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "Muuta manuaalitoimenpideilmoituksiin sisällytettäviä tietoja.", "NotificationsEmailSettingsBccAddress": "Piilokopio-osoitteet", "NotificationsDiscordSettingsWebhookUrlHelpText": "Discord-kanavan webhook-viestinnän URL-osoite.", "NotificationsDiscordSettingsAvatar": "Käyttäjäkuvake", "NotificationsEmailSettingsBccAddressHelpText": "Pilkuin eroteltu listaus sähköpostiosoitteista, joihin viestit lähetetään piilokopioina.", "NotificationsGotifySettingsAppToken": "Sovellustietue", - "NotificationsEmbySettingsSendNotificationsHelpText": "Ohjeista palvelinta välittämään ilmoitukset sen määritettyihin kohteisiin.", + "NotificationsEmbySettingsSendNotificationsHelpText": "Ohjeista Embyä ilmoittamaan myös siihen kytketyille palveluille. Ei toimi Jellyfinin kanssa.", "NotificationsEmailSettingsCcAddress": "Kopio-osoitteet", - "NotificationsNtfySettingsClickUrlHelpText": "Valinnainen URL-osoite, joka ilmoitusta painettaessa avataan.", + "NotificationsNtfySettingsClickUrlHelpText": "Valinnainen, ilmoitusta painettaessa avattava URL-osoite.", "NotificationsKodiSettingsCleanLibrary": "Siivoa kirjasto", "NotificationsKodiSettingsCleanLibraryHelpText": "Siivoa kirjasto päivityksen jälkeen.", - "NotificationsSettingsWebhookUrl": "Webhook-URL-osoite", + "NotificationsSettingsWebhookUrl": "Webhook URL", "NotificationsSlackSettingsChannel": "Kanava", - "NotificationsSignalValidationSslRequired": "Näyttää siltä, että SSL-yhteys vaaditaan", - "NotificationsSettingsUseSslHelpText": "Muodosta yhteys sovellukseen {serviceName} SSL-protokollan välityksellä.", + "NotificationsSignalValidationSslRequired": "SSL-yhteys näyttää olevan pakollinen.", + "NotificationsSettingsUseSslHelpText": "Muodosta yhteys palveluun {serviceName} SSL-protokollan välityksellä.", "NotificationsSettingsWebhookMethodHelpText": "Lähetyksessä käytettävä HTTP-menetelmä.", "NotificationsSettingsWebhookMethod": "HTTP-menetelmä", "NotificationsSimplepushSettingsEvent": "Tapahtuma", @@ -1509,111 +1509,111 @@ "NotificationsSynologyValidationInvalidOs": "On oltava Synology", "NotificationsSynologySettingsUpdateLibraryHelpText": "Kehota paikallista localhost-synoindexiä päivittämääin kirjasto.", "ReleaseGroups": "Julkaisuryhmät", - "DownloadClientPriorityHelpText": "Lautaustyökalujen painotus, 1– 50 (korkein-alin). Oletusarvo on 1 ja tasaveroiset erotetaan Round-Robin-tekniikalla.", + "DownloadClientPriorityHelpText": "Useiden latauspalveluiden painotus, 1–50 (korkein-alin). Oletusarvo on 1 ja tasaveroiset erotetaan Round-Robin-tekniikalla.", "BlackholeFolderHelpText": "Kansio, jonne {appName} tallentaa {extension}-tiedoston.", "BlackholeWatchFolder": "Valvontakansio", "BlackholeWatchFolderHelpText": "Kansio, josta {appName}in tulee tuoda valmistuneet lataukset.", "Category": "Kategoria", - "ChangeCategoryHint": "Vaihtaa latauksen kategoriaksi lataustyökalun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.", + "ChangeCategoryHint": "Vaihtaa latauksen kategoriaksi latauspalvelun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.", "DownloadClientFloodSettingsAdditionalTagsHelpText": "Lisää median ominaisuuksia tunnisteina. Vihjeet ovat esimerkkejä.", "DownloadClientQbittorrentSettingsFirstAndLastFirst": "Ensimmäinen ja viimeinen ensin", - "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Aloita lataamalla ensimmäinen ja viimeinen osa (qBittorrent 4.1.0+).", + "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Lataa ensimmäinen ja viimeinen osa ensin (qBittorrent 4.1.0+).", "DownloadClientQbittorrentSettingsSequentialOrder": "Peräkkäinen järjestys", "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Lataa tiedostot järjestyksessä (qBittorrent 4.1.0+).", "DownloadClientQbittorrentSettingsUseSslHelpText": "Käytä suojattua yhteyttä. Katso qBittorentin asetusten \"Selainkäyttö\"-osion \"Käytä HTTPS:ää HTTP:n sijaan\" -asetus.", - "DownloadClientQbittorrentValidationCategoryAddFailure": "Kategorian määritys epäonnistui", + "DownloadClientQbittorrentValidationCategoryAddFailure": "Kategorian määrittäminen epäonnistui", "DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName} ei voinut lisätä tunnistetta qBittorrentiin.", - "DownloadClientQbittorrentValidationCategoryRecommended": "Kategorian määritys on suositeltavaa", + "DownloadClientQbittorrentValidationCategoryRecommended": "Kategorian määrittäminen on suositeltavaa", "DownloadClientQbittorrentValidationCategoryUnsupported": "Kategorioita ei tueta", - "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} ei pyri tuomaan valmistuneita latauksia ilman kategoriamääritystä.", - "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "Kategoriatuki lisättiin qBittorrent-versiossa 3.3.0. Päivitä asennuksesi tai yritä uudelleen ilman kategoriaa.", + "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName} ei yritä tuoda valmistuneita latauksia ilman kategoriaa.", + "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "Kategoriatuki lisättiin qBittorrentin versiossa 3.3.0. Päivitä asennuksesi tai yritä uudelleen ilman kategoriaa.", "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "Torrentien jonotus ei ole käytössä qBittorent-asetuksissasi. Ota se käyttöön tai valitse painotukseksi \"Viimeiseksi\".", - "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Sinun on poistettava päiväysjärjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä Sabnzbd:stä.", - "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Sinun on poistettava elokuvien järjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä Sabnzbd:stä.", + "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "Sinun on poistettava päiväysjärjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä SABnzb:stä.", + "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "Sinun on poistettava elokuvien järjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä SABnzb:stä.", "DownloadClientSabnzbdValidationEnableJobFolders": "Käytä työkansioita", - "DownloadClientSettingsAddPaused": "Lisää pysäytettynä", + "DownloadClientSettingsAddPaused": "Lisää keskeytettynä", "DownloadClientSettingsCategoryHelpText": "Luomalla {appName}ille oman kategorian, erottuvat sen lataukset muiden lähteiden latauksista. Kategorian määritys on valinnaista, mutta erittäin suositeltavaa.", "DownloadClientSettingsCategorySubFolderHelpText": "Luomalla {appName}ille oman kategorian, erottuvat sen lataukset muiden lähteiden latauksista. Kategorian määritys on valinnaista, mutta erittäin suositeltavaa. Tämä luo latauskansioon [kategoria]-alikansion.", "DownloadClientSettingsDestinationHelpText": "Määrittää manuaalisen tallennuskohteen. Käytä oletusta jättämällä tyhjäksi.", - "DownloadClientSettingsInitialState": "Virheellinen tila", - "DownloadClientSettingsInitialStateHelpText": "Lataustyökaluun {clientName} lisättyjen torrentien aloitustila.", + "DownloadClientSettingsInitialState": "Aloitustila", + "DownloadClientSettingsInitialStateHelpText": "Latauspalveluun {clientName} lisättyjen torrentien aloitustila.", "DownloadClientSettingsOlderPriority": "Vanhojen painotus", "DownloadClientSettingsOlderPriorityMovieHelpText": "Yli 21 päivää sitten julkaistujen elokuvien kaappauksille käytettävä painotus.", "DownloadClientSettingsPostImportCategoryHelpText": "Kategoria, jonka {appName} asettaa tuonnin jälkeen. {appName} ei poista tämän kategorian torrenteja vaikka jakaminen olisi päättynyt. Säilytä alkuperäinen kategoria jättämällä tyhjäksi.", "DownloadClientSettingsRecentPriority": "Uusien painotus", "DownloadClientSettingsRecentPriorityMovieHelpText": "21 päivän sisällä julkaistujen elokuvien kaappauksille käytettävä painotus.", - "DownloadClientSettingsUrlBaseHelpText": "Lisää etuliite lataustuökalun {clientName} URL-osoitteeseen, kuten {url}.", - "DownloadClientSettingsUseSslHelpText": "Muodosta {clientName} -yhteys käyttäen salattua yhteyttä.", + "DownloadClientSettingsUrlBaseHelpText": "Lisää lataustuökalun {clientName} URL-osoitteeseen etuliitteen, esim. \"{url}\".", + "DownloadClientSettingsUseSslHelpText": "Muodosta {clientName}-yhteys käyttäen salattua yhteyttä.", "DownloadClientValidationCategoryMissing": "Kategoriaa ei ole olemassa", "DownloadClientValidationCategoryMissingDetail": "Syötettyä kategoriaa ei ole lautaustyökalussa {clientName}. Luo se sinne ensin.", "PostImportCategory": "Tuonnin jälkeinen kategoria", "UseSsl": "Käytä SSL-salausta", - "DownloadClientAriaSettingsDirectoryHelpText": "Valinnainen latuasten tallennussijainti. Käytä Aria2-oletusta jättämällä tyhjäksi.", - "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Sinun on poistettava televisiojärjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä Sabnzbd:stä.", - "ChangeCategoryMultipleHint": "Vaihtaa latausten kategoriaksi lataustyökalun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.", + "DownloadClientAriaSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Aria2:n oletusta jättämällä tyhjäksi.", + "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "Sinun on poistettava televisiojärjestely käytöstä {appName}in käyttämältä kategorialta tuontiongelmien välttämiseksi. Korjaa tämä SABnzb:stä.", + "ChangeCategoryMultipleHint": "Vaihtaa latausten kategoriaksi latauspalvelun \"Tuonnin jälkeinen kategoria\" -asetuksen kategorian.", "Destination": "Kohde", "Directory": "Kansio", "Donate": "Lahjoita", - "DownloadClientDelugeSettingsUrlBaseHelpText": "Lisää etuliitteen Delugen JSON-URL-osoitteeseen (ks. {url}).", + "DownloadClientDelugeSettingsUrlBaseHelpText": "Lisää Delugen JSON-URL-osoitteeseen etuliitteen, ks. \"{url})\".", "DownloadClientDelugeTorrentStateError": "Deluge ilmoittaa virhettä", "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorioiden käyttö edellyttää, että {clientName}n Label-tunnistelisäosa on käytössä.", "DownloadClientDelugeValidationLabelPluginInactive": "Label-tunnistelisäosa ei ole käytössä.", - "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} ei voinut lisätä Label-tunnistetta {clientName}en.", + "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} ei voinut lisätä Label-tunnistetta palveluun {clientName}.", "DownloadClientQbittorrentTorrentStateStalled": "Lataus on jäätynyt, koska yhdistettyjä lähteitä ei ole.", "MovieIsPopular": "Elokuva on suosittu TMDB:ssä", "MovieIsTrending": "Elokuva on nousussa TMDB:ssä", "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "Magnet-linkeille käytettävä tiedostopääte. Oletus on \".magnet\".", "DownloadClientDelugeValidationLabelPluginFailure": "Label-tunnisteen määritys epäonnistui.", - "DownloadClientDownloadStationProviderMessage": "{appName} ei voi yhdistää Download Stationiin, jos DSM-tilisi on määritetty käyttämään kaksivaihesita tunnistautumista.", - "DownloadClientDownloadStationSettingsDirectoryHelpText": "Valinnainen jaettu kansio latauksille. Download Stationin oletussijaintia jättämällä tyhjäksi.", - "DownloadClientDownloadStationValidationApiVersion": "Download Stationin API-versiota ei tueta. Sen tulee olla vähintään {requiredVersion} (versioita {minVersion}–{maxVersion} tuetaan).", + "DownloadClientDownloadStationProviderMessage": "{appName} ei voi muodostaa yhteyttä Download Stationiin, jos DSM-tili on määritetty käyttämään kaksivaiheista tunnistautumista.", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "Vaihtoehtoinen jaettu kansio latauksille. Käytä Download Stationin oletussijaintia jättämällä tyhjäksi.", + "DownloadClientDownloadStationValidationApiVersion": "Download Stationin rajapinnan versiota ei tueta. Sen tulee olla vähintään {requiredVersion} (versioita {minVersion}–{maxVersion} tuetaan).", "DownloadClientDownloadStationValidationFolderMissingDetail": "Kansiota \"{downloadDir}\" ei ole olemassa. Se on luotava manuaalisesti jaettuun kansioon \"{sharedFolder}\".", "DownloadClientDownloadStationValidationNoDefaultDestination": "Oletussijaintia ei ole", "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Tällä Diskstationilla ei ole jaettua kansiota \"{sharedFolder}\". Onko se varmasti määritetty oikein?", "DownloadClientDownloadStationValidationSharedFolderMissing": "Jaettua kansiota ei ole olemassa", - "DownloadClientFloodSettingsAddPaused": "Lisää pysäytettynä", + "DownloadClientFloodSettingsAddPaused": "Lisää keskeytettynä", "DownloadClientFloodSettingsAdditionalTags": "Lisätunnisteet", - "DownloadClientFloodSettingsPostImportTagsHelpText": "Sisällyttää tunnisteet kun lataus on tuotu.", + "DownloadClientFloodSettingsPostImportTagsHelpText": "Lisää tunnisteet kun lataus on tuotu.", "DownloadClientFloodSettingsStartOnAdd": "Käynnistä lisättäessä", - "DownloadClientFloodSettingsUrlBaseHelpText": "Lisää etuliitteen Flood-rajapintaan (esim. {url}).", + "DownloadClientFloodSettingsUrlBaseHelpText": "Lisää Flood-rajapintaan etuliitteen, esim. \"{url}\".", "DownloadClientFreeboxApiError": "Freebox-rajapinta palautti virheen: {errorDescription}", - "DownloadClientFreeboxSettingsApiUrl": "Rajapinnan URL-osoite", - "DownloadClientFreeboxAuthenticationError": "Freebox API -todennus epäonnistui. Syy: {errorDescription}.", + "DownloadClientFreeboxSettingsApiUrl": "Rajapinnan URL", + "DownloadClientFreeboxAuthenticationError": "Freebox API -todennus epäonnistui. {errorDescription}.", "DownloadClientFreeboxNotLoggedIn": "Ei kirjautunut", "DownloadClientFreeboxSettingsAppId": "Sovellustunniste", "DownloadClientFreeboxSettingsAppIdHelpText": "Freebox-rajapinnan käyttöoikeutta määritettäessä käytettävä App ID -sovellustunniste.", "DownloadClientFreeboxSettingsAppToken": "Sovellustietue", "DownloadClientFreeboxSettingsAppTokenHelpText": "Freebox-rajapinnan käyttöoikeutta määritettäessä saatu app_token-tietue.", "DownloadClientFreeboxSettingsHostHelpText": "Freeboxin isäntänimi tai IP-osoite. Oletus on \"{url}\" (toimii vain samassa verkossa).", - "DownloadClientFreeboxUnableToReachFreebox": "Freebox-rajapintaa ei tavoiteta. Tarkista \"Osoite\"-, \"Portti\"- ja \"Käytä SSL-salausta\"-asetukset. Virhe: {exceptionMessage}.", - "DownloadClientFreeboxSettingsPortHelpText": "Freebox-liittymän portti. Oletus on \"{port}\".", - "DownloadClientNzbgetSettingsAddPausedHelpText": "Tämä vaatii vähintään NzbGet-version 16.0.", + "DownloadClientFreeboxUnableToReachFreebox": "Freebox-rajapintaan ei voida muodostaa yhteyttä. Tarkista \"Osoite\"-, \"Portti\"- ja \"Käytä SSL-salausta\"-asetukset. Virhe: {exceptionMessage}.", + "DownloadClientFreeboxSettingsPortHelpText": "Freebox-liittymän portti. Oletus on {port}.", + "DownloadClientNzbgetSettingsAddPausedHelpText": "Tämä vaatii vähintään NzbGetin version 16.0.", "DownloadClientNzbgetValidationKeepHistoryOverMax": "NzbGetin \"KeepHistory\"-asetuksen tulee olla pienempi kuin 25000.", "DownloadClientNzbgetValidationKeepHistoryZero": "NzbGetin \"KeepHistory\"-asetuksen tulee olla suurempi kuin 0.", "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "NzbGetin \"KeepHistory\"-asetus on liian korkea.", - "DownloadClientNzbgetValidationKeepHistoryZeroDetail": "NzbGetin \"KeepHistory\"-asetus on 0 ja tämä estää {appName}ia näkemästä valmistuneita latauksia.", + "DownloadClientNzbgetValidationKeepHistoryZeroDetail": "NzbGetin \"KeepHistory\"-asetus on \"0\", joka estää {appName}ia näkemästä valmistuneita latauksia.", "DownloadClientPneumaticSettingsNzbFolder": "NZB-kansio", - "DownloadClientPneumaticSettingsNzbFolderHelpText": "Tämän kansion on oltava tavoitettavissa XBMC:stä.", + "DownloadClientPneumaticSettingsNzbFolderHelpText": "Tämän kansion on oltava Kodin tavoitettavissa.", "DownloadClientPneumaticSettingsStrmFolder": "Strm-kansio", "DownloadClientPneumaticSettingsStrmFolderHelpText": "Tämän kansion .strm-tiedostot tuodaan droonilla.", "DownloadClientQbittorrentSettingsInitialStateHelpText": "Tila, jossa torrentit lisätään qBittorrentiin. Huomioi, että pakotetut torrentit eivät noudata nopeusrajoituksia.", "DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent ei voi selvittää magnet-linkkejä, jos DHT ei ole käytössä.", "DownloadClientQbittorrentTorrentStateError": "qBittorrent ilmoittaa virheestä", "DownloadClientQbittorrentTorrentStateMetadata": "qBittorrent lataa metatietoja", - "DownloadClientQbittorrentTorrentStatePathError": "Tuonti ei onnistu. Tiedostosijainti vastaa lataustyökalun perussijaintia. Ehkä \"Säilytä ylätason kansio\" ei ole käytössä tälle torrentille tai \"Torrentin sisällön asettelu\" -asetuksena EI OLE \"Alkuperäinen\" tai \"Luo alikansio\"?", + "DownloadClientQbittorrentTorrentStatePathError": "Tuonti ei onnistu. Tiedostosijainti vastaa latauspalvelun latauskansiota. Ehkä \"Säilytä ylätason kansio\" ei ole käytössä tälle torrentille tai \"Torrentin sisällön asettelu\" -asetuksena EI OLE \"Alkuperäinen\" tai \"Luo alikansio\"?", "DownloadClientQbittorrentTorrentStateUnknown": "Tuntematon lataustila: {state}", "DownloadClientQbittorrentValidationQueueingNotEnabled": "Jonotus ei ole käytössä", "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent on määritetty poistamaan torrentit niiden saavuttaessa niitä koskevan jakosuhderajoituksen.", "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName} ei voi suorittaa valmistuneiden latausten hallintaa määritetyllä tavalla. Voit korjata tämän vaihtamalla qBittorentin asetusten \"BitTorrent\"-osion \"Jakosuhderajoitukset\"-osion toiminnoksi pysäytyksen poiston sijaan.", "DownloadClientRTorrentSettingsAddStopped": "Lisää pysäytettynä", "DownloadClientRTorrentSettingsUrlPath": "URL-sijainti", - "DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd:n develop-versio, oletettavasti vähintään versio 3.0.0.", + "DownloadClientSabnzbdValidationDevelopVersion": "SABnzb:n develop-versio, oletettavasti vähintään versio 3.0.0.", "DownloadClientSabnzbdValidationEnableDisableDateSorting": "Älä järjestele päiväyksellä", "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Älä järjestele elokuvia", "DownloadClientSabnzbdValidationEnableDisableTvSorting": "Älä järjestele sarjoja", "DownloadClientSabnzbdValidationUnknownVersion": "Tuntematon versio: {rawVersion}", - "DownloadClientTransmissionSettingsUrlBaseHelpText": "Lisää etuliite lataustyökalun {clientName} RPC-URL-osoitteeseen. Esimerkiksi {url}. Oletus on \"{defaultUrl}\".", - "DownloadClientTransmissionSettingsDirectoryHelpText": "Vaihtoehtoinen latauskansio. Käytä Transmissionin oletusta jättämällä tyhjäksi.", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "Lisää latauspalvelun {clientName} RPC-URL-osoitteeseen etuliitteen, esim. \"{url}\". Oletus on \"{defaultUrl}\".", + "DownloadClientTransmissionSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Transmissionin oletusta jättämällä tyhjäksi.", "DownloadClientUTorrentTorrentStateError": "uTorrent ilmoittaa virheestä", "DownloadClientValidationApiKeyIncorrect": "Rajapinnan avain ei kelpaa", "DownloadClientValidationApiKeyRequired": "Rajapinnan avain on pakollinen", @@ -1625,7 +1625,7 @@ "DownloadStationStatusExtracting": "Puretaan: {progress} %", "Menu": "Valikko", "SecretToken": "Salainen tunniste", - "TorrentBlackholeSaveMagnetFilesExtension": "Tallennettujen magnet-tiedostojen pääte", + "TorrentBlackholeSaveMagnetFilesExtension": "Tallenna magnet-tiedostojen pääte", "TorrentBlackholeSaveMagnetFiles": "Tallenna magnet-tiedostot", "TorrentBlackhole": "Torrent Blackhole", "TorrentBlackholeTorrentFolder": "Torrent-kansio", @@ -1640,12 +1640,12 @@ "RestartRequiredWindowsService": "Jotta palvelu käynnistyisi automaattisesti, voi suorittavasta käyttäjästä riippuen olla tarpeellista suorittaa {appName} kerran järjestelmänvalvojan oikeuksilla.", "MediaInfoFootNote": "MediaInfo Full, AudioLanguages ja SubtitleLanguages tukevat \":EN+FI\"-tyylisiä jälkiliitteitä, joiden avulla tiedostonimeen voidaan lisätä videon sisältämiä kieliä. \"-\" ohittaa tietyt kielet (esim. \"-EN\") ja \"+\"-pääte (esim. \":FI+\") tuottaa ohitettavista kielistä riippuen \"[FI]\", \"[FI+--]\" tai \"[--]\". Esimerkiksi \"{MediaInfo Full:FI+EN}\".", "DownloadClientDownloadStationValidationFolderMissing": "Kansiota ei ole olemassa", - "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Sinun on kirjauduttava Diskstationillesi tunnuksella {username} ja määritettävä se manuaalisesti Download Stationin \"BT/HTTP/FTP/NZB > Location\" -asetuksiin.", + "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Sinun on kirjauduttava Diskstationillesi tunnuksella {username} ja määritettävä se manuaalisesti Download Stationin asetusten kohtaan \"BT/HTTP/FTP/NZB\" > \"Location\".", "DownloadClientFloodSettingsRemovalInfo": "{appName} suorittaa torrenttien automaattisen poiston sen tietolähdeastuksissa määritettyjen jakoasetusten perusteella.", - "DownloadClientFloodSettingsTagsHelpText": "Latauksen alkuperäiset tunnisteet. Jotta se voidaa tunnistaa, on latauksella oltava sen alkuperäiset tunnisteet. Tämä välttää ristiriidat muiden latausten kanssa.", - "OrganizeRelativePaths": "Kaikki tiedostosijainnit on suhtetuttu sijaintiin: \"{path}\".", + "DownloadClientFloodSettingsTagsHelpText": "Latauksen alkuperäiset tunnisteet, jotka tarvitaan sen tunnistamiseen. Tämä välttää ristiriidat muiden latausten kanssa.", + "OrganizeRelativePaths": "Kaikki tiedostosijainnit on suhteutettu sijaintiin: \"{path}\".", "PopularityIndex": "Tämänhetkinen suosioarvo", - "NotificationsTagsMovieHelpText": "Ilmoita vain elokuvista, jotka on merkitty ainakin yhdellä vastaavalla tunnisteella.", + "NotificationsTagsMovieHelpText": "Ilmoita vain elokuvista, jotka on merkitty ainakin yhdellä täsmäävällä tunnisteella.", "OptionalName": "Valinnainen nimi", "OneMinute": "1 minuutti", "Period": "Piste", @@ -1654,7 +1654,7 @@ "WantMoreControlAddACustomFormat": "Haluatko hallita tarkemmin mitä latauksia suositaan? Lisää [Mukautettu muoto](/settings/customformats).", "NoExtraFilesToManage": "Hallittavia oheistiedostoja ei ole.", "NoMovieFilesToManage": "Hallittavia elokuvatiedostoja ei ole.", - "TorrentBlackholeSaveMagnetFilesHelpText": "Tallenna magnet-linkki, jos .torrent-tiedostoa ei ole käytettävissä (hyödyllinen vain lataustyökalun tukiessa tiedostoon tallennettuja magnet-linkkejä).", + "TorrentBlackholeSaveMagnetFilesHelpText": "Tallenna magnet-linkki, jos .torrent-tiedostoa ei ole käytettävissä (hyödyllinen vain latauspalvelun tukiessa tiedostoon tallennettuja magnet-linkkejä).", "QualityCutoffNotMet": "Laadun katkaisutasoa ei ole saavutettu", "Space": "Välilyönti", "Underscore": "Alaviiva", @@ -1676,16 +1676,16 @@ "DeleteReleaseProfileMessageText": "Haluatko varmasti poistaa julkaisuprofiilin \"{name}\"?", "DeleteSpecification": "Poista määritys", "DeleteSpecificationHelpText": "Haluatko varmasti poistaa määrityksen \"{name}\"?", - "DownloadClientValidationTestNzbs": "NZB-listausten nouto epäonnistui: {exceptionMessage}.", - "DownloadClientValidationTestTorrents": "Torrent-listausten nouto epäonnistui: {exceptionMessage}.", - "DownloadClientFreeboxSettingsApiUrlHelpText": "Määritä Freebox-rajapinnan perus-URL rajapinnan versiolla. Esimerkiksi \"{url}\". Oletus on \"{defaultApiUrl}\".", - "DownloadClientFreeboxUnableToReachFreeboxApi": "Freebox-rajapintaa ei tavoiteta. Tarkista \"Rajapinnan URL-osoite\" -asetuksen perus-URL ja versio.", + "DownloadClientValidationTestNzbs": "NZB-listauksen nouto epäonnistui: {exceptionMessage}.", + "DownloadClientValidationTestTorrents": "Torrent-listauksen nouto epäonnistui: {exceptionMessage}.", + "DownloadClientFreeboxSettingsApiUrlHelpText": "Määritä Freebox-rajapinnan perus-URL rajapinnan versiolla, esim. \"{url}\". Oletus on \"{defaultApiUrl}\".", + "DownloadClientFreeboxUnableToReachFreeboxApi": "Freebox-rajapintaan ei voida muodostaa yhteyttä. Tarkista \"Rajapinnan URL\" -asetuksen perus-URL ja versio.", "DownloadClientNzbVortexMultipleFilesMessage": "Lataus sisältää useita tiedostoja, eikä se ole työkansiossa: {outputPath}.", "HourShorthand": "t", "Example": "Esimerkki", "EditReleaseProfile": "Muokkaa julkaisuprofiilia", "EnableProfileHelpText": "Käytä julkaisuprofiilia merkitsemällä tämä.", - "DownloadClientValidationUnableToConnect": "Lataustyökalua {clientName} ei tavoitettu", + "DownloadClientValidationUnableToConnect": "Latauspalveluun {clientName} ei voida muodostaa yhteyttä", "No": "Ei", "NoDelay": "Ei viivettä", "MustNotContainHelpText": "Julkaisu hylätään, jos se sisältää yhden tai useampia näistä termeistä (kirjainkoolla ei ole merkitystä).", @@ -1697,72 +1697,178 @@ "Release": "Julkaisu", "RegularExpressionsTutorialLink": "Lisätietoja säännöllisistä lausekkeista löytyy [täältä]({url}).", "ReleaseProfileIndexerHelpText": "Määritä mitä tietolähdettä profiili koskee.", - "ReleaseProfileTagMovieHelpText": "Julkaisuprofiileja sovelletaan elokuviin, jotka on merkitty ainakin yhdellä vastaavalla tunnisteella. Käytä kaikille elokuville jättämällä tyhjäksi.", + "ReleaseProfileTagMovieHelpText": "Julkaisuprofiileja sovelletaan elokuviin, jotka on merkitty ainakin yhdellä täsmäävällä tunnisteella. Käytä kaikille elokuville jättämällä tyhjäksi.", "SearchMoviesOnAdd": "Etsi elokuvia kun ne lisätään", - "ClickToChangeIndexerFlags": "Vaihda tietolähteen lippuja painamalla tästä", + "ClickToChangeIndexerFlags": "Muuta tietolähteen lippuja painamalla tästä", "CustomFormatsSpecificationFlag": "Lippu", "SelectIndexerFlags": "Valitse tietolähteen liput", - "SetIndexerFlagsModalTitle": "{modalTitle} - Aseta tietolähteen liput", - "CustomFilter": "Oma suodatin", + "SetIndexerFlagsModalTitle": "{modalTitle} – Aseta tietolähteen liput", + "CustomFilter": "Mukautettu suodatin", "Label": "Nimi", "LabelIsRequired": "Nimi on pakollinen", "SetIndexerFlags": "Aseta tietolähteen liput", "Lists": "Listat", "External": "Ulkoinen", - "MissingLoadError": "Virhe ladattaessa puuttuvia kohteita", + "MissingLoadError": "Virhe ladattaessa puuttuvia kohteita.", "IncludeHealthWarnings": "Sisällytä kuntovaroitukset", "AutoTaggingSpecificationTag": "Tunniste", "CutoffUnmetLoadError": "Virhe ladattaessa katkaisutasoa saavuttamattomia kohteita", - "CutoffUnmetNoItems": "Katkaisutasoa saavuttamattomia kohteita ei ole.", - "DownloadClientDelugeSettingsDirectoryHelpText": "Valinnainen latuasten tallennussijainti. Käytä Aria2-oletusta jättämällä tyhjäksi.", - "DownloadClientVuzeValidationErrorVersion": "Protokollan versiota ei tueta. Käytä vähintään Vuze-versiota 5.0.0.0 sekä Vuze Web Remote -lisäosaa.", - "MassSearchCancelWarning": "Tätä ei ole mahdollista pysäyttää kuin käynnistämällä {appName}ia uudelleen tai poistamalla kaikki tietolähteet käytöstä.", - "MissingNoItems": "Puuttuvia kohteita ei ole.", + "CutoffUnmetNoItems": "Katkaisutasoa saavuttamattomia kohteita ei ole", + "DownloadClientDelugeSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Delugen oletusta jättämällä tyhjäksi.", + "DownloadClientVuzeValidationErrorVersion": "Protokollaversiota ei tueta. Käytä vähintään Vuzen versiota 5.0.0.0 Vuze Web Remote -lisäosan kanssa.", + "MassSearchCancelWarning": "Tämä on mahdollista keskeyttää vain käynnistämällä {appName} uudelleen tai poistamalla kaikki tietolähteet käytöstä.", + "MissingNoItems": "Puuttuvia kohteita ei ole", "MonitorSelected": "Valvo valittuja", "UnmonitorSelected": "Lopeta valittujen valvonta", - "DownloadClientValidationErrorVersion": "{clientName} version tulee olla vähintään {requiredVersion}. Ilmoitettu versio on {reportedVersion}.", - "AddListExclusion": "Lisää tuontilistojen poikkeussääntö", - "DownloadClientRTorrentSettingsDirectoryHelpText": "Valinnainen latuasten tallennussijainti. Käytä Aria2-oletusta jättämällä tyhjäksi.", - "ConnectionSettingsUrlBaseHelpText": "Lisää etuliite lataustuökalun {clientName} URL-osoitteeseen, kuten {url}.", - "UrlBaseHelpText": "Lisää {appName}in URL-osoitteeseen jälkiliitteen, esim. \"http://[osoite]:[portti]/[URL-perusta]\". Oletusarvo on tyhjä.", - "IndexerSettingsMultiLanguageRelease": "Monikielinen", + "DownloadClientValidationErrorVersion": "Latauspalvelun {clientName} version tulee olla vähintään {requiredVersion}. Ilmoitettu versio on {reportedVersion}.", + "AddListExclusion": "Lisää listapoikkeus", + "DownloadClientRTorrentSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä rTorrentin oletusta jättämällä tyhjäksi.", + "ConnectionSettingsUrlBaseHelpText": "Lisää palvelimen {connectionName} URL-osoitteeseen etuliitteen, esim. \"{url}\".", + "UrlBaseHelpText": "Käänteisen välityspalvelimen tukea varten. Oletusarvo on tyhjä.", + "IndexerSettingsMultiLanguageRelease": "Useat kielet", "IndexerSettingsSeedRatio": "Jakosuhde", - "IndexerSettingsSeedRatioHelpText": "Suhde, joka torrentin tulee saavuttaa ennen sen pysäytystä. Käytä lataustyökalun oletusta jättämällä tyhjäksi. Suhteen tulisi olla ainakin 1.0 ja noudattaa tietolähteen sääntöjä.", + "IndexerSettingsSeedRatioHelpText": "Suhde, joka torrentin tulee saavuttaa ennen sen pysäytystä. Käytä latauspalvelun oletusta jättämällä tyhjäksi. Suhteen tulisi olla ainakin 1.0 ja noudattaa tietolähteen sääntöjä.", "IndexerSettingsSeedTime": "Jakoaika", - "IndexerSettingsSeedTimeHelpText": "Aika, joka torrentia tulee jakaa ennen sen pysäytystä. Käytä lataustyökalun oletusta jättämällä tyhjäksi.", - "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Valinnainen latuasten tallennussijainti. Käytä Aria2-oletusta jättämällä tyhjäksi.", + "IndexerSettingsSeedTimeHelpText": "Aika, joka torrentia tulee jakaa ennen sen pysäytystä. Käytä latauspalvelun oletusta jättämällä tyhjäksi.", + "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Vaihtoehtoinen sijainti, johon valmistuneet lataukset siirretään. Käytä Delugen oletusta jättämällä tyhjäksi.", "MovieIsNotMonitored": "Elokuvaa ei valvota", - "SearchForAllMissingMovies": "Etsi kaikkia puuttuvia kirjoja", - "SearchForAllMissingMoviesConfirmationCount": "Haluatko varmasti etsiä '{0}' puuttuvaa albumia?", - "DownloadClientValidationGroupMissingDetail": "Syötettyä kategoriaa ei ole lautaustyökalussa {clientName}. Luo se sinne ensin.", - "SearchForCutoffUnmetMovies": "Etsi kaikkia kirjoja, joiden katkaisutasoa ei ole savutettu", - "SearchForCutoffUnmetMoviesConfirmationCount": "Haluatko varmasti etsiä kaikkia {totalRecords} katkaisutasoa saavuttamattomia jaksoja?", + "SearchForAllMissingMovies": "Etsi kaikkia puuttuvia elokuvia", + "SearchForAllMissingMoviesConfirmationCount": "Haluatko varmasti etsiä kaikkia {totalRecords} puuttuvaa elokuvaa?", + "DownloadClientValidationGroupMissingDetail": "Syötettyä ryhmää ei ole lautaustyökalussa {clientName}. Luo se sinne ensin.", + "SearchForCutoffUnmetMovies": "Etsi kaikkia elokuvia, joiden katkaisutasoa ei ole savutettu", + "SearchForCutoffUnmetMoviesConfirmationCount": "Haluatko varmasti etsiä kaikkia {totalRecords} elokuvaa, joiden katkaisutasoa ei ole saavutettu?", "DeleteMovieFolderCountConfirmation": "Haluatko varmasti poistaa {count} valitun elokuvan/valittua elokuvaa?", "DeleteMovieFolderCountWithFilesConfirmation": "Haluatko varmasti poistaa {count} valitun elokuvan/valittua elokuvaa sisältöineen?", "DeleteMovieFolders": "Poista elokuvakansiot", "DeleteMovieFoldersHelpText": "Poista elokuvakansiot sisältöineen", "DeleteSelectedMovies": "Poista valitut elokuvat", "NotificationsPlexSettingsServer": "Palvelin", - "Any": "Mikä vain", + "Any": "Mikä tahansa", "DeleteSelected": "Poista valitut", - "DeleteSelectedImportListExclusionsMessageText": "Haluatko varmasti poistaa tuontilistapoikkeuksen?", + "DeleteSelectedImportListExclusionsMessageText": "Haluatko varmasti poistaa valitut tuontilistapoikkeukset?", "ProgressBarProgress": "Tilapalkissa {progress} %", - "DeleteSelectedCustomFormatsMessageText": "Haluatko varmasti poistaa valitut {count} tuontilistaa?", - "DeleteSelectedCustomFormats": "Poista mukautettu muoto", - "ReleaseDate": "Julkaisupäivät", - "ShowDigitalRelease": "Näytä teatterijulkaisu", - "ShowDigitalReleaseHelpText": "Näytä teatterijulkaisun päiväys julisteen alla.", - "ShowPhysicalRelease": "Fyysinen julkaisu", - "ShowPhysicalReleaseHelpText": "Näytä teatterijulkaisun päiväys julisteen alla.", + "DeleteSelectedCustomFormatsMessageText": "Haluatko varmasti poistaa valitut {count} mukautettua muotoa?", + "DeleteSelectedCustomFormats": "Poista mukautetut muodot", + "ReleaseDate": "Julkaisupäivä", + "ShowDigitalRelease": "Näytä julkaisupäivä (digitaalinen)", + "ShowDigitalReleaseHelpText": "Näytä digitaalijulkaisun päiväys julisteen alla.", + "ShowPhysicalRelease": "Näytä julkaisupäivä (fyysinen)", + "ShowPhysicalReleaseHelpText": "Näytä fyysisen julkaisun päiväys julisteen alla.", "Logout": "Kirjaudu ulos", - "ShowTraktRatingPosterHelpText": "Näytä Tomato-arvio julisteen alla.", - "SmartReplaceHint": "Yhdysmerkki tai välilyönti nimen perusteella", - "FolderNameTokens": "Tiedostonimen muuttujat", + "ShowTraktRatingPosterHelpText": "Näytä Trakt-arvio julisteen alla.", + "SmartReplaceHint": "\"Yhdysmerkki\" tai \"Välilyönti Yhdysmerkki\" nimen perusteella.", + "FolderNameTokens": "Kansionimimuuttujat", "DefaultNotFoundMessage": "Lienet eksyksissä, koska täällä ei ole mitään nähtävää.", "ToggleMonitoredToUnmonitored": "Valvotaan (lopeta painamalla)", "ToggleUnmonitoredToMonitored": "Ei valvota (aloita painamalla)", "FileBrowser": "Tiedostoselain", - "Completed": "Kokonaiset", + "Completed": "Katseltu", "Delay": "Viive", - "DownloadClientUnavailable": "Lataustyökalu ei ole käytettävissä" + "DownloadClientUnavailable": "Latauspalvelu ei ole käytettävissä", + "AnnouncedMovieAvailabilityDescription": "Elokuvien käsitellään saatavilla olevina heti kun ne on lisätty {appName}iin.", + "Recommended": "Suositeltu", + "ReleaseProfileIndexerHelpTextWarning": "Jos julkaisuprofiilille määritetään tietty tietolähde, koskee se vain kyseisen tietolähteen julkaisuja.", + "ShowTagsHelpText": "Näytä tunnisteet julisteen alla.", + "NotificationsTelegramSettingsMetadataLinks": "Metatietolinkit", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Ilmoituksiin voidaan tarvittaessa sisällyttää instannin nimi.", + "OnFileImport": "Kun tiedosto tuodaan", + "OnFileUpgrade": "Kun tiedosto päivitetään", + "SmartReplace": "Älykäs korvaus", + "YesterdayAt": "Eilen klo {time}", + "Fallback": "Varmistus", + "FavoriteFolderAdd": "Lisää suosikkikansio", + "FavoriteFolderRemove": "Poista suosikkikansio", + "FavoriteFolders": "Suosikkikansiot", + "MetadataSettingsMovieImages": "Elokuvien kuvitukset", + "MetadataSettingsMovieMetadataLanguage": "Elokuvien metatietojen kieli", + "BlocklistFilterHasNoItems": "Valitulla estolistasuodattimella ei löydy kohteita", + "IncludeTrendingMoviesHelpText": "Sisällytä TMDB:n nousussa olevat elokuvat", + "CustomFormatsSettingsTriggerInfo": "Mukautettua muotoa sovelletaan julkaisuun tai tiedostoon, kun ainakin yksi valituista ehtotyypeistä täsmää.", + "CustomFormatsSpecificationExceptLanguageHelpText": "Täsmää, jos havaitaan mikä tahansa muu kuin valittu kieli.", + "DownloadClientRTorrentSettingsAddStoppedHelpText": "Tämä lisää torrentit ja magnet-linkit rTorentiin pysäytetyssä tilassa. Tämä saattaa rikkoa margnet-tiedostot.", + "DownloadClientRTorrentProviderMessage": "rTorrent ei pysäytä torrenteja niiden saavuttaessa jakomääritykset. {appName} suorittaa tietolähdeasetusten jakomäärityksiin perustuvan torrentien automaattisen poiston vain \"Poista valmistuneet\" -asetuksen ollessa käytössä. Tuonnin jälkeen se asettaa näkymän {importedView} rTorrent-näkymäksi, jota voidaan käyttää rTorrentin komentosarjojen kanssa.", + "DownloadClientRTorrentSettingsUrlPathHelpText": "Polku XMLRPC-päätteeseen, ks. \"{url}\". Käytettäessä ruTorrentia tämä on yleensä RPC2 tai [ruTorrentin sijainti]{url2}.", + "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "\"Tarkista ennen lataamista\" vaikuttaa {appName}in kykyyn valvoa uusia latauksia. Lisäksi SABnzb suosittelee tämän sijaan \"Peru lataukset, jotka eivät voi valmistua\" -asetusta, koska se on varmatoimisempi.", + "DownloadClientValidationAuthenticationFailureDetail": "Vahvista käyttäjätunnuksesi ja salasanasi. Varmista myös, ettei latauspalveluun {clientName} ole määritetty sääntöjä, jotka estävät {appName}in suorittavaa laitetta tavoittamasta sitä.", + "InvalidMovieInfoLanguageLanguage": "Elokuvatietojen kieliasetus on virheellinen. Korjaa se ja tallenna asetukset.", + "EditionFootNote": "Vaihtoehtoisesti voit hallita lyhennystä tavujen enimmäismäärän perusteella, ellipsi (...) mukaan lukien. Sekä lyhennystä lopusta (esim. \"{versiotunnisteet:30}\"), että alusta (esim. \"{versiotunnisteet:-30}\") tuetaan.", + "EditSelectedCustomFormats": "Muokkaa valittuja mukautettuja muotoja", + "MetadataXmbcSettingsMovieMetadataHelpText": "Elokuvien täydelliset metatiedot tallennetaan .nfo-tiedostoihin.", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Lisää lähetettäviin ilmoituksiin linkit elokuvien metatietoihin.", + "NotificationsTelegramSettingsIncludeInstanceName": "Sisällytä instanssin nimi otsikkoon", + "SkipFreeSpaceCheckHelpText": "Käytä, kun {appName} ei kykene tunnistamaan juurikansiosi käytettävissä olevaa vapaata tallennustilaa.", + "UnableToImportAutomatically": "Automaattinen tuonti ei onnistu", + "DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent ilmoittaa puuttuvista tiedostoista", + "ExistsInLibrary": "On jo kirjastossa", + "TodayAt": "Tänään klo {time}", + "IndexerSettingsMultiLanguageReleaseHelpText": "Mitkä kielet tämän tietolähteen monikielisiin julkaisuihin yleensä sisältyvät?", + "CountCustomFormatsSelected": "{count} mukautettu(a) muoto(a) on valittu", + "Install": "Asenna", + "InstallMajorVersionUpdate": "Asenna päivitys", + "InstallMajorVersionUpdateMessage": "Tämä päivitys asentaa uuden pääversion, joka ei välttämättä ole yhteensopiva laitteistosi kanssa. Haluatko varmasti asentaa päivityksen?", + "InstallMajorVersionUpdateMessageLink": "Saat lisätietoja osoitteesta [{domain}]({url}).", + "InteractiveSearchModalHeaderTitle": "Manuaalihaku – {title}", + "InCinemasMovieAvailabilityDescription": "Elokuvia käsitellään saatavilla olevina heti kun ne on julkaistu teattereissa.", + "LogSizeLimit": "Lokin kokorajoitus", + "LogSizeLimitHelpText": "Lokitiedoston enimmäiskoko ennen pakkausta. Oletusarvo on 1 Mt.", + "IncludePopular": "Sisällytä suositut", + "IncludePopularMoviesHelpText": "Sisällytä TMDB:n suositut elokuvat", + "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} toivoo jokaisen latauksen olevan omassa kansiossaan. Jos kansioon/polkuun lisätään tähtimerkki (*) SABnzbd ei luo näitä työkansioita. Korjaa tämä SABnzb:stä.", + "DownloadClientValidationSslConnectFailure": "Salattua SSL-yhteyttä ei voida muodostaa", + "TraktVotes": "Trakt-äänet", + "DayOfWeekAt": "{day} klo {time}", + "DeleteMovieFolderMovieCount": "{movieFileCount} elokuvatiedostoa, kooltaan yhteensä {size}.", + "DownloadClientDelugeSettingsDirectoryCompleted": "Kansio, johon valmistuneet siirretään", + "Popular": "Suosittu", + "DownloadClientSabnzbdValidationDevelopVersionDetail": "Kehitysversioita käytettäessä {appName} ei välttämättä tue SABnzbd:n uusia ominaisuuksia.", + "DownloadClientDelugeSettingsDirectory": "Latauskansio", + "ManageCustomFormats": "Hallitse mukautettuja muotoja", + "MovieDownloaded": "Elokuva on ladattu", + "NewNonExcluded": "Uusi ei-ohitettava", + "NoCustomFormatsFound": "Mukautettuja muotoja ei löytynyt", + "DownloadClientSabnzbdValidationCheckBeforeDownload": "Poista SABnbzd:n \"Tarkista ennen lataamista\" -asetus käytöstä", + "DownloadClientValidationSslConnectFailureDetail": "{appName} ei voi muodostaa salattua SSL-yhteyttä latauspalveluun {clientName}. Tämä voi olla laitekohtainen ongelma. Kokeile muodostaa yhteys määrittämällä {appName} ja latauspalvelu {clientName} käyttämään suojaamatonta yhteyttä.", + "IncludeTrending": "Sisällytä nuosevat", + "MetadataKometaDeprecated": "Kometa-tiedostoja ei enää luoda ja tuki poistuu täysin versiossa 6.", + "MetadataKometaDeprecatedSetting": "Poistunut", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Sisällytä elokuvan TMDB- ja IMDb-osoitteet .nfo-tiedostoon.", + "MinimumCustomFormatScoreIncrement": "Pienin mahdollinen mukautetun muodon pisteytyksen korotus", + "MinimumCustomFormatScoreIncrementHelpText": "Pienin vaadittu olemassa olevien ja uusien julkaisujen välinen mukautetun muodon pisteytyksen korotus ennen kuin {appName} tulkitsee julkaisun päivitykseksi.", + "MovieFootNote": "Vaihtoehtoisesti voit hallita lyhennystä tavujen enimmäismäärän perusteella, ellipsi (...) mukaan lukien. Sekä lyhennystä lopusta (esim. \"{Elokuvan nimi:30}\"), että alusta (esim. \"{Elokuvan nimi:-30}\") tuetaan.", + "MovieIsNotAvailable": "Elokuva ei ole saatavilla", + "NoBlocklistItems": "Estettyjä kohteita ei ole", + "NoMovieReleaseDatesAvailable": "Elokuvalle ei löydy julkaisupäiviä [TMDb:stä]({url}).", + "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Lisää ilmoituksiin linkit elokuvien metatietoihin.", + "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Metatietolinkki alustoille vain yhtä linkkiä tukeville alustoille.", + "NotificationsPlexSettingsServerHelpText": "Valitse tunnistautumisen jälkeen palvelin Plex.tv-tililtä.", + "NotificationsSettingsWebhookHeaders": "Otsakkeet", + "NotificationsTelegramSettingsIncludeAppName": "Sisällytä {appName} otsikkoon", + "NotificationsTelegramSettingsIncludeAppNameHelpText": "Ilmoitukset voidaan tarvittaessa erottaa muista sovelluksista lisäämällä niiden eteen \"{appName}\".", + "NzbgetHistoryItemMessage": "PAR-tila: {parStatus} – Purun tila: {unpackStatus} - Siirron tila: {moveStatus} – Komentosarjan tila: {scriptStatus} – Poiston tila: {deleteStatus} – Merkinnän tila: {markStatus}", + "Recommendation": "Suositus", + "ReleaseGroupFootNote": "Vaihtoehtoisesti voit hallita lyhennystä tavujen enimmäismäärän perusteella, ellipsi (...) mukaan lukien. Sekä lyhennystä lopusta (esim. \"{Julkaisuryhmä:30}\"), että alusta (esim. \"{Julkaisuryhmä:-30}\") tuetaan.", + "ReleasedMovieAvailabilityDescription": "Elokuvia käsitellään saatavilla olevina heti kun ne on julkaistu Blu-rayllä tai suoratoistossa.", + "MovieMissingFromDisk": "Elokuvaa ei ole levyllä", + "ShowTags": "Näytä tunnisteet", + "TomorrowAt": "Huomenna klo {time}", + "TraktRating": "Trakt-arvio", + "Trending": "Nousussa", + "Warning": "Varoitus", + "LastSearched": "Edellinen haku", + "OnExcludedList": "Ohitettavien listalla", + "MetadataSettingsMovieMetadata": "Elokuvien metatiedot", + "MetadataSettingsMovieMetadataCollectionName": "Elokuvakokoelman nimi", + "MetadataSettingsMovieMetadataUrl": "Elokuvien metatietojen URL", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Kokoelmien nimet tallennetaan .nfo-tiedostoihin.", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Sisällytä valittu kieli .nfo-tiedostoon (jos käytettävissä).", + "DownloadClientValidationVerifySslDetail": "Varmista SSL-asetuksesi latauspalvelusta {clientName} ja {appName}ista.", + "MetadataSettingsMovieMetadataNfo": "Käytä movie.nfo-tiedostoa", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Tallenna metatiedot oletusarvoisen \".nfo\"-tiedoston sijaan \"movie.nfo\"-tiedostoon.", + "CustomFormatsSpecificationExceptLanguage": "Paitsi kieli", + "CountVotes": "{votes} ääntä", + "ShowTraktRating": "Näytä Trakt-arviot", + "NotificationsGotifySettingsMetadataLinks": "Metatietolinkit", + "NotificationsGotifySettingsPreferredMetadataLink": "Ensisijainen metatietolinkki", + "ManageFormats": "Hallitse muotoja", + "Disposition": "Poikkeama" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 5a76364d2a..0b39d257c5 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -250,16 +250,16 @@ "Extension": "Extension", "CustomFormatScore": "Score du format personnalisé", "SystemTimeHealthCheckMessage": "L'heure du système est décalée de plus d'un jour. Les tâches planifiées peuvent ne pas s'exécuter correctement tant que l'heure ne sera pas corrigée", - "ShowMonitored": "Afficher le chemin", + "ShowMonitored": "Afficher l'état de surveillance", "WeekColumnHeaderHelpText": "Affiché au dessus de chaque colonne quand \"Semaine\" est l'affichage actif", "ShowRelativeDates": "Afficher les dates relatives", "OverviewOptions": "Options de présentation", "UnsavedChanges": "Modifications non enregistrées", "Table": "Tableau", - "ShowTitle": "Montrer le titre", + "ShowTitle": "Afficher le titre", "ShowStudio": "Afficher le studio", "ShowSizeOnDisk": "Afficher la taille sur le disque", - "ShowSearchHelpText": "Afficher le bouton de recherche au survol", + "ShowSearchHelpText": "Affiche le bouton de recherche au survol", "ShowSearch": "Afficher la recherche", "ShowQualityProfile": "Afficher le profil de qualité", "ShowPath": "Afficher le chemin", @@ -612,11 +612,11 @@ "ShowUnknownMovieItems": "Afficher les éléments de film inconnus", "ShowTitleHelpText": "Affiche le titre du film sous l'affiche", "ShowRatings": "Afficher les évaluations", - "ShowQualityProfileHelpText": "Afficher le profil de qualité sous l'affiche", + "ShowQualityProfileHelpText": "Affiche le profil de qualité sous l'affiche", "ShownClickToHide": "Affiché, cliquez pour masquer", - "ShowMovieInformationHelpText": "Afficher les genres de films et la certification", + "ShowMovieInformationHelpText": "Affiche les genres de film et la certification", "ShowMovieInformation": "Afficher les informations sur le film", - "ShowMonitoredHelpText": "Afficher l'état de surveillance sous le poster", + "ShowMonitoredHelpText": "Affiche l'état de surveillance sous le poster", "ShowGenres": "Afficher les genres", "IconForCutoffUnmetHelpText": "Afficher l'icône des fichiers lorsque la limite n'a pas été atteinte", "ShowCertification": "Afficher la certification", @@ -946,7 +946,7 @@ "YesMoveFiles": "Oui, déplacez les fichiers", "MoveFolders2": "Souhaitez-vous déplacer les fichiers vidéo de «{0}» vers «{1}» ?", "SqliteVersionCheckUpgradeRequiredMessage": "La version {0} de SQLite actuellement installée n'est plus prise en charge. Veuillez mettre à niveau SQLite vers au moins la version {1}.", - "ShowCinemaRelease": "Afficher la date de sortie du cinéma", + "ShowCinemaRelease": "Afficher la date de sortie au cinéma", "ShowReleaseDate": "Afficher la date de sortie", "ShowReleaseDateHelpText": "Affiche la date de sortie sous l'affiche", "OnMovieDelete": "À la suppression d'un film", @@ -1150,7 +1150,7 @@ "FormatShortTimeSpanHours": "{hours} heure(s)", "FormatRuntimeMinutes": "{minutes} m", "FormatShortTimeSpanSeconds": "{seconds} seconde(s)", - "ShowRottenTomatoesRatingHelpText": "Affiche la note Tomate sous l'affiche", + "ShowRottenTomatoesRatingHelpText": "Affiche la note Tomato sous l'affiche", "ListWillRefreshEveryInterval": "La liste se rafraîchira toutes les {refreshInterval}", "OverrideGrabNoMovie": "Un film doit être sélectionné", "OverrideGrabNoLanguage": "Au moins une langue doit être sélectionnée", @@ -1228,7 +1228,7 @@ "QueueLoadError": "Échec du chargement de la file d'attente", "RemoveSelectedBlocklistMessageText": "Êtes-vous sûr de vouloir supprimer les éléments sélectionnés de la liste de blocage ?", "RetryingDownloadOn": "Nouvelle tentative de téléchargement le {date} à {time}", - "ShowUnknownMovieItemsHelpText": "Afficher les éléments sans film dans la file d'attente. Cela peut inclure des films supprimés ou tout autre élément de la catégorie de {appName}", + "ShowUnknownMovieItemsHelpText": "Affiche les éléments sans film dans la file d'attente. Cela peut inclure des films supprimés ou tout autre élément de la catégorie de {appName}", "TablePageSize": "Taille de la page", "EditConditionImplementation": "Modifier la condition – {implementationName}", "EditConnectionImplementation": "Ajouter une condition - {implementationName}", @@ -1788,7 +1788,7 @@ "NotificationsPlexSettingsServerHelpText": "Sélectionnez le serveur à partir du compte plex.tv après l'authentification", "Any": "Tous", "ShowTags": "Afficher les labels", - "ShowTagsHelpText": "Afficher les labels sous l'affiche", + "ShowTagsHelpText": "Affiche les labels sous l'affiche", "DeleteSelected": "Supprimer la sélection", "DeleteSelectedImportListExclusionsMessageText": "Êtes-vous sûr de vouloir supprimer les exclusions de la liste d'importation sélectionnée ?", "ProgressBarProgress": "Barre de progression à {progress} %", @@ -1803,10 +1803,10 @@ "LogSizeLimit": "Limite de taille du journal", "LogSizeLimitHelpText": "Taille maximale du fichier journal en Mo avant archivage. La valeur par défaut est de 1 Mo.", "CountVotes": "{votes} votes", - "ShowDigitalRelease": "Afficher la date de sortie du cinéma", - "ShowDigitalReleaseHelpText": "Affiche la date de sortie au cinéma sous l'affiche", + "ShowDigitalRelease": "Afficher la date de sortie numérique", + "ShowDigitalReleaseHelpText": "Affiche la date de sortie numérique sous l'affiche", "ShowPhysicalRelease": "Date de sortie physique", - "ShowPhysicalReleaseHelpText": "Affiche la date de sortie au cinéma sous l'affiche", + "ShowPhysicalReleaseHelpText": "Affiche la date de sortie physique sous l'affiche", "DayOfWeekAt": "{day} à {time}", "TodayAt": "Aujourd'hui à {time}", "TomorrowAt": "Demain à {time}", @@ -1815,7 +1815,7 @@ "NoBlocklistItems": "Aucun élément de la liste de blocage", "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications", "NotificationsGotifySettingsMetadataLinks": "Liens de métadonnées", - "ShowTraktRatingPosterHelpText": "Affiche la note Tomate sous l'affiche", + "ShowTraktRatingPosterHelpText": "Affiche la note Trakt sous l'affiche", "SmartReplace": "Remplacement intelligent", "SmartReplaceHint": "Tiret ou espace puis tiret selon le nom", "AnnouncedMovieAvailabilityDescription": "Les films sont considérés disponibles dès qu'ils sont ajouté à {appName}.", @@ -1831,7 +1831,7 @@ "ToggleUnmonitoredToMonitored": "Non surveillé, cliquez pour surveiller", "OnFileImport": "Lors de l'importation du fichier", "OnFileUpgrade": "Lors de la mise à jour du fichier", - "ShowTraktRating": "Affiche la note Trakt", + "ShowTraktRating": "Afficher la note Trakt", "ReleasedMovieAvailabilityDescription": "Les films sont considérés comme disponibles dès la sortie de la version Blu-Ray ou streaming.", "LastSearched": "Dernière recherche", "SkipFreeSpaceCheckHelpText": "Utiliser quand {appName} ne parvient pas à détecter l'espace disponible de votre dossier racine", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 94b1043d3b..cb910e8764 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1082,7 +1082,7 @@ "AutoRedownloadFailed": "Download fallito", "AddAutoTagError": "Impossibile aggiungere un nuovo tag automatico, riprova.", "AddDelayProfileError": "Impossibile aggiungere un nuovo profilo di ritardo, riprova.", - "AddListExclusion": "Aggiungi Lista esclusioni", + "AddListExclusion": "Aggiungi elenco esclusioni", "Label": "Etichetta", "QueueLoadError": "Impossibile caricare la Coda", "IncludeHealthWarnings": "Includi gli avvisi di salute", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index b5e0c40349..47380bab39 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1133,7 +1133,7 @@ "DeleteMovieFolders": "Ștergeți dosarul filmului", "DeleteMovieFoldersHelpText": "Ștergeți folderul filmului și conținutul acestuia", "DeleteSelectedMovies": "Ștergeți fișierele film selectate", - "DownloadClientSettingsRecentPriority": "Prioritate client", + "DownloadClientSettingsRecentPriority": "Prioritate recente", "MovieIsNotMonitored": "Filmul nu este monitorizat", "DeleteSelectedImportListExclusionsMessageText": "Sigur doriți să ștergeți această excludere din lista de importuri?", "UpdateAvailableHealthCheckMessage": "O nouă versiune este disponibilă: {version}", @@ -1151,5 +1151,6 @@ "Clone": "Clonează", "AddReleaseProfile": "Editați profilul de întârziere", "Delay": "Întârziere", - "DownloadClientUnavailable": "Client de descărcare indisponibil" + "DownloadClientUnavailable": "Client de descărcare indisponibil", + "DownloadClientSettingsOlderPriority": "Prioritate mai vechi" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 0491ca6ded..da7cac6cb0 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -754,7 +754,7 @@ "BrowserReloadRequired": "Требуется перезагрузка браузера", "UiLanguageHelpText": "Язык, который {appName} будет использовать для пользовательского интерфейса", "UiLanguage": "Язык пользовательского интерфейса", - "Ui": "Пользовательский интерфейс", + "Ui": "Интерфейс", "Type": "Тип", "Trigger": "Триггер", "Trakt": "Тракт", @@ -1790,5 +1790,6 @@ "FileBrowser": "Файловый браузер", "Completed": "Завершенный", "Delay": "Задержка", - "DownloadClientUnavailable": "Программа для скачивания недоступна" + "DownloadClientUnavailable": "Программа для скачивания недоступна", + "RegularExpressionsTutorialLink": "Более подробную информацию о регулярных выражениях можно найти [здесь]({url})." } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 8d10a1bf31..3422e2aa82 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -29,8 +29,8 @@ "ProxyCheckBadRequestMessage": "Proxy ile test edilemedi. DurumKodu: {statusCode}", "Proxy": "Proxy", "PreviewRename": "Yeniden Adlandır ve Önizle", - "ImportListStatusCheckSingleClientMessage": "Hatalar nedeniyle kullanılamayan dizinleyiciler: {importListNames}", - "ImportListStatusCheckAllClientMessage": "Hatalar nedeniyle tüm dizinleyiciler kullanılamıyor", + "ImportListStatusCheckSingleClientMessage": "Hatalar nedeniyle kullanılamayan indeksleyiciler: {importListNames}", + "ImportListStatusCheckAllClientMessage": "Hatalar nedeniyle tüm indeksleyiciler kullanılamıyor", "MonitoredOnly": "Sadece Takip Edilen", "MetadataSettingsMovieSummary": "Filmler içe aktarıldığında veya yenilenince meta veri dosyaları oluştur", "Metadata": "Meta veri", @@ -76,7 +76,7 @@ "TagsSettingsSummary": "Tüm etiketleri ve nasıl kullanıldıklarını göster. Kullanılmayan etiketler kaldırılabilinir", "Tags": "Etiketler", "System": "Sistem", - "Style": "Tarz", + "Style": "Stil", "Studio": "Stüdyo", "Status": "Durum", "SizeOnDisk": "Diskteki boyut", @@ -190,7 +190,7 @@ "RemotePath": "Uzak Yol", "ShowCertification": "Sertifikayı Göster", "TestAllClients": "Tüm İstemcileri Test Et", - "TestAllIndexers": "Dizinleyicileri Test Et", + "TestAllIndexers": "İndeksleyicileri Test Et", "TestAllLists": "Tüm Listeleri Test Et", "TMDb": "TMDb", "Name": "İsim", @@ -198,8 +198,8 @@ "DeleteTag": "Etiketi Sil", "DetailedProgressBarHelpText": "İlerleme çubuğundaki metni göster", "IncludeCustomFormatWhenRenaming": "Yeniden Adlandırırken Özel Formatı Dahil Et", - "IndexerLongTermStatusCheckSingleClientMessage": "6 saatten uzun süredir yaşanan arızalar nedeniyle dizinleyiciler kullanılamıyor: {indexerNames}", - "IndexerStatusCheckAllClientMessage": "Hatalar nedeniyle tüm dizinleyiciler kullanılamıyor", + "IndexerLongTermStatusCheckSingleClientMessage": "6 saatten uzun süredir yaşanan arızalar nedeniyle indeksleyiciler kullanılamıyor: {indexerNames}", + "IndexerStatusCheckAllClientMessage": "Hatalar nedeniyle tüm indeksleyiciler kullanılamıyor", "Level": "Seviye", "LoadingMovieCreditsFailed": "Film jeneriği yüklenemedi", "LoadingMovieFilesFailed": "Film dosyaları yüklenemedi", @@ -216,7 +216,7 @@ "Columns": "Sütunlar", "CopyUsingHardlinksHelpTextWarning": "Bazen, dosya kilitleri, başlatılan dosyaların yeniden adlandırılmasını engelleyebilir. Tohumlamayı geçici olarak devre dışı bırakabilir ve geçici olarak {appName}'ın yeniden adlandırma işlevini kullanabilirsiniz.", "UpgradeUntilMovieHelpText": "Bu kaliteye ulaşıldığında {appName} artık film indirmeyecektir", - "DeleteIndexerMessageText": "'{name}' dizinleyicisini silmek istediğinizden emin misiniz?", + "DeleteIndexerMessageText": "'{name}' indeksleyicisini silmek istediğinizden emin misiniz?", "DeleteRestrictionHelpText": "Bu kısıtlamayı silmek istediğinizden emin misiniz?", "DoneEditingGroups": "Grupları Düzenleme Bitti", "EditCustomFormat": "Özel Formatı Düzenle", @@ -230,8 +230,8 @@ "Folders": "Klasörler", "FollowPerson": "Kişiyi Takip Et", "GrabReleaseMessageText": "{appName}, bu yayının hangi film için olduğunu belirleyemedi. {appName} bu yayını otomatik olarak içe aktaramayabilir. '{0}'ı almak istiyor musunuz?", - "IndexerPriority": "Dizinleyici Önceliği", - "IndexerSearchCheckNoAvailableIndexersMessage": "Son zamanlardaki dizinleyici hataları nedeniyle tüm arama yeteneğine sahip dizinleyiciler geçici olarak kullanılamıyor", + "IndexerPriority": "İndeksleyici Önceliği", + "IndexerSearchCheckNoAvailableIndexersMessage": "Son zamanlardaki indeksleyici hataları nedeniyle tüm arama yeteneğine sahip indeksleyiciler geçici olarak kullanılamıyor", "InstallLatest": "En Sonu Yükle", "InteractiveSearch": "Etkileşimli Arama", "MovieInvalidFormat": "Film: Geçersiz Format", @@ -253,7 +253,7 @@ "RemotePathMappingRemotePathHelpText": "İndirme İstemcisinin eriştiği dizinin kök yolu", "RuntimeFormat": "Çalışma Zamanı Biçimi", "ShortDateFormat": "Kısa Tarih Formatı", - "ShowRelativeDates": "Göreli Tarihleri Göster", + "ShowRelativeDates": "İlgili Tarihleri Göster", "TimeFormat": "Zaman formatı", "WeekColumnHeader": "Hafta Sütun Başlığı", "ListMonitorMovieHelpText": "Bu listeye eklenen Filmler veya Koleksiyonlar takip edilecek şekilde eklenmeli mi", @@ -278,7 +278,7 @@ "SorryThatMovieCannotBeFound": "Maalesef o film bulunamıyor.", "Source": "Kaynak", "SourcePath": "Kaynak Yolu", - "SourceRelativePath": "Kaynak Göreli Yol", + "SourceRelativePath": "Kaynak Göreceli Yol", "SslCertPassword": "SSL Sertifika Parolası", "SslCertPasswordHelpText": "Pfx dosyası için şifre", "SslCertPath": "SSL Sertifika Yolu", @@ -315,7 +315,7 @@ "AddConditionError": "Yeni bir koşul eklenemiyor, lütfen tekrar deneyin.", "AddCustomFormatError": "Yeni bir özel format eklenemiyor, lütfen tekrar deneyin.", "AddDownloadClientError": "Yeni bir indirme istemcisi eklenemiyor, lütfen tekrar deneyin.", - "AddIndexerError": "Yeni dizinleyici eklenemiyor, lütfen tekrar deneyin.", + "AddIndexerError": "Yeni indeksleyici eklenemiyor, lütfen tekrar deneyin.", "AddListError": "Yeni bir liste eklenemiyor, lütfen tekrar deneyin.", "AddNotificationError": "Yeni bir bildirim eklenemiyor, lütfen tekrar deneyin.", "AddQualityProfileError": "Yeni kalite profili eklenemiyor, lütfen tekrar deneyin.", @@ -323,8 +323,8 @@ "BackupsLoadError": "Yedeklemeler yüklenemiyor", "CustomFormatsLoadError": "Özel Formatlar yüklenemiyor", "GeneralSettingsLoadError": "Genel ayarlar yüklenemiyor", - "IndexerOptionsLoadError": "Dizinleyici seçenekleri yüklenemiyor", - "IndexersLoadError": "Dizinleyiciler yüklenemiyor", + "IndexerOptionsLoadError": "İndeksleyici seçenekleri yüklenemiyor", + "IndexersLoadError": "İndeksleyiciler yüklenemiyor", "ImportListExclusionsLoadError": "Hariç Tutulanlar Listesi yüklenemiyor", "ImportListsLoadError": "Listeler yüklenemiyor", "UnableToLoadManualImportItems": "El ile içe aktarılan öğeler yüklenemiyor", @@ -393,7 +393,7 @@ "DeleteHeader": "Sil - {0}", "DeleteMovieFolder": "Film Klasörünü Sil", "DestinationPath": "Hedef yol", - "DestinationRelativePath": "Hedef Göreli Yol", + "DestinationRelativePath": "Hedef Göreceli Yol", "DetailedProgressBar": "Ayrıntılı İlerleme Çubuğu", "EditGroups": "Grupları Düzenle", "ICalFeedHelpText": "Bu URL'yi müşterilerinize kopyalayın veya tarayıcınız webcal'i destekliyorsa abone olmak için tıklayın", @@ -418,7 +418,7 @@ "AfterManualRefresh": "Manüel Yenilemeden Sonra", "AllFiles": "Tüm dosyalar", "AcceptConfirmationModal": "Onay Modunu Kabul Et", - "AddIndexer": "Dizinleyici Ekle", + "AddIndexer": "İndeksleyici Ekle", "AllResultsHiddenFilter": "Tüm sonuçlar, uygulanan filtre tarafından gizlenir", "AnalyseVideoFiles": "Video Dosyalarını Analiz Et", "AppDataDirectory": "Uygulama Veri Dizini", @@ -458,7 +458,7 @@ "ICalFeed": "iCal Beslemesi", "Imported": "İçe aktarıldı", "IllRestartLater": "Daha sonra yeniden başlayacağım", - "IndexersSettingsSummary": "Dizinleyiciler ve yayımlama kısıtlamaları", + "IndexersSettingsSummary": "İndeksleyiciler ve yayımlama kısıtlamaları", "InvalidFormat": "Geçersiz format", "LastDuration": "Yürütme Süresi", "ListSyncLevelHelpTextWarning": "Film dosyaları kalıcı olarak silinecek, bu, listeleriniz boşsa kitaplığınızın silinmesine neden olabilir", @@ -483,9 +483,9 @@ "UpgradesAllowed": "Yükseltmelere İzin Ver", "Pending": "Bekliyor", "EnableSsl": "SSL'yi etkinleştir", - "Indexer": "Dizinleyici", - "IndexerFlags": "Dizinleyici Bayrakları", - "IndexerLongTermStatusCheckAllClientMessage": "6 saatten uzun süren arızalar nedeniyle tüm dizinleyiciler kullanılamıyor", + "Indexer": "İndeksleyici", + "IndexerFlags": "İndeksleyici Bayrakları", + "IndexerLongTermStatusCheckAllClientMessage": "6 saatten uzun süren arızalar nedeniyle tüm indeksleyiciler kullanılamıyor", "LoadingMovieExtraFilesFailed": "İlave film dosyaları yüklenemedi", "Manual": "Manuel", "ManualImport": "Manuel İçe Aktar", @@ -494,7 +494,7 @@ "Hostname": "Hostname", "MinutesSixty": "60 Dakika: {sixty}", "MoreDetails": "Daha fazla detay", - "MovieInfoLanguageHelpText": "{appName}'ın Kullanıcı Arayüzünde Film Bilgileri için kullanacağı dil", + "MovieInfoLanguageHelpText": "{appName}'in Kullanıcı Arayüzünde Film Bilgileri için kullanacağı dil", "MovieIsMonitored": "Film takip ediliyor", "SuggestTranslationChange": "Çeviri değişikliği önerin", "DownloadClientStatusCheckAllClientMessage": "Hatalar nedeniyle tüm indirme istemcileri kullanılamıyor", @@ -505,11 +505,11 @@ "AddImportListExclusion": "İçe Aktarma Listesi Hariç Tutma Ekle", "ApiKey": "API Anahtarı", "NamingSettings": "Adlandırma Ayarları", - "NoLogFiles": "Log kayıt dosyası henüz yok", + "NoLogFiles": "Log kayıt dosyası henüz oluşturulmadı", "NoMatchFound": "Eşleşme bulunamadı!", "NotMonitored": "Takip Edilmeyen", "MinimumAge": "Minimum Geçen Süre", - "NoUpdatesAreAvailable": "Güncelleme yok", + "NoUpdatesAreAvailable": "Güncelleme bulunamadı", "AddingTag": "Etiket ekleniyor", "Age": "Yıl", "AgeWhenGrabbed": "Yıl (alındığında)", @@ -520,7 +520,7 @@ "ApplyTags": "Etiketleri Uygula", "AuthenticationMethodHelpText": "{appName}'e erişmek için Kullanıcı Adı ve Parola gereklidir", "Automatic": "Otomatik", - "AutoRedownloadFailedHelpText": "Otomatik olarak farklı bir Yayın arayın ve indirmeye çalışın", + "AutoRedownloadFailedHelpText": "Farklı bir sürümü otomatik olarak ara ve indirmeyi dene", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Diskten silinen filmler otomatik olarak {appName}'da takip edilmez", "AvailabilityDelay": "Kullanılabilirlik Gecikmesi", "AvailabilityDelayHelpText": "Film aramak için mevcut tarihten önceki veya sonraki zaman miktarı", @@ -540,7 +540,7 @@ "ChangeFileDate": "Dosya Tarihini Değiştir", "ChangeHasNotBeenSavedYet": "Değişiklik henüz kaydedilmedi", "CheckDownloadClientForDetails": "daha fazla ayrıntı için indirme istemcisini kontrol edin", - "CheckForFinishedDownloadsInterval": "Tamamlanan İndirmeler Aralığını Kontrol Et", + "CheckForFinishedDownloadsInterval": "Tamamlanan İndirmeleri Kontrol Etme Aralığını", "CleanLibraryLevel": "Kütüphane Seviyesini Temizle", "ClientPriority": "Müşteri Önceliği", "CertificationCountry": "Sertifikasyon Ülkesi", @@ -575,7 +575,7 @@ "PendingChangesDiscardChanges": "Değişiklikleri at ve ayrıl", "PreferredSize": "Tercih Edilen Boyut", "Proper": "Uygun", - "PtpOldSettingsCheckMessage": "Aşağıdaki PassThePopcorn dizinleyicilerinin ayarları kullanımdan kaldırıldı ve güncellenmeleri gerekiyor: {0}", + "PtpOldSettingsCheckMessage": "Aşağıdaki PassThePopcorn indeksleyicilerinin ayarları kullanımdan kaldırıldı ve güncellenmeleri gerekiyor: {0}", "Queued": "Kuyruğa alındı", "RecyclingBinCleanup": "Geri Dönüşüm Kutusu Temizle", "RefreshMovie": "Filmi yenile", @@ -673,7 +673,7 @@ "DeleteEmptyFoldersHelpText": "Disk taraması sırasında ve film dosyaları silindiğinde boş film klasörlerini silin", "DeleteFile": "Dosyayı sil", "DeleteImportListExclusion": "İçe Aktarma Listesi Hariç Tutmasını Sil", - "DeleteIndexer": "Dizinleyiciyi Sil", + "DeleteIndexer": "İndeksleyiciyi Sil", "DeleteMovieFolderHelpText": "Film klasörünü ve içeriğini silin", "DeleteNotification": "Bildirimi Sil", "DeleteNotificationMessageText": "'{name}' bildirimini silmek istediğinizden emin misiniz?", @@ -683,7 +683,7 @@ "DeleteSelectedMovieFiles": "Seçili Film Dosyalarını Sil", "DeleteTagMessageText": "'{label}' etiketini silmek istediğinizden emin misiniz?", "DeleteMovieFolderConfirmation": "'{path}' film klasörü ve tüm içeriği silinecek.", - "Discord": "Uyuşmazlık", + "Discord": "Discord", "Docker": "Docker", "Donations": "Bağış", "DoNotPrefer": "Tercih etmeme", @@ -737,7 +737,7 @@ "ChangeFileDateHelpText": "İçe aktarma/yeniden tarama sırasında dosya tarihini değiştir", "FileNames": "Dosya Adları", "FilterPlaceHolder": "Film ara", - "FirstDayOfWeek": "Haftanın ilk günü", + "FirstDayOfWeek": "Haftanın İlk Günü", "Fixed": "Düzeltilen", "FolderMoveRenameWarning": "Bu aynı zamanda ayarlarda film klasörü formatına göre film klasörünü yeniden adlandıracaktır.", "SupportedDownloadClientsMoreInfo": "Bireysel indirme istemcileri hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", @@ -770,14 +770,14 @@ "IncludeRecommendationsHelpText": "{appName} tarafından önerilen filmleri keşif görünümüne dahil et", "IncludeUnmonitored": "Takip Edilmeyenleri Dahil Et", "ImportMovies": "Filmleri İçe Aktar", - "IndexerPriorityHelpText": "Dizinleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm dizin oluşturucuları kullanmaya devam edecek", - "IndexerRssHealthCheckNoAvailableIndexers": "Son zamanlardaki dizinleyici hataları nedeniyle tüm rss uyumlu dizinleyiciler geçici olarak kullanılamıyor", - "IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonunun etkin olduğu dizinleyici yok, {appName} yeni yayınlar otomatik olarak almayacak", - "Indexers": "Dizinleyiciler", - "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır", - "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir dizinleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır", - "IndexerSettings": "Dizinleyici Ayarları", - "IndexerStatusCheckSingleClientMessage": "Hatalar nedeniyle dizinleyiciler kullanılamıyor: {indexerNames}", + "IndexerPriorityHelpText": "İndeksleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm indeksleyicileri kullanmaya devam edecek", + "IndexerRssHealthCheckNoAvailableIndexers": "Son zamanlardaki indeksleyici hataları nedeniyle tüm rss uyumlu indeksleyiciler geçici olarak kullanılamıyor", + "IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonunun etkin olduğu indeksleyici bulunamadı, {appName} yeni yayınlar otomatik olarak almayacak", + "Indexers": "İndeksleyiciler", + "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır", + "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır", + "IndexerSettings": "İndeksleyici Ayarları", + "IndexerStatusCheckSingleClientMessage": "Hatalar nedeniyle indeksleyiciler kullanılamıyor: {indexerNames}", "InteractiveImport": "Etkileşimli İçe Aktarma", "Interval": "Periyot", "KeepAndUnmonitorMovie": "Filmi Sakla ve Takibi Bırak", @@ -840,7 +840,7 @@ "PhysicalReleaseDate": "Fiziksel Yayın Tarihi", "PosterOptions": "Poster Seçenekleri", "PreferAndUpgrade": "Tercih Et ve Yükselt", - "PreferIndexerFlags": "Dizinleyici Bayraklarını Tercih Edin", + "PreferIndexerFlags": "İndeksleyici Bayraklarını Tercih Edin", "Preferred": "Tercihli", "PreviewRenameHelpText": "İpucu: Yeniden adlandırmayı önizlemek için... 'Düzenlemeden Çık'ı seçin, ardından herhangi bir film başlığına tıklayın ve", "Priority": "Öncelik", @@ -890,7 +890,7 @@ "Retention": "Saklama", "RssIsNotSupportedWithThisIndexer": "RSS, bu indeksleyici ile desteklenmiyor", "RssSyncInterval": "RSS Senkronizasyon Aralığı", - "RssSyncIntervalHelpTextWarning": "Bu, tüm dizinleyiciler için geçerli olacaktır, lütfen onlar tarafından belirlenen kurallara uyun", + "RssSyncIntervalHelpTextWarning": "Bu, tüm indeksleyiciler için geçerli olacaktır, lütfen onlar tarafından belirlenen kurallara uyun", "Save": "Kaydet", "SaveSettings": "Ayarları kaydet", "Score": "Puan", @@ -911,7 +911,7 @@ "SetPermissions": "İzinleri Ayarla", "SetPermissionsLinuxHelpTextWarning": "Bu ayarların ne yaptığından emin değilseniz, değiştirmeyin.", "LongDateFormat": "Uzun Tarih Formatı", - "ShowRelativeDatesHelpText": "Göreli (Bugün / Dün / vb.) Veya mutlak tarihleri göster", + "ShowRelativeDatesHelpText": "Göreceli (Bugün/Dün/vb.) veya mutlak tarihleri göster", "WeekColumnHeaderHelpText": "Aktif görünüm hafta olduğunda her bir sütunun üzerinde gösterilir", "ICalShowAsAllDayEvents": "Tüm Gün Olayları Olarak Göster", "ShowMovieInformation": "Film Bilgilerini Göster", @@ -978,7 +978,7 @@ "AddCondition": "Koşul Ekle", "AddConditionImplementation": "Koşul Ekle - {implementationName}", "AddConnection": "Bağlantı Ekle", - "AddIndexerImplementation": "Yeni Dizinleyici Ekle - {implementationName}", + "AddIndexerImplementation": "Yeni İndeksleyici Ekle - {implementationName}", "AddConnectionImplementation": "Bağlantı Ekle - {implementationName}", "EditIndexerImplementation": "Koşul Ekle - {implementationName}", "AllTitles": "Tüm Başlıklar", @@ -990,7 +990,7 @@ "AddImportListImplementation": "İçe Aktarım Listesi Ekle -{implementationName}", "AddReleaseProfile": "Yayın Profili Ekle", "CollectionOptions": "Koleksiyon Seçenekleri", - "AutoRedownloadFailedFromInteractiveSearch": "Etkileşimli Aramadan Yeniden İndirme Başarısız Oldu", + "AutoRedownloadFailedFromInteractiveSearch": "Etkileşimli Arama'dan Başarısız İndirmeleri Yenile", "AutoTaggingNegateHelpText": "İşaretlenirse, {implementationName} koşulu eşleştiğinde otomatik etiketleme kuralı uygulanmayacaktır.", "AutomaticUpdatesDisabledDocker": "Docker güncelleme mekanizması kullanıldığında otomatik güncellemeler doğrudan desteklenmez. Konteyner görüntüsünü {appName} dışında güncellemeniz veya bir komut dosyası kullanmanız gerekecek", "BypassDelayIfHighestQuality": "En Yüksek Kalitedeyse Atla", @@ -1024,7 +1024,7 @@ "CollectionShowPostersHelpText": "Koleksiyon öğesi posterlerini göster", "CloneCondition": "Klon Durumu", "ApiKeyValidationHealthCheckMessage": "Lütfen API anahtarınızı en az {length} karakter sayısı kadar güncelleyiniz. Bunu ayarlar veya yapılandırma dosyası üzerinden yapabilirsiniz", - "AutoRedownloadFailed": "Yeniden İndirme Başarısız", + "AutoRedownloadFailed": "Başarısız İndirmeleri Yenile", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimum Özel Format Puanı", "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Tercih edilen protokolde gecikmeyi atlamak için gereken Minimum Özel Format Puanı", @@ -1042,7 +1042,7 @@ "AuthenticationRequired": "Kimlik Doğrulama", "AuthenticationMethod": "Kimlik Doğrulama Yöntemi", "AuthenticationMethodHelpTextWarning": "Lütfen geçerli bir kimlik doğrulama yöntemi seçin", - "ClickToChangeIndexerFlags": "Dizinleyici bayraklarını değiştirmek için tıklayın", + "ClickToChangeIndexerFlags": "İndeksleyici bayraklarını değiştirmek için tıklayın", "BypassDelayIfHighestQualityHelpText": "Tercih edilen protokolle kalite profilinde en yüksek etkin kaliteye sahip yayın olduğunda gecikmeyi atlayın", "AutoTaggingRequiredHelpText": "Otomatik etiketleme kuralının uygulanabilmesi için bu {implementationName} koşulunun eşleşmesi gerekir. Aksi takdirde tek bir {implementationName} eşleşmesi yeterlidir.", "CustomFilter": "Özel Filtre", @@ -1051,14 +1051,14 @@ "ApplyTagsHelpTextHowToApplyImportLists": "Seçilen içe aktarma listelerine etiketler nasıl uygulanır", "ApplyTagsHelpTextReplace": "Değiştir: Etiketleri girilen etiketlerle değiştirin (tüm etiketleri kaldırmak için etiket girmeyin)", "Auto": "Otomatik", - "CountIndexersSelected": "{count} dizinleyici seçildi", + "CountIndexersSelected": "{count} indeksleyici seçildi", "CustomFormatsSpecificationFlag": "Bayrak", "CountCollectionsSelected": "{count} koleksiyon seçildi", "CustomFormatJson": "Özel JSON Formatı", "AddListExclusion": "Hariç Tutma Listesine Ekle", "AuthenticationRequiredPasswordHelpTextWarning": "Yeni şifre girin", "AuthenticationRequiredUsernameHelpTextWarning": "Yeni kullanıcı adınızı girin", - "AutoRedownloadFailedFromInteractiveSearchHelpText": "Başarısız indirmeler, etkileşimli aramada bulunduğunda otomatik olarak farklı bir versiyonu arayın ve indirmeyi deneyin", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "Etkileşimli aramadan başarısız bir sürüm alındığında otomatik olarak farklı bir sürümü arayın ve indirmeye çalışın", "AutoTagging": "Otomatik Etiketleme", "ChangeCategoryHint": "İndirme İstemcisi'nden indirme işlemini 'İçe Aktarma Sonrası Kategorisi' olarak değiştirir", "Clone": "Klon", @@ -1108,10 +1108,10 @@ "DeleteCustomFormatMessageText": "'{name}' özel formatı silmek istediğinizden emin misiniz?", "DeleteImportList": "İçe Aktarma Listesini Sil", "DeleteRootFolder": "Kök Klasörü Sil", - "DeleteSelectedIndexers": "Dizinleyicileri Sil", + "DeleteSelectedIndexers": "İndeksleyicileri Sil", "DisabledForLocalAddresses": "Yerel Adreslerde Devre Dışı Bırak", "DeleteRootFolderMessageText": "'{path}' kök klasörünü silmek istediğinizden emin misiniz?", - "DeleteSelectedIndexersMessageText": "Seçilen {count} dizinleyiciyi silmek istediğinizden emin misiniz?", + "DeleteSelectedIndexersMessageText": "Seçilen {count} indeksleyiciyi silmek istediğinizden emin misiniz?", "Destination": "Hedef", "DeletedReasonMovieMissingFromDisk": "{appName} dosyayı diskte bulamadığından dosyanın veritabanındaki filmle bağlantısı kaldırıldı", "DownloadClientDelugeTorrentStateError": "Deluge bir hata bildiriyor", @@ -1119,7 +1119,7 @@ "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Kategorileri kullanmak için {clientName} uygulamasında Etiket eklentisini etkinleştirmiş olmanız gerekir.", "DownloadClientDownloadStationValidationApiVersion": "Download Station API sürümü desteklenmiyor; en az {requiredVersion} olmalıdır. {minVersion}'dan {maxVersion}'a kadar destekler", "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Diskstation'da '{sharedFolder}' adında bir Paylaşımlı Klasör yok, bunu doğru belirttiğinizden emin misiniz?", - "DownloadClientFloodSettingsRemovalInfo": "{appName}, Ayarlar -> Dizinleyiciler'deki geçerli başlangıç ölçütlerine göre torrentlerin otomatik olarak kaldırılmasını sağlar", + "DownloadClientFloodSettingsRemovalInfo": "{appName}, Ayarlar -> İndeksleyiciler'deki geçerli başlangıç ölçütlerine göre torrentlerin otomatik olarak kaldırılmasını sağlar", "DownloadClientFloodSettingsTagsHelpText": "Bir indirme işleminin başlangıç etiketleri. Bir indirmenin tanınabilmesi için tüm başlangıç etiketlerine sahip olması gerekir. Bu, ilgisiz indirmelerle çakışmaları önler.", "DownloadClientFreeboxUnableToReachFreebox": "Freebox API'sine ulaşılamıyor. 'Ana Bilgisayar', 'Bağlantı Noktası' veya 'SSL Kullan' ayarlarını doğrulayın. (Hata: {exceptionMessage})", "DownloadClientAriaSettingsDirectoryHelpText": "İndirilenlerin yerleştirileceği isteğe bağlı konum, varsayılan Aria2 konumunu kullanmak için boş bırakın", @@ -1138,7 +1138,7 @@ "DeleteSelectedDownloadClients": "İndirme İstemcilerini Sil", "DeleteSelectedDownloadClientsMessageText": "Seçilen {count} indirme istemcisini silmek istediğinizden emin misiniz?", "DeletedReasonManual": "Dosya, {appName} kullanılarak manuel olarak veya API aracılığıyla başka bir araçla silindi", - "DownloadClientDownloadStationValidationNoDefaultDestination": "Varsayılan hedef yok", + "DownloadClientDownloadStationValidationNoDefaultDestination": "Varsayılan hedef bulunamadı", "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Diskstation'ınızda {username} olarak oturum açmalı ve BT/HTTP/FTP/NZB -> Konum altında DownloadStation ayarlarında manuel olarak ayarlamalısınız.", "DownloadClientDelugeSettingsDirectory": "İndirme Dizini", "DownloadClientDelugeSettingsDirectoryCompleted": "Tamamlandığında Dizini Taşı", @@ -1151,13 +1151,13 @@ "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName}, etiketi {clientName} uygulamasına ekleyemedi.", "DownloadClientFreeboxSettingsAppId": "Uygulama kimliği", "DownloadClientFreeboxSettingsApiUrl": "API URL'si", - "DownloadClientFreeboxSettingsAppToken": "Uygulama Jetonu", + "DownloadClientFreeboxSettingsAppToken": "Uygulama Token'ı", "DownloadClientFreeboxSettingsHostHelpText": "Freebox'un istemci adı veya istemci IP adresi, varsayılan olarak '{url}' şeklindedir (yalnızca aynı ağda çalışır)", "DownloadClientFreeboxAuthenticationError": "Freebox API'sinde kimlik doğrulama başarısız oldu. Sebep: {errorDescription}", "DownloadClientFreeboxNotLoggedIn": "Giriş yapmadınız", "DownloadClientFreeboxSettingsApiUrlHelpText": "Freebox API temel URL'sini API sürümüyle tanımlayın, örneğin '{url}', varsayılan olarak '{defaultApiUrl}' olur", "DownloadClientFreeboxSettingsAppIdHelpText": "Freebox API'sine erişim oluşturulurken verilen uygulama kimliği (ör. 'app_id')", - "DownloadClientFreeboxSettingsAppTokenHelpText": "Freebox API'sine erişim oluşturulurken alınan uygulama jetonu (ör. 'app_token')", + "DownloadClientFreeboxSettingsAppTokenHelpText": "Freebox API'sine erişim oluşturulurken alınan uygulama token'ı (ör. 'app_token')", "DownloadClientNzbgetSettingsAddPausedHelpText": "Bu seçenek en az NzbGet sürüm 16.0'ı gerektirir", "DownloadClientNzbgetValidationKeepHistoryOverMax": "NzbGet ayarı KeepHistory 25000'den az olmalıdır", "DownloadClientNzbgetValidationKeepHistoryZero": "NzbGet ayarı KeepHistory 0'dan büyük olmalıdır", @@ -1233,7 +1233,7 @@ "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "{downloadClientName} indirme istemcisi, tamamlanan indirmeleri kaldıracak şekilde ayarlandı. Bu, indirilenlerin {appName} içe aktarılmadan önce istemcinizden kaldırılmasına neden olabilir.", "DownloadClientQbittorrentTorrentStatePathError": "İçe Aktarılamıyor. Yol, istemci tabanlı indirme dizini ile eşleşiyor, bu torrent için 'Üst düzey klasörü tut' seçeneği devre dışı bırakılmış olabilir veya 'Torrent İçerik Düzeni' 'Orijinal' veya 'Alt Klasör Oluştur' olarak ayarlanmamış olabilir mi?", "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} her indirme işleminin ayrı bir klasöre sahip olmasını tercih ediyor. Klasör/Yol'a * eklendiğinde Sabnzbd bu iş klasörlerini oluşturmayacaktır. Düzeltmek için Sabnzbd'a gidin.", - "DownloadClientSettingsPostImportCategoryHelpText": "{appName}'in indirmeyi içe aktardıktan sonra ayarlayacağı kategori. {appName}, tohumlama tamamlansa bile bu kategorideki torrentleri kaldırmaz. Aynı kategoriyi korumak için boş bırakın.", + "DownloadClientSettingsPostImportCategoryHelpText": "{appName}'in indirmeyi içe aktardıktan sonra ayarlayacağı kategori. {appName}, seed tamamlanmış olsa bile bu kategorideki torrentleri kaldırmayacaktır. Aynı kategoriyi korumak için boş bırakın.", "DownloadClientTransmissionSettingsUrlBaseHelpText": "{clientName} rpc URL'sine bir önek ekler, örneğin {url}, varsayılan olarak '{defaultUrl}' olur", "DownloadClientQbittorrentSettingsUseSslHelpText": "Güvenli bir bağlantı kullanın. qBittorrent'te Seçenekler -> Web Kullanıcı Arayüzü -> 'HTTP yerine HTTPS kullan' bölümüne bakın.", "DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent, DHT devre dışıyken magnet bağlantısını çözemiyor", @@ -1250,7 +1250,7 @@ "DownloadClientSabnzbdValidationDevelopVersionDetail": "{appName}, geliştirme sürümlerini çalıştırırken SABnzbd'ye eklenen yeni özellikleri desteklemeyebilir.", "DownloadClientSabnzbdValidationEnableDisableDateSorting": "Tarih Sıralamayı Devre Dışı Bırak", "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "Film Sıralamayı Devre Dışı Bırak", - "DownloadClientRTorrentProviderMessage": "rTorrent, başlangıç kriterlerini karşılayan torrentleri duraklatmaz. {appName}, torrentlerin otomatik olarak kaldırılmasını Ayarlar->Dizinleyiciler'deki geçerli tohum kriterlerine göre yalnızca Tamamlandı Kaldırma etkinleştirildiğinde gerçekleştirecektir. İçe aktardıktan sonra, davranışı özelleştirmek için rTorrent komut dosyalarında kullanılabilen {importedView}'ı bir rTorrent görünümü olarak ayarlayacaktır.", + "DownloadClientRTorrentProviderMessage": "rTorrent, başlangıç kriterlerini karşılayan torrentleri duraklatmaz. {appName}, torrentlerin otomatik olarak kaldırılmasını Ayarlar->İndeksleyiciler'deki geçerli tohum kriterlerine göre yalnızca Tamamlandı Kaldırma etkinleştirildiğinde gerçekleştirecektir. İçe aktardıktan sonra, davranışı özelleştirmek için rTorrent komut dosyalarında kullanılabilen {importedView}'ı bir rTorrent görünümü olarak ayarlayacaktır.", "DownloadClientRTorrentSettingsAddStoppedHelpText": "Etkinleştirme, durdurulmuş durumdaki rTorrent'e torrentler ve magnet ekleyecektir. Bu magnet dosyalarını bozabilir.", "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "'İndirmeden önce kontrol et' seçeneğinin kullanılması, {appName} uygulamasının yeni indirilenleri takip etme yeteneğini etkiler. Ayrıca Sabnzbd, daha etkili olduğu için bunun yerine 'Tamamlanamayan işleri iptal et' seçeneğini öneriyor.", "DownloadClientValidationCategoryMissing": "Kategori mevcut değil", @@ -1291,7 +1291,7 @@ "NotificationsAppriseSettingsServerUrlHelpText": "Gerekiyorsa http(s):// ve bağlantı noktasını içeren Apprise sunucu URL'si", "NotificationsAppriseSettingsTags": "Apprise Etiketler", "NotificationsEmailSettingsUseEncryption": "Şifreleme Kullan", - "EditSelectedIndexers": "Seçili Dizinleyicileri Düzenle", + "EditSelectedIndexers": "Seçili İndeksleyicileri Düzenle", "MovieMatchType": "Film Eşleme Türü", "MoveAutomatically": "Otomatik Olarak Taşı", "ManageLists": "Listeleri Yönet", @@ -1302,7 +1302,7 @@ "FormatRuntimeHours": "{hours}s", "IgnoreDownloadHint": "{appName}'in bu indirmeyi daha fazla işlemesini durdurur", "LogFilesLocation": "Log kayıtlarının bulunduğu konum: {location}", - "ManageIndexers": "Dizinleyicileri Yönet", + "ManageIndexers": "İndeksleyicileri Yönet", "MovieFileDeletedTooltip": "Film dosyası silindi", "NotificationsCustomScriptSettingsArgumentsHelpText": "Komut dosyasına aktarılacak argümanlar", "NotificationsCustomScriptSettingsArguments": "Argümanlar", @@ -1330,14 +1330,14 @@ "FullColorEventsHelpText": "Etkinliğin tamamını yalnızca sol kenar yerine durum rengiyle renklendirecek şekilde stil değiştirildi. Gündem için geçerli değildir", "IMDbId": "IMDb Id", "EnableProfile": "Profili Etkinleştir", - "IndexerDownloadClientHelpText": "Bu dizinleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin", + "IndexerDownloadClientHelpText": "Bu indeksleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin", "InstanceNameHelpText": "Sekmedeki örnek adı ve Syslog uygulaması adı için", "InstanceName": "Örnek isim", "InteractiveImportNoFilesFound": "Seçilen klasörde video dosyası bulunamadı", "InteractiveImportNoQuality": "Seçilen her dosya için kalite seçilmelidir", "InvalidUILanguage": "Kullanıcı arayüzünüz geçersiz bir dile ayarlanmış, düzeltin ve ayarlarınızı kaydedin", "ManualGrab": "Manuel Alımlarda", - "IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip dizinleyiciler: {indexerNames}.", + "IndexerDownloadClientHealthCheckMessage": "Geçersiz indirme istemcilerine sahip indeksleyiciler: {indexerNames}.", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Film koleksiyonu için eksik kök klasör: {rootFolderInfo}", "NoImportListsFound": "İçe aktarma listesi bulunamadı", "MovieGrabbedTooltip": "Film {indexer}'dan alındı ve {downloadClient}'a gönderildi", @@ -1372,7 +1372,7 @@ "NotificationsEmailSettingsRecipientAddressHelpText": "E-posta alıcılarının virgülle ayrılmış listesi", "NotificationsEmbySettingsUpdateLibraryHelpText": "İçe Aktarma, Yeniden Adlandırma veya Silme sırasında Kitaplığı Güncelleyin", "NotificationsGotifySettingIncludeMoviePosterHelpText": "Mesaja film posterini ekle", - "NotificationsGotifySettingsAppToken": "Uygulama Jetonu", + "NotificationsGotifySettingsAppToken": "Uygulama Token'ı", "InteractiveSearchModalHeader": "İnteraktif Arama", "NotificationsAppriseSettingsConfigurationKey": "Apprise Yapılandırma Anahtarı", "NotificationsAppriseSettingsConfigurationKeyHelpText": "Kalıcı Depolama Çözümü için Yapılandırma Anahtarı. Durum Bilgisi Olmayan URL'ler kullanılıyorsa boş bırakın.", @@ -1400,13 +1400,13 @@ "NotificationsDiscordSettingsAuthor": "Yazar", "NotificationsGotifySettingsPriorityHelpText": "Bildirimin önceliği", "NotificationsGotifySettingIncludeMoviePoster": "Film Posterini Ekle", - "NotificationsGotifySettingsAppTokenHelpText": "Gotify tarafından oluşturulan Uygulama Jetonu", + "NotificationsGotifySettingsAppTokenHelpText": "Gotify tarafından oluşturulan Uygulama Token'ı", "NotificationsKodiSettingsCleanLibrary": "Kütüphaneyi Temizle", "NotificationsKodiSettingsCleanLibraryHelpText": "Güncellemeden sonra kitaplığı temizle", "NotificationsMailgunSettingsUseEuEndpointHelpText": "AB MailGun uç noktasını kullanmayı etkinleştirin", - "IndexerJackettAll": "Desteklenmeyen Jackett 'hepsi' uç noktasını kullanan dizinleyiciler: {indexerNames}", + "IndexerJackettAll": "Jackett'in desteklenmeyen 'hepsi' uç noktasını kullanan indeksleyiciler: {indexerNames}", "IndexerSettingsRejectBlocklistedTorrentHashes": "Alırken Engellenen Torrent Karmalarını Reddet", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı dizinleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent alındıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Bir torrent hash tarafından engellenirse, bazı indeksleyiciler için RSS / Arama sırasında düzgün bir şekilde reddedilmeyebilir, bunun etkinleştirilmesi, torrent alındıktan sonra, ancak istemciye gönderilmeden önce reddedilmesine izin verecektir.", "MovieFileRenamedTooltip": "Film dosyası yeniden adlandırıldı", "MovieFileRenamed": "Film Dosyası Yeniden Adlandırıldı", "NotificationsCustomScriptValidationFileDoesNotExist": "Dosya bulunmuyor", @@ -1449,12 +1449,12 @@ "NotificationsEmailSettingsCcAddressHelpText": "E-posta CC alıcılarının virgülle ayrılmış listesi", "NotificationsEmailSettingsFromAddress": "Adresten", "NotificationsMailgunSettingsUseEuEndpoint": "AB Uç Noktasını Kullan", - "NotificationsNtfySettingsAccessToken": "Erişim Jetonu", + "NotificationsNtfySettingsAccessToken": "Erişim Token'ı", "NotificationsEmailSettingsName": "E-posta", "NotificationsNtfySettingsTopics": "Konular", "NotificationsNtfySettingsTopicsHelpText": "Bildirim gönderilecek konuların listesi", "NotificationsNtfySettingsUsernameHelpText": "İsteğe bağlı kullanıcı adı", - "NotificationsNtfySettingsAccessTokenHelpText": "İsteğe bağlı jeton tabanlı yetkilendirme. Kullanıcı adı/şifreye göre önceliklidir", + "NotificationsNtfySettingsAccessTokenHelpText": "İsteğe bağlı token tabanlı yetkilendirme. Kullanıcı adı/şifreye göre önceliklidir", "NotificationsNtfySettingsServerUrlHelpText": "Genel sunucuyu ({url}) kullanmak için boş bırakın", "EditReleaseProfile": "Yayımlama Profilini Düzenle", "Example": "Örnek", @@ -1465,14 +1465,14 @@ "HourShorthand": "s", "ImportScriptPathHelpText": "İçe aktarma için kullanılacak komut dosyasının yolu", "ImportUsingScriptHelpText": "Bir komut dosyası kullanarak içe aktarmak için dosyaları kopyalayın (ör. kod dönüştürme için)", - "IndexerTagMovieHelpText": "Bu dizinleyiciyi yalnızca en az bir eşleşen etikete sahip filmler için kullanın. Tüm filmlerle kullanmak için boş bırakın.", - "NoDelay": "Gecikme yok", + "IndexerTagMovieHelpText": "Bu indeksleyiciyi yalnızca en az bir eşleşen etikete sahip filmler için kullanın. Tüm filmlerle kullanmak için boş bırakın.", + "NoDelay": "Gecikmesiz", "Label": "Etiket", "LabelIsRequired": "Etiket gerekli", "Lists": "Listeler", "Letterboxd": "Letterboxd", "MediaInfoFootNote": "Full/AudioLanguages/SubtitleLanguages, dosya adında yer alan dilleri filtrelemenize olanak tanıyan bir `:EN+DE` son ekini destekler. Belirli dilleri hariç tutmak için '-DE'yi kullanın. `+` (örneğin `:EN+`) eklenmesi, hariç tutulan dillere bağlı olarak `[EN]`/`[EN+--]`/`[--]` sonucunu verecektir. Örneğin `{MediaInfo Full:EN+DE}`.", - "NoIndexersFound": "Dizinleyici bulunamadı", + "NoIndexersFound": "İndeksleyici bulunamadı", "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Bu 'alındı' bildirimi için iletilen alanları değiştirin", "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "'Manuel Etkileşimlerde' bildirimi için iletilen alanları değiştirin", "Popularity": "Popülerlik", @@ -1498,12 +1498,12 @@ "NotificationsTelegramSettingsIncludeAppNameHelpText": "Farklı uygulamalardan gelen bildirimleri ayırt etmek için isteğe bağlı olarak mesaj başlığının önüne {appName} ekleyin", "NotificationsTwitterSettingsConsumerKeyHelpText": "Twitter uygulamasından kullanıcı anahtarı", "OnApplicationUpdate": "Uygulama Güncellemesinde", - "NotificationsValidationInvalidAccessToken": "Erişim Jetonu geçersiz", + "NotificationsValidationInvalidAccessToken": "Erişim Token'ı geçersiz", "OnManualInteractionRequiredHelpText": "Manuel Etkileşim Gerektiğinde", "OverrideGrabNoQuality": "Kalite seçilmelidir", "PendingDownloadClientUnavailable": "Beklemede - İndirme istemcisi kullanılamıyor", - "ReleaseProfileIndexerHelpText": "Profilin hangi dizinleyiciye uygulanacağını belirtin", - "ReleaseProfileIndexerHelpTextWarning": "Bir sürüm profilinde belirli bir dizinleyicinin ayarlanması, bu profilin yalnızca söz konusu dizinleyicinin yayınlarına uygulanmasına neden olur.", + "ReleaseProfileIndexerHelpText": "Profilin hangi indeksleyiciye uygulanacağını belirtin", + "ReleaseProfileIndexerHelpTextWarning": "Bir sürüm profilinde belirli bir indeksleyicinin ayarlanması, bu profilin yalnızca söz konusu indeksleyicinin yayınlarına uygulanmasına neden olur.", "RemotePathMappingCheckDownloadPermissions": "{appName}, indirilen filmin {path} yolunu görebilir ancak erişemez. Olası izin hatası.", "RemotePathMappingCheckLocalFolderMissing": "Uzaktan indirme istemcisi {downloadClientName}, indirmeleri {path} dizinine yerleştiriyor ancak bu dizin mevcut görünmüyor. Muhtemelen eksik veya yanlış uzak yol eşlemesi.", "NotificationsSettingsUpdateMapPathsTo": "Harita Yolları", @@ -1517,7 +1517,7 @@ "NotificationsTwitterSettingsDirectMessage": "Direk mesaj", "NotificationsTwitterSettingsConsumerKey": "Kullanıcı anahtarı", "NotificationsTwitterSettingsMention": "Bahset", - "NotificationsValidationInvalidAuthenticationToken": "Kimlik Doğrulama Jetonu geçersiz", + "NotificationsValidationInvalidAuthenticationToken": "Kimlik Doğrulama Token'ı geçersiz", "NotificationsValidationUnableToSendTestMessageApiResponse": "Test mesajı gönderilemiyor. API'den yanıt: {error}", "OverrideGrabNoMovie": "Film seçilmelidir", "OnMovieAdded": "Film Eklendiğinde", @@ -1543,7 +1543,7 @@ "Or": "veya", "PasswordConfirmation": "Şifre Tekrarı", "ReleaseHash": "Yayın Karması", - "QueueFilterHasNoItems": "Seçilen kuyruk filtresinde hiç öğe yok", + "QueueFilterHasNoItems": "Seçilen kuyruk filtresinde hiç öğe bulunamadı", "NotificationsValidationInvalidHttpCredentials": "HTTP Kimlik Doğrulama kimlik bilgileri geçersiz: {exceptionMessage}", "RefreshCollections": "Koleksiyonları Yenile", "ReleaseProfiles": "Yayımlama Profilleri", @@ -1553,11 +1553,11 @@ "NotificationsSlackSettingsIconHelpText": "Slack'e gönderilen mesajlar için kullanılan simgeyi değiştirin (Emoji veya URL)", "NotificationsSynologyValidationInvalidOs": "Bir Synology olmalı", "NotificationsTelegramSettingsChatId": "Sohbet Kimliği", - "NotificationsTraktSettingsAccessToken": "Erişim Jetonu", + "NotificationsTraktSettingsAccessToken": "Erişim Token'ı", "NotificationsTraktSettingsAuthUser": "Yetkilendirilmiş Kullanıcı", "NotificationsNtfyValidationAuthorizationRequired": "Yetkilendirme gerekli", "NotificationsPlexSettingsAuthenticateWithPlexTv": "Plex.tv ile kimlik doğrulaması yapın", - "NotificationsPlexSettingsAuthToken": "Kimlik Doğrulama Jetonu", + "NotificationsPlexSettingsAuthToken": "Kimlik Doğrulama Token'ı", "NotificationsSignalSettingsUsernameHelpText": "Signal-api'ye yönelik istekleri doğrulamak için kullanılan kullanıcı adı", "NotificationsSignalValidationSslRequired": "SSL gerekli görünüyor", "NotificationsSimplepushSettingsEvent": "Etkinlik", @@ -1592,14 +1592,14 @@ "NotificationsSlackSettingsChannel": "Kanal", "NotificationsSlackSettingsIcon": "Simge", "NotificationsTelegramSettingsSendSilentlyHelpText": "Mesajı sessizce gönderir. Kullanıcılar sessiz bir bildirim alacak", - "NotificationsTraktSettingsRefreshToken": "Jetonu Yenile", + "NotificationsTraktSettingsRefreshToken": "Token'ı Yenile", "NotificationsTraktSettingsAuthenticateWithTrakt": "Trakt ile kimlik doğrulama", - "NotificationsTwitterSettingsAccessToken": "Erişim Jetonu", + "NotificationsTwitterSettingsAccessToken": "Erişim Token'ı", "NotificationsTraktSettingsExpires": "Süresi doluyor", "NotificationsTwitterSettingsConnectToTwitter": "Twitter / X'e bağlanın", "PreferredProtocol": "Tercih Edilen Protokol", - "NotificationsTelegramSettingsBotToken": "Bot Jetonu", - "NotificationsPushBulletSettingsAccessToken": "Erişim Jetonu", + "NotificationsTelegramSettingsBotToken": "Bot Token'ı", + "NotificationsPushBulletSettingsAccessToken": "Erişim Token'ı", "NotificationsPlexValidationNoMovieLibraryFound": "En az bir Film kitaplığı gerekli", "NotificationsValidationInvalidApiKeyExceptionMessage": "API Anahtarı geçersiz: {exceptionMessage}", "NotificationsValidationUnableToConnectToApi": "{service} API'sine bağlanılamıyor. Sunucu bağlantısı başarısız oldu: ({responseCode}) {exceptionMessage}", @@ -1618,13 +1618,13 @@ "QualityCutoffNotMet": "Kalite sınırı karşılanmadı", "ReleaseGroupFootNote": "İsteğe bağlı olarak, üç nokta (`...`) dahil olmak üzere maksimum bayt sayısına kadar kesmeyi kontrol edin. Sondan (ör. `{Release Group:30}`) veya baştan (ör. `{Release Group:-30}`) kesmenin her ikisi de desteklenir.`).", "RemotePathMappingCheckBadDockerPath": "Docker kullanıyorsunuz; {downloadClientName} indirme istemcisi indirmeleri {path} yoluna yerleştiriyor ancak bu geçerli bir {osName} yolu değil. Uzak yol eşlemelerinizi gözden geçirin ve istemci ayarlarını indirin.", - "RemotePathMappingCheckFilesBadDockerPath": "Docker kullanıyorsunuz; {downloadClientName} indirme istemcisi, {path} yolunda dosyalar bildirdi ancak bu geçerli bir {osName} yolu değil. Uzak yol eşlemelerinizi gözden geçirin ve istemci ayarlarını indirin.", + "RemotePathMappingCheckFilesBadDockerPath": "Docker kullanıyorsunuz; {downloadClientName} istemcinizin bildirdiği dosyaları {path} dizinine indirir ancak bu geçerli bir {osName} yolu değil. Uzak yol eşlemelerinizi ve indirme istemcisi ayarlarınızı inceleyin.", "ReleaseGroups": "Yayımlama Grupları", "NotificationsPushBulletSettingSenderIdHelpText": "Bildirimlerin gönderileceği cihaz kimliği, pushbullet.com'da cihazın URL'sinde Device_iden kullanın (kendinizden göndermek için boş bırakın)", "NotificationsPushBulletSettingsDeviceIds": "Cihaz Kimlikleri", "NotificationsSettingsUpdateMapPathsFrom": "Harita Yolları", "NotificationsPushBulletSettingsDeviceIdsHelpText": "Cihaz kimliklerinin listesi (tüm cihazlara göndermek için boş bırakın)", - "NotificationsTwitterSettingsAccessTokenSecret": "Erişim Jetonu Gizliliği", + "NotificationsTwitterSettingsAccessTokenSecret": "Erişim Token Gizliliği", "NotificationsPushBulletSettingsChannelTags": "Kanal Etiketleri", "NotificationsSettingsWebhookMethod": "Yöntem", "NotificationsSettingsWebhookMethodHelpText": "Web hizmetine göndermek için hangi HTTP yönteminin kullanılacağı", @@ -1655,7 +1655,7 @@ "ShowTmdbRating": "TMDb Derecelendirmesini Göster", "SkipRedownload": "Yeniden İndirmeyi Atla", "RestartRequiredToApplyChanges": "{appName}, değişikliklerin uygulanabilmesi için yeniden başlatmayı gerektiriyor. Şimdi yeniden başlatmak istiyor musunuz?", - "SetIndexerFlags": "Dizinleyici Bayraklarını Ayarla", + "SetIndexerFlags": "İndeksleyici Bayraklarını Ayarla", "ShowImdbRating": "IMDb Derecelendirmesini Göster", "ShowRottenTomatoesRatingHelpText": "Posterin altında Tomato derecelendirmesini göster", "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText": "Bu, dosyaları taşımak yerine {appName}'e Kopyalama veya Sabit Bağlantı kurma talimatını verecektir (ayarlara/sistem yapılandırmasına bağlı olarak)", @@ -1694,7 +1694,7 @@ "RemoveFromDownloadClientHint": "İndirilenleri ve dosyaları indirme istemcisinden kaldırır", "RemoveQueueItemsRemovalMethodHelpTextWarning": "'İndirme İstemcisinden Kaldır', indirilenleri ve dosyaları indirme istemcisinden kaldıracaktır.", "ResetAPIKeyMessageText": "API Anahtarınızı sıfırlamak istediğinizden emin misiniz?", - "SecretToken": "Gizlilik Jetonu", + "SecretToken": "Gizlilik Token'ı", "StopSelecting": "Düzenlemeden Çık", "SearchMoviesConfirmationMessageText": "{count} film için arama yapmak istediğinizden emin misiniz?", "ShowCollectionDetails": "Koleksiyon Durumunu Göster", @@ -1728,7 +1728,7 @@ "UnableToLoadCollections": "Koleksiyonlar yüklenemiyor", "RemoveQueueItem": "Kaldır - {sourceTitle}", "RemoveSelectedItems": "Seçili öğeleri kaldır", - "SelectIndexerFlags": "Dizinleyici Bayraklarını Seçin", + "SelectIndexerFlags": "İndeksleyici Bayraklarını Seçin", "ShowImdbRatingHelpText": "Posterin altında IMDb derecelendirmesini göster", "SearchOnAddCollectionHelpText": "Kitaplığa eklendiğinde bu koleksiyondaki filmleri arayın", "TorrentBlackholeSaveMagnetFiles": "Magnet Dosyalarını Kaydet", @@ -1740,7 +1740,7 @@ "SearchMoviesOnAdd": "Filmleri Ara ve Ekle", "TablePageSize": "Sayfa Boyutu", "RestartRequiredWindowsService": "{appName} hizmetini hangi kullanıcının çalıştırdığına bağlı olarak, hizmetin otomatik olarak başlamasından önce {appName} hizmetini yönetici olarak bir kez yeniden başlatmanız gerekebilir.", - "SetIndexerFlagsModalTitle": "{modalTitle} - Dizinleyici Bayraklarını Ayarla", + "SetIndexerFlagsModalTitle": "{modalTitle} - İndeksleyici Bayraklarını Ayarla", "Space": "Boşluk", "SupportedAutoTaggingProperties": "{appName}, otomatik etiketleme kuralları için takip özelliklerini destekler", "Theme": "Tema", @@ -1769,7 +1769,7 @@ "CutoffUnmetNoItems": "Karşılanmayan son öğe yok", "External": "Harici", "InteractiveSearchModalHeaderTitle": "İnteraktif Arama - {title}", - "MassSearchCancelWarning": "Bu işlem, {appName} yeniden başlatılmadan veya tüm dizin oluşturucularınız devre dışı bırakılmadan başlatılır ise iptal edilemez.", + "MassSearchCancelWarning": "Bu, {appName} uygulamasını yeniden başlatmadan veya tüm İndeksleyiciler devre dışı bırakılmadan başlatılır ise iptal edilemez.", "MonitorSelected": "Seçilenleri Bırak", "MovieIsNotMonitored": "Film takip edilemiyor", "SearchForAllMissingMovies": "Eksik tüm filmleri arayın", diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index 9aca50298b..0aeb3b6852 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -1,17 +1,17 @@ { "About": "關於", "Add": "新增", - "AcceptConfirmationModal": "接受確認模式", - "Actions": "執行", + "AcceptConfirmationModal": "接受確認對話框", + "Actions": "動作", "Activity": "‎活動‎", "AddIndexer": "新增索引", "AddingTag": "新增標籤", - "AddDownloadClient": "新增下載器", + "AddDownloadClient": "加入下載用戶端", "Added": "已新增", "Age": "年齡", "All": "全部", "Analytics": "分析", - "AddCustomFormat": "新增自定義格式", + "AddCustomFormat": "加入自訂格式", "AddDelayProfile": "加入延遲設定", "AddedToDownloadQueue": "已添加到下載隊列", "EditCustomFormat": "新增自定義格式", @@ -74,7 +74,7 @@ "EditQualityProfile": "編輯品質設定檔", "Announced": "已公布", "ApiKey": "API 金鑰", - "AddExclusion": "新增列外", + "AddExclusion": "加入排除", "AddListExclusionMovieHelpText": "防止清單中的電影被添加到 {appName} 中", "AnalyticsEnabledHelpText": "將使用和錯誤資訊匿名傳送至{appName}的伺服器。這些資訊包括您的瀏覽器資訊、使用的{appName} WebUI頁面、錯誤報告,以及作業系統和執行時版本。我們將使用這些資訊來優先處理功能和錯誤修復。", "AddQualityProfile": "加入品質設定檔", @@ -216,11 +216,11 @@ "ImportLists": "導入列表", "Movie": "電影", "Filters": "篩選器", - "AddIndexerError": "無法加入新的條件,請重新嘗試。", + "AddIndexerError": "無法加入新的索引器,請重試。", "AddNotificationError": "無法加入新的條件,請重新嘗試。", "AddAutoTagError": "無法加入新的自動標籤,請重新嘗試。", "AddConditionError": "無法加入新的條件,請重新嘗試。", - "AddDownloadClientError": "無法加入新的條件,請重新嘗試。", + "AddDownloadClientError": "無法加入下載用戶端,請重試。", "Release": "發布", "Theme": "主題", "Password": "密碼", @@ -242,10 +242,10 @@ "YouCanAlsoSearch": "您也可以使用該電影的TMDbID來搜尋。例如「tmdb:71663」", "ImportListExclusions": "新增匯入排除清單", "AddImportListExclusionError": "無法加入新的條件,請重新嘗試。", - "AddListError": "無法加入新的自動標籤,請重新嘗試。", + "AddListError": "無法加入新的清單,請重試。", "AddQualityProfileError": "無法加入新的條件,請重新嘗試。", - "AddCustomFormatError": "無法加入新的自動標籤,請重新嘗試。", - "AddDelayProfileError": "無法加入新的條件,請重新嘗試。", + "AddCustomFormatError": "無法加入自訂格式,請重試。", + "AddDelayProfileError": "無法加入新的延遲配置,請重新嘗試。", "DeleteImportListExclusion": "新增排除清單", "Letterboxd": "文字方框", "Discord": "Discord", @@ -266,5 +266,21 @@ "UiSettings": "使用者介面設定", "UiSettingsLoadError": "無法載入 UI 設定", "HistoryLoadError": "無法載入歷史記錄", - "UiLanguageHelpText": "{appName} 介面所使用的語言" + "UiLanguageHelpText": "{appName} 介面所使用的語言", + "AlternativeTitlesLoadError": "無法加載其他標題。", + "AddNewRestriction": "加入新的限制", + "AddRemotePathMappingError": "無法加入新的遠程路徑對應,請重試。", + "AutoRedownloadFailed": "失敗時重新下載", + "AudioLanguages": "音頻語言", + "AuthenticationMethod": "驗證方式", + "AnalyseVideoFilesHelpText": "從文件中提取影像資訊,如解析度、運行環境和編解碼器資訊。這需要 {appName} 在掃描期間讀取文件並可能導致高磁盤或網絡佔用。", + "AuthenticationMethodHelpTextWarning": "請選擇一個有效的驗證方式", + "AuthenticationRequiredHelpText": "更改需要進行驗證的請求。除非你了解其中的風險,否則請勿修改。", + "AuthenticationRequired": "需要驗證", + "AuthenticationRequiredWarning": "為防止未經認證的遠程訪問,{appName} 現需要啟用身份認證。您可以選擇禁用本地地址的身份認證。", + "AnnouncedMovieAvailabilityDescription": "一但添加至 {appName} 便被視爲可用的電影。", + "AuthenticationRequiredPasswordHelpTextWarning": "請輸入新密碼", + "AuthenticationRequiredUsernameHelpTextWarning": "請輸入新用戶名", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "確認新密碼", + "AutoRedownloadFailedFromInteractiveSearch": "失敗時重新下載來自手動搜索的資源" } From 4051cf3d8016f2e386ae786c06466530aa636f0d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 2 Jan 2025 23:16:48 +0200 Subject: [PATCH 160/579] Fixed: Increase rate limit for PassThePopcorn --- src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcorn.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcorn.cs b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcorn.cs index e81991eb45..3c42f2a283 100644 --- a/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcorn.cs +++ b/src/NzbDrone.Core/Indexers/PassThePopcorn/PassThePopcorn.cs @@ -1,4 +1,5 @@ -using NLog; +using System; +using NLog; using NzbDrone.Common.Http; using NzbDrone.Core.Configuration; using NzbDrone.Core.Parser; @@ -12,6 +13,7 @@ public class PassThePopcorn : HttpIndexerBase public override bool SupportsRss => true; public override bool SupportsSearch => true; public override int PageSize => 50; + public override TimeSpan RateLimit => TimeSpan.FromSeconds(4); public PassThePopcorn(IHttpClient httpClient, IIndexerStatusService indexerStatusService, From c0ebbee7c93322c26a4498b3affcd79474afa087 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 5 Jan 2025 13:52:57 +0200 Subject: [PATCH 161/579] Bump version to 5.18.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c26ecb5020..e5af45f76e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.17.2' + majorVersion: '5.18.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 5f03e7142a24a73b14ad9b7aa059f14d87e5ffa8 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sun, 5 Jan 2025 02:56:49 +0100 Subject: [PATCH 162/579] Fixed: qBittorrent Ratio Limit Check (cherry picked from commit 4dcc015fb19ceb57d2e8f4985c5137e765829d1c) --- .../QBittorrentTests/QBittorrentFixture.cs | 48 +++++++++++++++++++ .../Clients/QBittorrent/QBittorrent.cs | 4 +- 2 files changed, 50 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs index ef7161ef5b..0a4e44f7f5 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/QBittorrentTests/QBittorrentFixture.cs @@ -711,6 +711,30 @@ public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached item.CanMoveFiles.Should().BeTrue(); } + [TestCase("pausedUP")] + [TestCase("stoppedUP")] + public void should_be_removable_and_should_allow_move_files_if_max_ratio_reached_after_rounding_and_paused(string state) + { + GivenGlobalSeedLimits(1.0f); + GivenCompletedTorrent(state, ratio: 1.1006066990976857f); + + var item = Subject.GetItems().Single(); + item.CanBeRemoved.Should().BeTrue(); + item.CanMoveFiles.Should().BeTrue(); + } + + [TestCase("pausedUP")] + [TestCase("stoppedUP")] + public void should_be_removable_and_should_allow_move_files_if_just_under_max_ratio_reached_after_rounding_and_paused(string state) + { + GivenGlobalSeedLimits(1.0f); + GivenCompletedTorrent(state, ratio: 0.9999f); + + var item = Subject.GetItems().Single(); + item.CanBeRemoved.Should().BeTrue(); + item.CanMoveFiles.Should().BeTrue(); + } + [TestCase("pausedUP")] [TestCase("stoppedUP")] public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_and_paused(string state) @@ -723,6 +747,30 @@ public void should_be_removable_and_should_allow_move_files_if_overridden_max_ra item.CanMoveFiles.Should().BeTrue(); } + [TestCase("pausedUP")] + [TestCase("stoppedUP")] + public void should_be_removable_and_should_allow_move_files_if_overridden_max_ratio_reached_after_rounding_and_paused(string state) + { + GivenGlobalSeedLimits(2.0f); + GivenCompletedTorrent(state, ratio: 1.1006066990976857f, ratioLimit: 1.1f); + + var item = Subject.GetItems().Single(); + item.CanBeRemoved.Should().BeTrue(); + item.CanMoveFiles.Should().BeTrue(); + } + + [TestCase("pausedUP")] + [TestCase("stoppedUP")] + public void should_be_removable_and_should_allow_move_files_if_just_under_overridden_max_ratio_reached_after_rounding_and_paused(string state) + { + GivenGlobalSeedLimits(2.0f); + GivenCompletedTorrent(state, ratio: 0.9999f, ratioLimit: 1.0f); + + var item = Subject.GetItems().Single(); + item.CanBeRemoved.Should().BeTrue(); + item.CanMoveFiles.Should().BeTrue(); + } + [TestCase("pausedUP")] [TestCase("stoppedUP")] public void should_not_be_removable_if_overridden_max_ratio_not_reached_and_paused(string state) diff --git a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs index d533354650..f5c9fe450d 100644 --- a/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrent.cs @@ -630,14 +630,14 @@ protected bool HasReachedSeedLimit(QBittorrentTorrent torrent, QBittorrentPrefer { if (torrent.RatioLimit >= 0) { - if (torrent.Ratio >= torrent.RatioLimit) + if (torrent.RatioLimit - torrent.Ratio <= 0.001f) { return true; } } else if (torrent.RatioLimit == -2 && config.MaxRatioEnabled) { - if (Math.Round(torrent.Ratio, 2) >= config.MaxRatio) + if (config.MaxRatio - torrent.Ratio <= 0.001f) { return true; } From f507d5154ec162df11c17d65c3f1d73b6cbe0c2e Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sun, 5 Jan 2025 02:58:24 +0100 Subject: [PATCH 163/579] Fixed: Listening on all IPv4 Addresses (cherry picked from commit 035c474f10c257331a5f47e863d24af82537e335) --- src/NzbDrone.Core/Validation/IpValidation.cs | 6 ------ src/Radarr.Api.V3/Config/HostConfigController.cs | 1 - 2 files changed, 7 deletions(-) diff --git a/src/NzbDrone.Core/Validation/IpValidation.cs b/src/NzbDrone.Core/Validation/IpValidation.cs index eb5863caa9..f4afa1f66b 100644 --- a/src/NzbDrone.Core/Validation/IpValidation.cs +++ b/src/NzbDrone.Core/Validation/IpValidation.cs @@ -1,5 +1,4 @@ using FluentValidation; -using FluentValidation.Validators; using NzbDrone.Common.Extensions; namespace NzbDrone.Core.Validation @@ -10,10 +9,5 @@ public static IRuleBuilderOptions ValidIpAddress(this IRuleBuilder { return ruleBuilder.Must(x => x.IsValidIpAddress()).WithMessage("Must contain wildcard (*) or a valid IP Address"); } - - public static IRuleBuilderOptions NotListenAllIp4Address(this IRuleBuilder ruleBuilder) - { - return ruleBuilder.SetValidator(new RegularExpressionValidator(@"^(?!0\.0\.0\.0)")).WithMessage("Use * instead of 0.0.0.0"); - } } } diff --git a/src/Radarr.Api.V3/Config/HostConfigController.cs b/src/Radarr.Api.V3/Config/HostConfigController.cs index 503b4eea4c..1580ce5d63 100644 --- a/src/Radarr.Api.V3/Config/HostConfigController.cs +++ b/src/Radarr.Api.V3/Config/HostConfigController.cs @@ -33,7 +33,6 @@ public HostConfigController(IConfigFileProvider configFileProvider, SharedValidator.RuleFor(c => c.BindAddress) .ValidIpAddress() - .NotListenAllIp4Address() .When(c => c.BindAddress != "*" && c.BindAddress != "localhost"); SharedValidator.RuleFor(c => c.Port).ValidPort(); From f8704a16557669aa56f1eb8578ee2a935b59721d Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sun, 14 Jan 2024 21:57:42 +0100 Subject: [PATCH 164/579] Translate backend: Autotagging + CF specs Signed-off-by: Stevie Robinson (cherry picked from commit de1cc25c903924fecbca79fedb458d729ae584fd) Towards #9647 --- .../Specifications/GenreSpecification.cs | 2 +- .../OriginalLanguageSpecification.cs | 2 +- .../QualityProfileSpecification.cs | 2 +- .../Specifications/RootFolderSpecification.cs | 2 +- .../Specifications/RuntimeSpecification.cs | 4 ++-- .../Specifications/YearSpecification.cs | 4 ++-- .../Specifications/LanguageSpecification.cs | 2 +- .../QualityModifierSpecification.cs | 2 +- .../Specifications/ResolutionSpecification.cs | 2 +- .../Specifications/SizeSpecification.cs | 4 ++-- .../Specifications/SourceSpecification.cs | 2 +- .../Specifications/YearSpecification.cs | 4 ++-- src/NzbDrone.Core/Localization/Core/en.json | 18 ++++++++++++++++++ src/Radarr.Http/ClientSchema/SchemaBuilder.cs | 7 ++++++- 14 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/GenreSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/GenreSpecification.cs index c4548888ad..77de3a541d 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/GenreSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/GenreSpecification.cs @@ -23,7 +23,7 @@ public class GenreSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Genre"; - [FieldDefinition(1, Label = "Genre(s)", Type = FieldType.Tag)] + [FieldDefinition(1, Label = "AutoTaggingSpecificationGenre", Type = FieldType.Tag)] public IEnumerable Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/OriginalLanguageSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/OriginalLanguageSpecification.cs index 3e47e19252..547fb381f9 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/OriginalLanguageSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/OriginalLanguageSpecification.cs @@ -21,7 +21,7 @@ public class OriginalLanguageSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Original Language"; - [FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(OriginalLanguageFieldConverter))] + [FieldDefinition(1, Label = "AutoTaggingSpecificationOriginalLanguage", Type = FieldType.Select, SelectOptions = typeof(OriginalLanguageFieldConverter))] public int Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/QualityProfileSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/QualityProfileSpecification.cs index a698bc015c..e7a3e23716 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/QualityProfileSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/QualityProfileSpecification.cs @@ -20,7 +20,7 @@ public class QualityProfileSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Quality Profile"; - [FieldDefinition(1, Label = "Quality Profile", Type = FieldType.QualityProfile)] + [FieldDefinition(1, Label = "AutoTaggingSpecificationQualityProfile", Type = FieldType.QualityProfile)] public int Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/RootFolderSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/RootFolderSpecification.cs index 2ff8bb24d9..553a4ca576 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/RootFolderSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/RootFolderSpecification.cs @@ -22,7 +22,7 @@ public class RootFolderSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Root Folder"; - [FieldDefinition(1, Label = "Root Folder", Type = FieldType.RootFolder)] + [FieldDefinition(1, Label = "AutoTaggingSpecificationRootFolder", Type = FieldType.RootFolder)] public string Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/RuntimeSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/RuntimeSpecification.cs index 9bf11da62c..4b89577fc8 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/RuntimeSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/RuntimeSpecification.cs @@ -24,10 +24,10 @@ public class RuntimeSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Runtime"; - [FieldDefinition(1, Label = "Minimum Runtime", Type = FieldType.Number)] + [FieldDefinition(1, Label = "AutoTaggingSpecificationMinimumRuntime", Type = FieldType.Number, Unit = "minutes")] public int Min { get; set; } - [FieldDefinition(2, Label = "Maximum Runtime", Type = FieldType.Number)] + [FieldDefinition(2, Label = "AutoTaggingSpecificationMaximumRuntime", Type = FieldType.Number, Unit = "minutes")] public int Max { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/YearSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/YearSpecification.cs index 966af681b7..b6b57187c3 100644 --- a/src/NzbDrone.Core/AutoTagging/Specifications/YearSpecification.cs +++ b/src/NzbDrone.Core/AutoTagging/Specifications/YearSpecification.cs @@ -23,10 +23,10 @@ public class YearSpecification : AutoTaggingSpecificationBase public override int Order => 1; public override string ImplementationName => "Year"; - [FieldDefinition(1, Label = "Minimum Year", Type = FieldType.Number)] + [FieldDefinition(1, Label = "AutoTaggingSpecificationMinimumYear", Type = FieldType.Number)] public int Min { get; set; } - [FieldDefinition(2, Label = "Maximum Year", Type = FieldType.Number)] + [FieldDefinition(2, Label = "AutoTaggingSpecificationMaximumYear", Type = FieldType.Number)] public int Max { get; set; } protected override bool IsSatisfiedByWithoutNegate(Movie movie) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs index 516c8196c9..49a6dff46f 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/LanguageSpecification.cs @@ -27,7 +27,7 @@ public class LanguageSpecification : CustomFormatSpecificationBase public override int Order => 3; public override string ImplementationName => "Language"; - [FieldDefinition(1, Label = "Language", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))] + [FieldDefinition(1, Label = "CustomFormatsSpecificationLanguage", Type = FieldType.Select, SelectOptions = typeof(LanguageFieldConverter))] public int Value { get; set; } [FieldDefinition(1, Label = "CustomFormatsSpecificationExceptLanguage", HelpText = "CustomFormatsSpecificationExceptLanguageHelpText", Type = FieldType.Checkbox)] diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs index 3be30fe41a..d5a1cf7872 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/QualityModifierSpecification.cs @@ -28,7 +28,7 @@ public class QualityModifierSpecification : CustomFormatSpecificationBase public override int Order => 7; public override string ImplementationName => "Quality Modifier"; - [FieldDefinition(1, Label = "Quality Modifier", Type = FieldType.Select, SelectOptions = typeof(Modifier))] + [FieldDefinition(1, Label = "CustomFormatsSpecificationQualityModifier", Type = FieldType.Select, SelectOptions = typeof(Modifier))] public int Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs index 6889605a49..a7866d0a02 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/ResolutionSpecification.cs @@ -20,7 +20,7 @@ public class ResolutionSpecification : CustomFormatSpecificationBase public override int Order => 6; public override string ImplementationName => "Resolution"; - [FieldDefinition(1, Label = "Resolution", Type = FieldType.Select, SelectOptions = typeof(Resolution))] + [FieldDefinition(1, Label = "CustomFormatsSpecificationResolution", Type = FieldType.Select, SelectOptions = typeof(Resolution))] public int Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs index fe873f9ec2..039d446e75 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/SizeSpecification.cs @@ -21,10 +21,10 @@ public class SizeSpecification : CustomFormatSpecificationBase public override int Order => 8; public override string ImplementationName => "Size"; - [FieldDefinition(1, Label = "Minimum Size", HelpText = "Release must be greater than this size", Unit = "GB", Type = FieldType.Number)] + [FieldDefinition(1, Label = "CustomFormatsSpecificationMinimumSize", HelpText = "CustomFormatsSpecificationMinimumSizeHelpText", Unit = "GB", Type = FieldType.Number)] public double Min { get; set; } - [FieldDefinition(1, Label = "Maximum Size", HelpText = "Release must be less than or equal to this size", Unit = "GB", Type = FieldType.Number)] + [FieldDefinition(1, Label = "CustomFormatsSpecificationMaximumSize", HelpText = "CustomFormatsSpecificationMaximumSizeHelpText", Unit = "GB", Type = FieldType.Number)] public double Max { get; set; } protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs index e150318ead..b5d3566996 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/SourceSpecification.cs @@ -20,7 +20,7 @@ public class SourceSpecification : CustomFormatSpecificationBase public override int Order => 5; public override string ImplementationName => "Source"; - [FieldDefinition(1, Label = "Source", Type = FieldType.Select, SelectOptions = typeof(QualitySource))] + [FieldDefinition(1, Label = "CustomFormatsSpecificationSource", Type = FieldType.Select, SelectOptions = typeof(QualitySource))] public int Value { get; set; } protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) diff --git a/src/NzbDrone.Core/CustomFormats/Specifications/YearSpecification.cs b/src/NzbDrone.Core/CustomFormats/Specifications/YearSpecification.cs index 87bf7ba27d..1a146936a0 100644 --- a/src/NzbDrone.Core/CustomFormats/Specifications/YearSpecification.cs +++ b/src/NzbDrone.Core/CustomFormats/Specifications/YearSpecification.cs @@ -20,10 +20,10 @@ public class YearSpecification : CustomFormatSpecificationBase public override int Order => 10; public override string ImplementationName => "Year"; - [FieldDefinition(1, Label = "Minimum Year", Type = FieldType.Number)] + [FieldDefinition(1, Label = "CustomFormatsSpecificationMinimumYear", Type = FieldType.Number)] public int Min { get; set; } - [FieldDefinition(2, Label = "Maximum Year", Type = FieldType.Number)] + [FieldDefinition(2, Label = "CustomFormatsSpecificationMaximumYear", Type = FieldType.Number)] public int Max { get; set; } protected override bool IsSatisfiedByWithoutNegate(CustomFormatInput input) diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index cff52025f1..a86df4f69d 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -116,6 +116,14 @@ "AutoTaggingLoadError": "Unable to load auto tagging", "AutoTaggingNegateHelpText": "If checked, the auto tagging rule will not apply if this {implementationName} condition matches.", "AutoTaggingRequiredHelpText": "This {implementationName} condition must match for the auto tagging rule to apply. Otherwise a single {implementationName} match is sufficient.", + "AutoTaggingSpecificationGenre": "Genre(s)", + "AutoTaggingSpecificationMaximumRuntime": "Maximum Runtime", + "AutoTaggingSpecificationMaximumYear": "Maximum Year", + "AutoTaggingSpecificationMinimumRuntime": "Minimum Runtime", + "AutoTaggingSpecificationMinimumYear": "Minimum Year", + "AutoTaggingSpecificationOriginalLanguage": "Language", + "AutoTaggingSpecificationQualityProfile": "Quality Profile", + "AutoTaggingSpecificationRootFolder": "Root Folder", "AutoTaggingSpecificationTag": "Tag", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Movies deleted from the disk are automatically unmonitored in {appName}", "Automatic": "Automatic", @@ -270,8 +278,18 @@ "CustomFormatsSpecificationExceptLanguage": "Except Language", "CustomFormatsSpecificationExceptLanguageHelpText": "Matches if any language other than the selected language is present", "CustomFormatsSpecificationFlag": "Flag", + "CustomFormatsSpecificationLanguage": "Language", + "CustomFormatsSpecificationMaximumSize": "Maximum Size", + "CustomFormatsSpecificationMaximumSizeHelpText": "Release must be less than or equal to this size", + "CustomFormatsSpecificationMaximumYear": "Maximum Year", + "CustomFormatsSpecificationMinimumSize": "Minimum Size", + "CustomFormatsSpecificationMinimumSizeHelpText": "Release must be greater than this size", + "CustomFormatsSpecificationMinimumYear": "Minimum Year", + "CustomFormatsSpecificationQualityModifier": "Quality Modifier", "CustomFormatsSpecificationRegularExpression": "Regular Expression", "CustomFormatsSpecificationRegularExpressionHelpText": "Custom Format RegEx is Case Insensitive", + "CustomFormatsSpecificationResolution": "Resolution", + "CustomFormatsSpecificationSource": "Source", "Cutoff": "Cutoff", "CutoffNotMet": "Cutoff Not Met", "CutoffUnmet": "Cutoff Unmet", diff --git a/src/Radarr.Http/ClientSchema/SchemaBuilder.cs b/src/Radarr.Http/ClientSchema/SchemaBuilder.cs index 2be2743381..88838a2b5c 100644 --- a/src/Radarr.Http/ClientSchema/SchemaBuilder.cs +++ b/src/Radarr.Http/ClientSchema/SchemaBuilder.cs @@ -228,10 +228,15 @@ private static List GetSelectOptions(Type selectOptions) if (attrib != null) { + var label = attrib.Label.IsNotNullOrWhiteSpace() + ? _localizationService.GetLocalizedString(attrib.Label, + GetTokens(selectOptions, attrib.Label, TokenField.Label)) + : attrib.Label; + return new SelectOption { Value = value, - Name = attrib.Label ?? name, + Name = label ?? name, Order = attrib.Order, Hint = attrib.Hint ?? $"({value})" }; From e36de8ab8d9630ab542268ee5b870af2945a70b0 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 6 Jan 2025 04:24:29 +0200 Subject: [PATCH 165/579] New: Auto tag based on movie status --- .../Specifications/StatusSpecification.cs | 43 +++++++++++++++++++ src/NzbDrone.Core/Localization/Core/en.json | 1 + 2 files changed, 44 insertions(+) create mode 100644 src/NzbDrone.Core/AutoTagging/Specifications/StatusSpecification.cs diff --git a/src/NzbDrone.Core/AutoTagging/Specifications/StatusSpecification.cs b/src/NzbDrone.Core/AutoTagging/Specifications/StatusSpecification.cs new file mode 100644 index 0000000000..e161bc21b1 --- /dev/null +++ b/src/NzbDrone.Core/AutoTagging/Specifications/StatusSpecification.cs @@ -0,0 +1,43 @@ +using System; +using FluentValidation; +using NzbDrone.Core.Annotations; +using NzbDrone.Core.Movies; +using NzbDrone.Core.Validation; + +namespace NzbDrone.Core.AutoTagging.Specifications +{ + public class StatusSpecificationValidator : AbstractValidator + { + public StatusSpecificationValidator() + { + RuleFor(c => c.Status).Custom((statusType, context) => + { + if (!Enum.IsDefined(typeof(MovieStatusType), statusType)) + { + context.AddFailure($"Invalid status type condition value: {statusType}"); + } + }); + } + } + + public class StatusSpecification : AutoTaggingSpecificationBase + { + private static readonly StatusSpecificationValidator Validator = new (); + + public override int Order => 1; + public override string ImplementationName => "Status"; + + [FieldDefinition(1, Label = "AutoTaggingSpecificationStatus", Type = FieldType.Select, SelectOptions = typeof(MovieStatusType))] + public int Status { get; set; } + + protected override bool IsSatisfiedByWithoutNegate(Movie movie) + { + return movie?.MovieMetadata?.Value?.Status == (MovieStatusType)Status; + } + + public override NzbDroneValidationResult Validate() + { + return new NzbDroneValidationResult(Validator.Validate(this)); + } + } +} diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index a86df4f69d..71da4174a8 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -124,6 +124,7 @@ "AutoTaggingSpecificationOriginalLanguage": "Language", "AutoTaggingSpecificationQualityProfile": "Quality Profile", "AutoTaggingSpecificationRootFolder": "Root Folder", + "AutoTaggingSpecificationStatus": "Status", "AutoTaggingSpecificationTag": "Tag", "AutoUnmonitorPreviouslyDownloadedMoviesHelpText": "Movies deleted from the disk are automatically unmonitored in {appName}", "Automatic": "Automatic", From 7ba9603449252f24fa99c47aef4706e1b52b3c1d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 6 Jan 2025 12:28:51 +0200 Subject: [PATCH 166/579] Fixed: Sending Discord notifications with images without absolute links --- src/NzbDrone.Core/Notifications/Discord/Discord.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index a3ac651ce6..ec2fd9c3e6 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -270,7 +270,7 @@ public override void OnMovieAdded(Movie movie) { embed.Thumbnail = new DiscordImage { - Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url + Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl }; } @@ -278,7 +278,7 @@ public override void OnMovieAdded(Movie movie) { embed.Image = new DiscordImage { - Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url + Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.RemoteUrl }; } @@ -327,7 +327,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { embed.Thumbnail = new DiscordImage { - Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.Url + Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Poster)?.RemoteUrl }; } @@ -335,7 +335,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { embed.Image = new DiscordImage { - Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.Url + Url = movie.MovieMetadata.Value.Images.FirstOrDefault(x => x.CoverType == MediaCoverTypes.Fanart)?.RemoteUrl }; } From 5fac3486130df3b316dd882d676ca13ecb697b59 Mon Sep 17 00:00:00 2001 From: Qstick Date: Mon, 30 Dec 2024 22:22:19 -0600 Subject: [PATCH 167/579] Bump SonarCloud azure extension to 3.X (cherry picked from commit 7b8e352d876cd8f8e5b6296f0c3938bed4db8bb8) --- azure-pipelines.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e5af45f76e..ffb396b4f8 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1205,12 +1205,12 @@ stages: submodules: true - powershell: Set-Service SCardSvr -StartupType Manual displayName: Enable Windows Test Service - - task: SonarCloudPrepare@2 + - task: SonarCloudPrepare@3 condition: eq(variables['System.PullRequest.IsFork'], 'False') inputs: SonarCloud: 'SonarCloud' organization: 'radarr' - scannerMode: 'MSBuild' + scannerMode: 'dotnet' projectKey: 'Radarr_Radarr' projectName: 'Radarr' projectVersion: '$(radarrVersion)' @@ -1223,7 +1223,7 @@ stages: ./build.sh --backend -f net6.0 -r win-x64 TEST_DIR=_tests/net6.0/win-x64/publish/ ./test.sh Windows Unit Coverage displayName: Coverage Unit Tests - - task: SonarCloudAnalyze@2 + - task: SonarCloudAnalyze@3 condition: eq(variables['System.PullRequest.IsFork'], 'False') displayName: Publish SonarCloud Results - task: reportgenerator@5.3.11 From 927eb389455db4d2a878d1b8452eac039be0f6a0 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 12 Jan 2025 15:16:00 +0200 Subject: [PATCH 168/579] Bump version to 5.18.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index ffb396b4f8..fd7a89c059 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.18.0' + majorVersion: '5.18.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 18032cc83bfbcc67cd0f3c14ba493f4946707286 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 11 Jan 2025 08:33:21 +0000 Subject: [PATCH 169/579] Multiple Translations updated by Weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ignore-downstream Co-authored-by: Ano10 Co-authored-by: Dimitar \"Topper\" Maznekov Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Mickaël O Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 9 +- src/NzbDrone.Core/Localization/Core/bg.json | 86 ++++++++++++++++-- src/NzbDrone.Core/Localization/Core/ca.json | 15 +++- src/NzbDrone.Core/Localization/Core/cs.json | 58 ++++++++++++- src/NzbDrone.Core/Localization/Core/da.json | 10 ++- src/NzbDrone.Core/Localization/Core/de.json | 18 +++- src/NzbDrone.Core/Localization/Core/el.json | 9 +- src/NzbDrone.Core/Localization/Core/es.json | 21 ++++- src/NzbDrone.Core/Localization/Core/fi.json | 39 ++++++--- src/NzbDrone.Core/Localization/Core/fr.json | 53 +++++++++-- src/NzbDrone.Core/Localization/Core/he.json | 9 +- src/NzbDrone.Core/Localization/Core/hi.json | 9 +- src/NzbDrone.Core/Localization/Core/hr.json | 9 +- src/NzbDrone.Core/Localization/Core/hu.json | 18 +++- src/NzbDrone.Core/Localization/Core/id.json | 5 +- src/NzbDrone.Core/Localization/Core/is.json | 9 +- src/NzbDrone.Core/Localization/Core/it.json | 18 +++- src/NzbDrone.Core/Localization/Core/ja.json | 9 +- src/NzbDrone.Core/Localization/Core/ko.json | 9 +- .../Localization/Core/nb_NO.json | 7 +- src/NzbDrone.Core/Localization/Core/nl.json | 15 +++- src/NzbDrone.Core/Localization/Core/pl.json | 10 ++- src/NzbDrone.Core/Localization/Core/pt.json | 10 ++- .../Localization/Core/pt_BR.json | 21 ++++- src/NzbDrone.Core/Localization/Core/ro.json | 9 +- src/NzbDrone.Core/Localization/Core/ru.json | 18 +++- src/NzbDrone.Core/Localization/Core/sk.json | 7 +- src/NzbDrone.Core/Localization/Core/sv.json | 9 +- src/NzbDrone.Core/Localization/Core/th.json | 9 +- src/NzbDrone.Core/Localization/Core/tr.json | 87 +++++++++++-------- src/NzbDrone.Core/Localization/Core/uk.json | 18 +++- src/NzbDrone.Core/Localization/Core/vi.json | 9 +- .../Localization/Core/zh_CN.json | 18 +++- .../Localization/Core/zh_TW.json | 7 +- 34 files changed, 581 insertions(+), 86 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 66253916e4..a26ea92261 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1076,5 +1076,12 @@ "Clone": "قريب", "AllTitles": "كل الملفات", "AddReleaseProfile": "تحرير ملف تعريف التأخير", - "DownloadClientUnavailable": "عميل التنزيل غير متوفر" + "DownloadClientUnavailable": "عميل التنزيل غير متوفر", + "AutoTaggingSpecificationOriginalLanguage": "لغة", + "AutoTaggingSpecificationQualityProfile": "ملف الجودة", + "AutoTaggingSpecificationRootFolder": "المجلد الرئيسي", + "AutoTaggingSpecificationStatus": "الحالة", + "CustomFormatsSpecificationLanguage": "لغة", + "CustomFormatsSpecificationMaximumSize": "أكبر مقاس", + "CustomFormatsSpecificationSource": "مصدر" } diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index eaac7645dd..aad4c50d37 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -133,7 +133,7 @@ "CustomFormatUnknownConditionOption": "Неизвестна опция „{0}“ за условие „{1}“", "UpgradeUntilCustomFormatScoreMovieHelpText": "След като бъде постигнат резултатът от този персонализиран формат, {appName} вече няма да изтегля филми", "UpgradeUntilMovieHelpText": "След достигане на това качество {appName} вече няма да изтегля филми", - "CutoffUnmet": "Прекъсване Неудовлетворено", + "CutoffUnmet": "Прекъсването не е удовлетворено", "Days": "Дни", "DefaultDelayProfileMovie": "Това е профилът по подразбиране. Прилага се за всички филми, които нямат изричен профил.", "DelayProfile": "Профил за забавяне", @@ -688,7 +688,7 @@ "AddNewMessage": "Лесно е да добавите нов филм, просто започнете да въвеждате името на филма, който искате да добавите", "AddRootFolder": "Добавяне на коренна папка", "AllFiles": "Всички файлове", - "AllMoviesInPathHaveBeenImported": "Всички филми от {0} са импортирани", + "AllMoviesInPathHaveBeenImported": "Всички филми от {path} са импортирани", "AllResultsHiddenFilter": "Всички резултати са скрити от приложения филтър", "AlternativeTitle": "Алтернативно заглавие", "AnalyticsEnabledHelpText": "Изпращайте анонимна информация за използването и грешките до сървърите на {appName}. Това включва информация за вашия браузър, кои страници на {appName} WebUI използвате, отчитане на грешки, както и версията на операционната система и времето за изпълнение. Ще използваме тази информация, за да дадем приоритет на функциите и корекциите на грешки.", @@ -719,10 +719,10 @@ "AddCustomFormat": "Добавете персонализиран формат", "AddDelayProfile": "Добавете профил за забавяне", "AddDownloadClient": "Добавяне на клиент за изтегляне", - "AddedToDownloadQueue": "Добавено към изтеглената опашка", + "AddedToDownloadQueue": "Добави към опашката за изтегляне", "AddingTag": "Добавяне на таг", "AddQualityProfile": "Добавете качествен профил", - "AddToDownloadQueue": "Добавено за опашка за изтегляне", + "AddToDownloadQueue": "Добави на опашката за изтегляне", "AfterManualRefresh": "След ръчно опресняване", "Always": "Винаги", "AnalyseVideoFiles": "Анализирайте видео файлове", @@ -744,7 +744,7 @@ "Backups": "Архиви", "BeforeUpdate": "Преди актуализация", "BindAddress": "Адрес за обвързване", - "BindAddressHelpText": "Валиден IP4 адрес или '*' за всички интерфейси", + "BindAddressHelpText": "Валиден IP адрес, localhost или '*' за всички интерфейси", "Branch": "Клон", "BuiltIn": "Вграден", "CalendarOptions": "Опции на календара", @@ -1073,5 +1073,79 @@ "Clone": "Близо", "AllTitles": "Всички файлове", "AddReleaseProfile": "Редактиране на профил за забавяне", - "DownloadClientUnavailable": "Клиентът за изтегляне не е наличен" + "DownloadClientUnavailable": "Клиентът за изтегляне не е наличен", + "AutoTaggingSpecificationOriginalLanguage": "Език", + "AutoTaggingSpecificationQualityProfile": "Качествен профил", + "AutoTaggingSpecificationRootFolder": "Рут папка", + "AutoTaggingSpecificationStatus": "Състояние", + "CustomFormatsSpecificationLanguage": "Език", + "CustomFormatsSpecificationMaximumSize": "Максимален размер", + "CustomFormatsSpecificationSource": "Източник", + "AddImportListImplementation": "Добави списък за импортиране - {implementationName}", + "ApplicationUrlHelpText": "Външният URL адрес на това приложение, включително http(s)://, порт и основно URL", + "AuthenticationMethod": "Метод за удостоверяване", + "AuthenticationMethodHelpTextWarning": "Моля, изберете валиден метод за удостоверяване", + "AutoTaggingLoadError": "Не може да се зареди автоматичното маркиране", + "AutoTaggingRequiredHelpText": "Това условие {implementationName} трябва да съответства, за да се приложи правилото за автоматично маркиране. В противен случай е достатъчно едно съвпадение на {implementationName}.", + "AuthenticationRequired": "Изисква се удостоверяване", + "AuthenticationRequiredHelpText": "Променете за кои заявки се изисква удостоверяване. Не променяйте, освен ако не разбирате рисковете.", + "AppUpdated": "{appName} Актуализиранa", + "CustomFormatsSettingsTriggerInfo": "Персонализиран формат ще бъде приложен към издание или файл, когато съвпада с поне един от всеки от избраните различни типове условия.", + "AnnouncedMovieAvailabilityDescription": "Филмите се считат за налични веднага, щом бъдат добавени към {appName}.", + "AppUpdatedVersion": "{appName} е актуализиранa до версия `{version}`, за да получите най-новите промени, ще трябва да презаредите {appName}", + "AuthenticationRequiredPasswordHelpTextWarning": "Въведете нова парола", + "AuthenticationRequiredUsernameHelpTextWarning": "Въведете ново потребителско име", + "AnnouncedMovieDescription": "Филмът е обявен", + "DayOfWeekAt": "{day} в {time}", + "Any": "Всеки", + "AutoTaggingSpecificationTag": "Етикет", + "CustomFormatsSpecificationRegularExpression": "Регулярни изрази", + "BlocklistAndSearch": "Списък за блокиране и търсене", + "BlocklistAndSearchHint": "Започнете търсене на заместител след блокиране", + "BlocklistAndSearchMultipleHint": "Започнете търсене на заместители след блокиране", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Потвърдете новата парола", + "AuthenticationRequiredWarning": "За да предотврати отдалечен достъп без удостоверяване, {appName} вече изисква удостоверяването да бъде активирано. По желание можете да деактивирате удостоверяването от локални адреси.", + "AutoRedownloadFailedFromInteractiveSearch": "Неуспешно повторно изтегляне от интерактивното търсене", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "Автоматично търсене и опит за изтегляне на различно издание, когато неуспешното издание е било взето от интерактивно търсене", + "BlackholeFolderHelpText": "Папка, в която {appName} ще съхранява файла {extension}", + "BlackholeWatchFolder": "Папка за наблюдаване", + "BlackholeWatchFolderHelpText": "Папка, от която {appName} трябва да импортира завършените изтегляния", + "Auto": "Авто", + "CutoffUnmetLoadError": "Грешка при зареждането на неизпълнени елементи за прекъсване", + "CutoffUnmetNoItems": "Няма неизпълнени елементи за прекъсване", + "AddConditionImplementation": "Добави условие - {implementationName}", + "AddConnection": "Добави връзка", + "AddConnectionImplementation": "Добави връзка - {implementationName}", + "AddDownloadClientImplementation": "Добавяне на клиент за изтегляне - {implementationName}", + "AddImportList": "Добави списък за импортиране", + "AddIndexerImplementation": "Добави индексатор - {implementationName}", + "ApplyChanges": "Прилагане на промените", + "ApplicationURL": "URL адрес на приложението", + "AddAutoTag": "Добави автоматичен таг", + "AddCondition": "Добави условие", + "AutoTagging": "Автоматично етикетиране", + "AutomaticAdd": "Автоматично добавяне", + "AutoTaggingSpecificationGenre": "Жанр(ове)", + "AutoTaggingSpecificationMaximumRuntime": "Максимално време за изпълнение", + "AutoTaggingSpecificationMaximumYear": "Максимална година", + "AutoTaggingSpecificationMinimumRuntime": "Минимално време за изпълнение", + "AutoTaggingSpecificationMinimumYear": "Минимална година", + "AutomaticUpdatesDisabledDocker": "Автоматичните актуализации не се поддържат директно при използване на механизма за актуализация на Docker. Ще трябва да актуализирате Image-a на контейнера извън {appName} или да използвате скрипт", + "CustomFormatsSpecificationExceptLanguageHelpText": "Съответства, ако има друг език, различен от избрания", + "CustomFormatsSpecificationFlag": "Флаг", + "CustomFormatsSpecificationMaximumSizeHelpText": "Изданието трябва да е по-малко или равно на този размер", + "CustomFormatsSpecificationMaximumYear": "Максимална година", + "CustomFormatsSpecificationMinimumSize": "Минимален размер", + "CustomFormatsSpecificationMinimumSizeHelpText": "Изданието трябва да е по-голямо от този размер", + "CustomFormatsSpecificationMinimumYear": "Минимална година", + "CustomFormatsSpecificationQualityModifier": "Модификатор на качеството", + "CustomFormatsSpecificationRegularExpressionHelpText": "Персонализираният формат RegEx не е чувствителен към главни и малки букви", + "CustomFormatsSpecificationResolution": "Разделителна способност", + "CutoffNotMet": "Прекъсването не е постигнато", + "Dash": "Тире", + "Default": "Подразбиране", + "ApiKeyValidationHealthCheckMessage": "Моля, актуализирайте API ключа си така, че да съдържа поне {length} знака. Можете да направите това чрез настройките или конфигурационния файл", + "AudioLanguages": "Аудио езици", + "CustomFormatsSpecificationExceptLanguage": "Освен езика", + "Database": "База данни" } diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 41fe487554..703e51eb2e 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1387,5 +1387,18 @@ "DefaultNotFoundMessage": "Deu estar perdut, no hi ha res a veure aquí.", "Completed": "Completat", "Delay": "Retard", - "DownloadClientUnavailable": "El client de descàrrega no està disponible" + "DownloadClientUnavailable": "El client de descàrrega no està disponible", + "AutoTaggingSpecificationGenre": "Gènere(s)", + "AutoTaggingSpecificationMaximumYear": "Any màxim", + "AutoTaggingSpecificationMinimumYear": "Any mínim", + "AutoTaggingSpecificationOriginalLanguage": "Idioma", + "AutoTaggingSpecificationQualityProfile": "Perfil de Qualitat", + "AutoTaggingSpecificationRootFolder": "Carpeta arrel", + "AutoTaggingSpecificationStatus": "Estat", + "CustomFormatsSpecificationLanguage": "Idioma", + "CustomFormatsSpecificationMaximumSize": "Mida màxima", + "CustomFormatsSpecificationMaximumYear": "Any màxim", + "CustomFormatsSpecificationMinimumYear": "Any mínim", + "CustomFormatsSpecificationResolution": "Resolució", + "CustomFormatsSpecificationSource": "Font" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 4efa5cf10c..09f8b27647 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1205,5 +1205,61 @@ "Delay": "Zpoždění", "DownloadClientUnavailable": "Stahovací klient není k dispozici", "NotificationsDiscordSettingsAuthor": "Autor", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Pokud je torrent blokován pomocí hash, nemusí být u některých indexerů správně odmítnut během RSS/vyhledávání. Povolení této funkce umožní jeho odmítnutí po zachycení torrentu, ale před jeho odesláním klientovi." + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Pokud je torrent blokován pomocí hash, nemusí být u některých indexerů správně odmítnut během RSS/vyhledávání. Povolení této funkce umožní jeho odmítnutí po zachycení torrentu, ale před jeho odesláním klientovi.", + "DownloadClientDelugeSettingsUrlBaseHelpText": "Přidá předponu do url adresy json deluge, viz {url}", + "DownloadClientSettingsAddPaused": "Přidat pozastavené", + "DownloadClientFloodSettingsAdditionalTagsHelpText": "Přidá vlastnosti médií jako štítky. Nápovědy jsou příklady.", + "DownloadClientQbittorrentSettingsFirstAndLastFirst": "Nejprve první a poslední", + "DownloadClientSettingsInitialStateHelpText": "Počáteční stav pro torrenty přidané do {clientName}", + "DownloadClientSettingsDestinationHelpText": "Ručně určuje cíl stahování, pro použití výchozího nastavení nechte prázdné", + "DownloadClientSettingsInitialState": "Počáteční stav", + "Donate": "Darovat", + "DownloadClientQbittorrentSettingsContentLayout": "Rozvržení obsahu", + "Implementation": "Implementace", + "Destination": "Cíl", + "DownloadClientFloodSettingsAddPaused": "Přidat pozastavené", + "DownloadClientFloodSettingsUrlBaseHelpText": "Přidá předponu do Flood API, například {url}", + "DownloadClientPneumaticSettingsNzbFolder": "Složka Nzb", + "DownloadClientFreeboxSettingsAppTokenHelpText": "Token aplikace získaný při vytváření přístupu k Freebox API (tj. ‚app_token‘)", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Zda použít rozvržení obsahu nakonfigurované v qBittorrentu, původní rozvržení z torrentu nebo vždy vytvořit podsložku (qBittorrent 4.3.2+)", + "DownloadClientFreeboxSettingsAppToken": "Token aplikace", + "DownloadClientFreeboxSettingsAppIdHelpText": "ID aplikace zadané při vytváření přístupu k Freebox API (tj. ‚app_id‘)", + "DownloadClientPneumaticSettingsNzbFolderHelpText": "Tato složka bude muset být dostupná z XBMC", + "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "Stahovat v postupném pořadí (qBittorrent 4.1.0+)", + "DownloadClientSettingsUseSslHelpText": "Při připojení k {clientName} použít zabezpečené připojení", + "DownloadClientQbittorrentSettingsSequentialOrder": "Postupné pořadí", + "DownloadClientQbittorrentSettingsInitialStateHelpText": "Počáteční stav torrentů přidaných do qBittorrentu. Pamatujte, že vynucené torrenty nedodržují omezení týkající se seedů", + "DownloadClientRTorrentSettingsUrlPathHelpText": "Cesta ke koncovému bodu XMLRPC, viz {url}. Při použití ruTorrentu je to obvykle RPC2 nebo [cesta k ruTorrentu]{url2}.", + "HealthMessagesInfoBox": "Další informace o příčině těchto zpráv o kontrole zdraví najdete kliknutím na odkaz wiki (ikona knihy) na konci řádku nebo kontrolou [logů]({link}). Pokud máte potíže s interpretací těchto zpráv, můžete se obrátit na naši podporu, a to na níže uvedených odkazech.", + "DownloadClientAriaSettingsDirectoryHelpText": "Volitelné umístění pro stahování, ponechte prázdné pro použití výchozího umístění Aria2", + "AutoTaggingSpecificationOriginalLanguage": "Jazyk", + "AutoTaggingSpecificationQualityProfile": "Profil kvality", + "AutoTaggingSpecificationRootFolder": "Kořenový adresář", + "AutoTaggingSpecificationStatus": "Postavení", + "CustomFormatsSpecificationLanguage": "Jazyk", + "CustomFormatsSpecificationMaximumSize": "Maximální velikost", + "CustomFormatsSpecificationResolution": "Rozlišení", + "CustomFormatsSpecificationSource": "Zdroj", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "Volitelná sdílená složka pro stahování, ponechte prázdné pro použití výchozího umístění Download Station", + "DownloadClientFloodSettingsTagsHelpText": "Počáteční štítky stahování. Aby bylo stahování rozpoznáno, musí mít všechny počáteční štítky. Tím se zabrání konfliktům s nesouvisejícími stahováními.", + "DownloadClientFreeboxSettingsApiUrl": "URL API", + "DownloadClientFreeboxSettingsApiUrlHelpText": "Definujte základní adresu URL Freebox API s verzí API, např. ‚{url}‘, výchozí hodnota je ‚{defaultApiUrl}‘", + "DownloadClientFreeboxSettingsAppId": "ID aplikace", + "DownloadClientFreeboxSettingsHostHelpText": "Název hostitele nebo IP adresa hostitele Freeboxu, výchozí hodnota je ‚{url}‘ (funguje pouze ve stejné síti)", + "DownloadClientFreeboxSettingsPortHelpText": "Port použitý pro přístup k rozhraní Freeboxu, výchozí hodnota je ‚{port}‘", + "DownloadClientNzbgetSettingsAddPausedHelpText": "Tato volba vyžaduje NzbGet verze alespoň 16.0", + "DownloadClientPneumaticSettingsStrmFolder": "Složka Strm", + "DownloadClientPneumaticSettingsStrmFolderHelpText": "Soubory .strm v této složce budou importovány pomocí drone", + "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "Stahovat nejprve první a poslední kusy (qBittorrent 4.1.0+)", + "DownloadClientQbittorrentSettingsUseSslHelpText": "Používat zabezpečené připojení. Viz Možnosti -> WebUI -> Webové uživatelské rozhraní -> ‚Použít HTTPS místo HTTP‘ v qBittorrentu.", + "DownloadClientRTorrentSettingsAddStopped": "Přidat zastavené", + "DownloadClientRTorrentSettingsAddStoppedHelpText": "Povolení přidá torrenty a magnety do rTorrentu v zastaveném stavu. To může způsobit poškození souborů magnet.", + "DownloadClientRTorrentSettingsDirectoryHelpText": "Volitelné umístění pro stahování, ponechte prázdné pro použití výchozího umístění rTorrentu", + "DownloadClientRTorrentSettingsUrlPath": "Cesta URL", + "DownloadClientTransmissionSettingsDirectoryHelpText": "Volitelné umístění pro stahování, ponechte prázdné pro použití výchozího umístění Transmission", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "Přidá předponu k url {clientName} rpc, např. {url}, výchozí hodnota je ‚{defaultUrl}‘", + "External": "Externí", + "NotificationsGotifySettingsAppToken": "Token aplikace", + "UsenetBlackholeNzbFolder": "Složka Nzb", + "DownloadClientFloodSettingsAdditionalTags": "Další štítky" } diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 4d7da10167..39d6595903 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1097,5 +1097,13 @@ "DownloadClientUnavailable": "Downloadklienten er ikke tilgængelig", "AddReleaseProfile": "Rediger forsinkelsesprofil", "ApiKeyValidationHealthCheckMessage": "Opdater din API-nøgle til at være på mindste {length} karakterer. Dette kan gøres i indstillingerne eller i konfigurationsfilen", - "AutoTaggingSpecificationTag": "Etiket" + "AutoTaggingSpecificationTag": "Etiket", + "AutoTaggingSpecificationOriginalLanguage": "Sprog", + "AutoTaggingSpecificationQualityProfile": "Kvalitetsprofil", + "AutoTaggingSpecificationRootFolder": "Rodmappe", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationLanguage": "Sprog", + "CustomFormatsSpecificationMaximumSize": "Maksimal størrelse", + "CustomFormatsSpecificationResolution": "Opløsning", + "CustomFormatsSpecificationSource": "Kilde" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index b9b4c23ff3..4961ee57ac 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1789,5 +1789,21 @@ "Warning": "Warnung", "YesterdayAt": "Gestern um {time}", "RemotePathMappingsInfo": "Remote-Pfadzuordnungen sind sehr selten erforderlich. Wenn {appName} und dein Download-Client auf demselben System sind, ist es besser, deine Pfade abzugleichen. Weitere Informationen findest du im [Wiki]({wikiLink}).", - "NotificationsTelegramSettingsMetadataLinks": "Metadaten-Links" + "NotificationsTelegramSettingsMetadataLinks": "Metadaten-Links", + "CustomFormatsSpecificationMinimumYear": "Höchstjahr", + "CustomFormatsSpecificationResolution": "Auflösung", + "CustomFormatsSpecificationSource": "Quelle", + "AutoTaggingSpecificationGenre": "Genre(s)", + "AutoTaggingSpecificationMaximumYear": "Höchstjahr", + "AutoTaggingSpecificationMinimumYear": "Höchstjahr", + "AutoTaggingSpecificationOriginalLanguage": "Sprache", + "AutoTaggingSpecificationQualityProfile": "Qualitätsprofil", + "AutoTaggingSpecificationRootFolder": "Root-Ordner", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationLanguage": "Sprache", + "CustomFormatsSpecificationMaximumSize": "Maximale Größe", + "CustomFormatsSpecificationMaximumSizeHelpText": "Das Release muss kleiner oder gleich Groß sein", + "CustomFormatsSpecificationMaximumYear": "Höchstjahr", + "CustomFormatsSpecificationMinimumSize": "Mindestgröße", + "CustomFormatsSpecificationMinimumSizeHelpText": "Das Release muss größer als diese Größe sein" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index d51eaa8937..78786dfb9f 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1234,5 +1234,12 @@ "DownloadIgnored": "Λήψη Εισήχθη", "AllTitles": "Ολα τα αρχεία", "Completed": "Ολοκληρώθηκαν", - "DownloadClientUnavailable": "Ο πελάτης λήψης δεν είναι διαθέσιμος" + "DownloadClientUnavailable": "Ο πελάτης λήψης δεν είναι διαθέσιμος", + "AutoTaggingSpecificationOriginalLanguage": "Γλώσσα", + "AutoTaggingSpecificationQualityProfile": "Ποιοτικό προφίλ", + "AutoTaggingSpecificationRootFolder": "Φάκελος ρίζας", + "AutoTaggingSpecificationStatus": "Κατάσταση", + "CustomFormatsSpecificationLanguage": "Γλώσσα", + "CustomFormatsSpecificationMaximumSize": "Μέγιστο μέγεθος", + "CustomFormatsSpecificationSource": "Πηγή" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 6a935434a7..10fb59fe75 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1870,5 +1870,24 @@ "NotificationsTelegramSettingsMetadataLinks": "Enlaces de metadatos", "NotificationsTelegramSettingsIncludeInstanceName": "Incluir el nombre de la instancia en el título", "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Opcionalmente incluye el nombre de la instancia en la notificación", - "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Añade un enlace a los metadatos de la película cuando se envían notificaciones" + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Añade un enlace a los metadatos de la película cuando se envían notificaciones", + "AutoTaggingSpecificationMaximumYear": "Año máximo", + "AutoTaggingSpecificationMinimumYear": "Año mínimo", + "AutoTaggingSpecificationOriginalLanguage": "Idioma", + "AutoTaggingSpecificationQualityProfile": "Perfil de calidad", + "AutoTaggingSpecificationRootFolder": "Carpeta raíz", + "AutoTaggingSpecificationStatus": "Estado", + "CustomFormatsSpecificationMaximumSizeHelpText": "La versión debe ser menor o igual a este tamaño", + "CustomFormatsSpecificationMinimumSize": "Tamaño mínimo", + "CustomFormatsSpecificationMinimumSizeHelpText": "La versión debe ser mayor que este tamaño", + "CustomFormatsSpecificationMinimumYear": "Año mínimo", + "CustomFormatsSpecificationResolution": "Resolución", + "CustomFormatsSpecificationSource": "Fuente", + "AutoTaggingSpecificationGenre": "Género(s)", + "CustomFormatsSpecificationLanguage": "Idioma", + "CustomFormatsSpecificationMaximumSize": "Tamaño máximo", + "CustomFormatsSpecificationMaximumYear": "Año máximo", + "AutoTaggingSpecificationMaximumRuntime": "Tiempo de ejecución máximo", + "AutoTaggingSpecificationMinimumRuntime": "Tiempo de ejecución mínimo", + "CustomFormatsSpecificationQualityModifier": "Modificador de calidad" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index ade44ac50b..7ded7b0ee0 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -45,7 +45,7 @@ "Large": "Suuri", "LinkHere": "tässä", "ListSyncLevelHelpText": "Kirjaston elokuvia käsitellään valinnan perusteella, jos ne poistuvat tai niitä ei löydy tuontilistoilta.", - "ManualImportSelectMovie": "Manuaalituonti – Valitse elokuva", + "ManualImportSelectMovie": "Manuaalinen tuonti – Valitse elokuva", "MappedNetworkDrivesWindowsService": "Yhdistetyt verkkoasemat eivät ole käytettävissä kun sovellus suoritetaan Windows-palveluna. Saat lisätietoja UKK:sta ({url}).", "MinimumAgeHelpText": "Vain Usenet: NZB:n vähimmäisikä minuutteina, ennen niiden kaappausta. Tämän avulla uusille julkaisuille voidaan antaa aikaa levitä Usenet-palveluntarjoajalle.", "MinimumFreeSpaceHelpText": "Estä tuonti, jos sen jälkeinen vapaa levytila olisi tässä määritettyä pienempi.", @@ -63,7 +63,7 @@ "RssSync": "Synkronoi RSS", "Runtime": "Kesto", "SearchCutoffUnmet": "Haun raja-arvo ei täytetty", - "SearchFiltered": "Etsi suodatetuista", + "SearchFiltered": "Etsi suodatettuja", "SetPermissionsLinuxHelpTextWarning": "Jollet ole varma mitä nämä asetukset tekevät, älä muuta niitä.", "RemotePathMappingRemotePathHelpText": "Latauspalvelun käyttämän kansion juurisijainti.", "ShowRelativeDatesHelpText": "Korvaa absoluuttiset päiväykset suhteellisilla päiväyksillä (tänään/eilen/yms.).", @@ -267,7 +267,7 @@ "LoadingMovieFilesFailed": "Elokuvatiedostojen lataus epäonnistui", "Location": "Sijainti", "Manual": "Manuaalinen", - "ManualImport": "Manuaalituonti", + "ManualImport": "Manuaalinen tuonti", "MarkAsFailed": "Merkitse epäonnistuneeksi", "Mechanism": "Mekanismi", "MediaInfo": "Median tiedot", @@ -603,7 +603,7 @@ "IndexerSettings": "Tietolähdeasetukset", "IndexerStatusCheckSingleClientMessage": "Tietolähteet eivät ole virheiden vuoksi käytettävissä: {indexerNames}", "InstallLatest": "Asenna uusin", - "InteractiveImport": "Manuaalituonti", + "InteractiveImport": "Manuaalinen tuonti", "InteractiveSearch": "Etsi manuaalisesti", "KeepAndUnmonitorMovie": "Säilytä elokuva ja lopeta sen valvonta", "KeyboardShortcuts": "Pikanäppäimet", @@ -626,8 +626,8 @@ "LookingForReleaseProfiles1": "Etsitkö julkaisuprofiileja? Kokeile", "LookingForReleaseProfiles2": "-sivua sen sijaan.", "Lowercase": "Pienet kirjaimet", - "ManualImportSelectLanguage": "Manuaalituonti – Valitse kieli", - "ManualImportSelectQuality": " Manuaalituonti – Valitse laatu", + "ManualImportSelectLanguage": "Manuaalinen tuonti – Valitse kieli", + "ManualImportSelectQuality": " Manuaalinen tuonti – Valitse laatu", "MarkAsFailedMessageText": "Haluatko varmasti merkitä kohteen {0} epäonnistuneeksi?", "MassMovieSearch": "Elokuvien massahaku", "MaximumLimits": "Enimmäisrajoitukset", @@ -940,7 +940,7 @@ "MissingNotMonitored": "Puuttuu (valvomattomat)", "MoveFolders2": "Haluatko siirtää elokuvatiedostot kansiosta {0} kansioon {1}?", "MovieDetailsPreviousMovie": "Elokuvan tiedot: Edellinen elokuva", - "MovieEditor": "Elokuvaeditori", + "MovieEditor": "Elokuvien monivalinta", "MovieExcludedFromAutomaticAdd": "Elokuvaa ei huomioida automaattisessa lisäyksessä.", "Edit": "Muokkaa", "SqliteVersionCheckUpgradeRequiredMessage": "Tällä hetkellä asennettua SQLite-versiota {0} ei enää tueta. Päivitä SQLite vähintään versioon {1}.", @@ -991,7 +991,7 @@ "RemoveDownloadsAlert": "Poistoasetukset on siirretty yllä olevan taulukon latauspalvelukohtaisiin asetuksiin.", "OnApplicationUpdate": "Kun sovellus päivitetään", "DiscordUrlInSlackNotification": "Olet määrittänyt Discordin Slack-ilmoituksena. Määritä se Discord-ilmoituksena parempaa toiminnallisuutta varten. Koskee seuraavia: {0}.", - "ManualImportSetReleaseGroup": "Manuaalituonti – Aseta julkaisuryhmä", + "ManualImportSetReleaseGroup": "Manuaalinen tuonti– Aseta julkaisuryhmä", "AnnouncedMovieDescription": "Elokuva on julkistettu", "IndexerDownloadClientHelpText": "Määritä tämän tietolähteen kanssa käytettävä latauspalvelu.", "SelectLanguages": "Valitse kielet", @@ -1635,7 +1635,7 @@ "UsenetBlackholeNzbFolder": "NZB-kansio", "UsenetBlackhole": "Usenet Blackhole", "EditMetadata": "Muokkaa metatietoa {metadataType}", - "MovieFolderFormatHelpText": "Käytetään kun lisätään uusi elokuva tai siirretään elokuvia elokuvaeditorin avulla.", + "MovieFolderFormatHelpText": "Käytetään kun lisätään uusia elokuvia tai siirretään vanhoja kun niiden tietoja muokataan.", "RestartRequiredToApplyChanges": "{appName} on käynnistettävä uudelleen muutosten käyttöönottamiseksi. Haluatko tehdä sen nyt?", "RestartRequiredWindowsService": "Jotta palvelu käynnistyisi automaattisesti, voi suorittavasta käyttäjästä riippuen olla tarpeellista suorittaa {appName} kerran järjestelmänvalvojan oikeuksilla.", "MediaInfoFootNote": "MediaInfo Full, AudioLanguages ja SubtitleLanguages tukevat \":EN+FI\"-tyylisiä jälkiliitteitä, joiden avulla tiedostonimeen voidaan lisätä videon sisältämiä kieliä. \"-\" ohittaa tietyt kielet (esim. \"-EN\") ja \"+\"-pääte (esim. \":FI+\") tuottaa ohitettavista kielistä riippuen \"[FI]\", \"[FI+--]\" tai \"[--]\". Esimerkiksi \"{MediaInfo Full:FI+EN}\".", @@ -1870,5 +1870,24 @@ "NotificationsGotifySettingsMetadataLinks": "Metatietolinkit", "NotificationsGotifySettingsPreferredMetadataLink": "Ensisijainen metatietolinkki", "ManageFormats": "Hallitse muotoja", - "Disposition": "Poikkeama" + "Disposition": "Poikkeama", + "AutoTaggingSpecificationQualityProfile": "Laatuprofiili", + "AutoTaggingSpecificationRootFolder": "Juurikansio", + "AutoTaggingSpecificationStatus": "Tila", + "CustomFormatsSpecificationLanguage": "Kieli", + "CustomFormatsSpecificationMaximumSize": "Enimmäiskoko", + "CustomFormatsSpecificationMaximumSizeHelpText": "Julkaisun tulee olla enintään tämän kokoinen.", + "CustomFormatsSpecificationMaximumYear": "Suurin vuosi", + "CustomFormatsSpecificationMinimumSize": "Vähimmäiskoko", + "CustomFormatsSpecificationMinimumSizeHelpText": "Julkaisun tulee olla tätä kokoa suurempi.", + "CustomFormatsSpecificationMinimumYear": "Pienin vuosi", + "CustomFormatsSpecificationResolution": "Resoluutio", + "CustomFormatsSpecificationSource": "Lähde", + "AutoTaggingSpecificationGenre": "Lajityypit", + "AutoTaggingSpecificationMaximumYear": "Suurin vuosi", + "AutoTaggingSpecificationMinimumYear": "Pienin vuosi", + "AutoTaggingSpecificationOriginalLanguage": "Kieli", + "AutoTaggingSpecificationMaximumRuntime": "Enimmäiskesto", + "AutoTaggingSpecificationMinimumRuntime": "Vähimmäiskesto", + "CustomFormatsSpecificationQualityModifier": "Laatumuuttuja" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 0b39d257c5..3f8f4a1a77 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -26,7 +26,7 @@ "Edit": "Modifier", "Downloaded": "Téléchargé", "DownloadClientStatusCheckAllClientMessage": "Aucun client de téléchargement n'est disponible en raison d'échecs", - "DownloadClients": "Clients de télécharg.", + "DownloadClients": "Clients de téléchargement", "DownloadClientCheckNoneAvailableMessage": "Aucun client de téléchargement n'est disponible", "Dates": "Dates", "Date": "Date", @@ -213,7 +213,7 @@ "AllMoviesHiddenDueToFilter": "Tous les films sont masqués en raison du filtre appliqué.", "Age": "Âge", "AddNewMovie": "Ajouter un nouveau film", - "Warn": "Avertissement", + "Warn": "Attention", "VideoCodec": "Video Codec", "Unavailable": "Indisponible", "Type": "Type", @@ -838,7 +838,7 @@ "InCinemasMovieDescription": "Le film est dans les cinémas", "Lowercase": "Minuscule", "ManualImportSelectMovie": "Importation manuelle - Sélectionnez un film", - "MappedNetworkDrivesWindowsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la FAQ pour plus d'informations", + "MappedNetworkDrivesWindowsService": "Les lecteurs réseau mappés ne sont pas disponibles en fonctionnement en tant que service Windows. Veuillez consulter la [FAQ]({url}) pour plus d'informations.", "RequiredRestrictionHelpText": "La version doit contenir au moins un de ces termes (insensible à la casse)", "InvalidFormat": "Format invalide", "LastExecution": "Dernière exécution", @@ -1757,7 +1757,7 @@ "InteractiveSearchModalHeaderTitle": "Recherche interactive - {title}", "MovieIsNotAvailable": "Film indisponible", "MovieIsNotMonitored": "Film non surveillé", - "NoMovieReleaseDatesAvailable": "Aucune date de sortie n'est disponible sur TMDb pour ce film.", + "NoMovieReleaseDatesAvailable": "Aucune date de sortie n'est disponible sur [TMDb]({url}) pour ce film.", "SearchForAllMissingMovies": "Chercher touts les films manquants", "SearchForAllMissingMoviesConfirmationCount": "Êtes-vous sûr de vouloir lancer la recherche pour touts les {totalRecords} films manquants ?", "ReleaseGroupFootNote": "Contrôlez éventuellement la troncature à un nombre maximum d'octets, y compris les points de suspension (`...`). La troncature de la fin (par exemple `{Release Group:30}`) ou du début (par exemple `{Release Group:-30}`) sont toutes deux prises en charge.`).", @@ -1805,7 +1805,7 @@ "CountVotes": "{votes} votes", "ShowDigitalRelease": "Afficher la date de sortie numérique", "ShowDigitalReleaseHelpText": "Affiche la date de sortie numérique sous l'affiche", - "ShowPhysicalRelease": "Date de sortie physique", + "ShowPhysicalRelease": "Afficher la date de sortie physique", "ShowPhysicalReleaseHelpText": "Affiche la date de sortie physique sous l'affiche", "DayOfWeekAt": "{day} à {time}", "TodayAt": "Aujourd'hui à {time}", @@ -1848,5 +1848,46 @@ "Delay": "Délai", "DownloadClientUnavailable": "Le client de téléchargement n'est pas disponible", "NotificationsTelegramSettingsMetadataLinks": "Liens de métadonnées", - "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications" + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Ajouter un lien vers les métadonnées de la série lors de l'envoi de notifications", + "AutoTaggingSpecificationGenre": "Genre(s)", + "AutoTaggingSpecificationMaximumYear": "Année maximum", + "AutoTaggingSpecificationOriginalLanguage": "Langue", + "AutoTaggingSpecificationQualityProfile": "Profil de qualité", + "AutoTaggingSpecificationRootFolder": "Dossier racine", + "AutoTaggingSpecificationStatus": "État", + "CustomFormatsSpecificationMaximumSize": "Taille maximum", + "CustomFormatsSpecificationMaximumSizeHelpText": "La version doit être inférieur ou égal à cette taille", + "CustomFormatsSpecificationMaximumYear": "Année maximum", + "CustomFormatsSpecificationMinimumSize": "Taille minimum", + "CustomFormatsSpecificationMinimumSizeHelpText": "La version doit être supérieure à cette taille", + "CustomFormatsSpecificationMinimumYear": "Année minimum", + "CustomFormatsSpecificationResolution": "Résolution", + "CustomFormatsSpecificationSource": "Source", + "AutoTaggingSpecificationMinimumYear": "Année minimum", + "CustomFormatsSpecificationLanguage": "Langue", + "Fallback": "Alternative", + "MetadataKometaDeprecated": "Les fichiers Kometa ne seront plus créés, le support sera complètement supprimé dans la v6", + "NotificationsSettingsWebhookHeaders": "En-têtes", + "MinimumCustomFormatScoreIncrementHelpText": "Amélioration minimale requise du score de format personnalisé entre les versions existantes et nouvelles avant que {appName} ne le considère comme une mise à niveau", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Écrire les métadonnées dans movie.nfo au lieu du fichier par défaut .nfo", + "TraktRating": "Évaluation de Trakt", + "MinimumCustomFormatScoreIncrement": "Incrément minimal du score du format personnalisé", + "TraktVotes": "Votes de Trakt", + "AutoTaggingSpecificationMaximumRuntime": "Durée d'exécution maximale", + "AutoTaggingSpecificationMinimumRuntime": "Durée d'exécution minimale", + "CustomFormatsSpecificationQualityModifier": "Modificateur de qualité", + "FavoriteFolderAdd": "Ajouter un dossier favori", + "FavoriteFolderRemove": "Supprimer le dossier favori", + "FavoriteFolders": "Dossiers favoris", + "MetadataKometaDeprecatedSetting": "Obsolète", + "MetadataSettingsMovieImages": "Images de films", + "MetadataSettingsMovieMetadataLanguage": "Langue des métadonnées du film", + "MetadataSettingsMovieMetadataNfo": "Utiliser movie.nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Inclure les URL des films TMDb et IMDb dans .nfo", + "NotificationsTelegramSettingsIncludeInstanceName": "Inclure le nom de l'instance dans le titre", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Inclure éventuellement le nom de l'instance dans la notification", + "Warning": "Avertissement", + "NotificationsGotifySettingsPreferredMetadataLink": "Lien de métadonnées préféré", + "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Lien de métadonnées pour les clients qui ne prennent en charge qu'un seul lien", + "ManageFormats": "Gérer les formats" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 3d03220f43..149bf43704 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1119,5 +1119,12 @@ "EditReleaseProfile": "ערוך פרופיל עיכוב", "AddReleaseProfile": "ערוך פרופיל עיכוב", "DownloadClientUnavailable": "לקוח ההורדות אינו זמין", - "AddCondition": "הוסף תנאי" + "AddCondition": "הוסף תנאי", + "AutoTaggingSpecificationOriginalLanguage": "שפה", + "AutoTaggingSpecificationQualityProfile": "פרופיל איכות", + "CustomFormatsSpecificationLanguage": "שפה", + "CustomFormatsSpecificationMaximumSize": "גודל מקסימלי", + "CustomFormatsSpecificationSource": "מָקוֹר", + "AutoTaggingSpecificationRootFolder": "תיקיית שורש", + "AutoTaggingSpecificationStatus": "סטָטוּס" } diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index e9cec94338..059112a34d 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1071,5 +1071,12 @@ "AllTitles": "सारे दस्तावेज", "EditReleaseProfile": "देरी प्रोफ़ाइल संपादित करें", "DownloadClientUnavailable": "डाउनलोड क्लाइंट अनुपलब्ध है", - "AddReleaseProfile": "देरी प्रोफ़ाइल संपादित करें" + "AddReleaseProfile": "देरी प्रोफ़ाइल संपादित करें", + "AutoTaggingSpecificationOriginalLanguage": "भाषा: हिन्दी", + "AutoTaggingSpecificationQualityProfile": "गुणवत्ता प्रोफ़ाइल", + "AutoTaggingSpecificationRootFolder": "मूल फ़ोल्डर", + "AutoTaggingSpecificationStatus": "स्थिति", + "CustomFormatsSpecificationLanguage": "भाषा: हिन्दी", + "CustomFormatsSpecificationMaximumSize": "अधिकतम आकार", + "CustomFormatsSpecificationSource": "स्रोत" } diff --git a/src/NzbDrone.Core/Localization/Core/hr.json b/src/NzbDrone.Core/Localization/Core/hr.json index 0fc4edde8e..ec31c6dbef 100644 --- a/src/NzbDrone.Core/Localization/Core/hr.json +++ b/src/NzbDrone.Core/Localization/Core/hr.json @@ -366,5 +366,12 @@ "Clone": "Zatvori", "Reason": "Sezona", "Delay": "Odgoda", - "DeleteSelectedMovieFilesHelpText": "Jeste li sigurni da želite obrisati ovaj profil odgode?" + "DeleteSelectedMovieFilesHelpText": "Jeste li sigurni da želite obrisati ovaj profil odgode?", + "AutoTaggingSpecificationStatus": "Status", + "AutoTaggingSpecificationOriginalLanguage": "jezik", + "AutoTaggingSpecificationQualityProfile": "Profil Kvalitete", + "AutoTaggingSpecificationRootFolder": "Korijenska Mapa", + "CustomFormatsSpecificationLanguage": "jezik", + "CustomFormatsSpecificationResolution": "Razlučivost", + "CustomFormatsSpecificationSource": "Izvor" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 24f414dbb2..d5fc922f0b 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1448,5 +1448,21 @@ "FileBrowser": "Fájl Böngésző", "Completed": "Teljes", "Delay": "Késleltetés", - "DownloadClientUnavailable": "Letöltőkliens nem elérhető" + "DownloadClientUnavailable": "Letöltőkliens nem elérhető", + "AutoTaggingSpecificationGenre": "Műfaj(ok)", + "AutoTaggingSpecificationMaximumYear": "Maximum Év", + "AutoTaggingSpecificationMinimumYear": "Minimum Év", + "AutoTaggingSpecificationOriginalLanguage": "Nyelv", + "AutoTaggingSpecificationQualityProfile": "Minőségi profil", + "AutoTaggingSpecificationRootFolder": "Gyökérmappa", + "AutoTaggingSpecificationStatus": "Állapot", + "CustomFormatsSpecificationLanguage": "Nyelv", + "CustomFormatsSpecificationMaximumSize": "Maximális méret", + "CustomFormatsSpecificationMaximumSizeHelpText": "A kioldásnak kisebbnek vagy egyenlőnek kell lennie ennél a méretnél", + "CustomFormatsSpecificationMaximumYear": "Maximum Év", + "CustomFormatsSpecificationMinimumSize": "Minimum méret", + "CustomFormatsSpecificationMinimumSizeHelpText": "A kibocsátásnak nagyobbnak kell lennie ennél a méretnél", + "CustomFormatsSpecificationMinimumYear": "Minimum Év", + "CustomFormatsSpecificationResolution": "Felbontás", + "CustomFormatsSpecificationSource": "Forrás" } diff --git a/src/NzbDrone.Core/Localization/Core/id.json b/src/NzbDrone.Core/Localization/Core/id.json index aee3dcd4be..4cd7bdbbaf 100644 --- a/src/NzbDrone.Core/Localization/Core/id.json +++ b/src/NzbDrone.Core/Localization/Core/id.json @@ -176,5 +176,8 @@ "Clone": "Tutup", "EnableSsl": "Aktifkan RSS", "AddCustomFormatError": "Tidak dapat menambahkan format khusus baru, coba lagi.", - "AddDelayProfile": "Tambah Delay Profile" + "AddDelayProfile": "Tambah Delay Profile", + "AutoTaggingSpecificationOriginalLanguage": "Bahasa", + "AutoTaggingSpecificationQualityProfile": "Profil Kualitas", + "CustomFormatsSpecificationLanguage": "Bahasa" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 3db126c46b..f97eaf3b50 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1073,5 +1073,12 @@ "EditReleaseProfile": "Breyta seinkunarprófíl", "AllTitles": "Allar skrár", "AddReleaseProfile": "Breyta seinkunarprófíl", - "DownloadClientUnavailable": "Niðurhalsþjónn er ekki tiltækur" + "DownloadClientUnavailable": "Niðurhalsþjónn er ekki tiltækur", + "AutoTaggingSpecificationOriginalLanguage": "Tungumál", + "AutoTaggingSpecificationRootFolder": "Rótamappa", + "AutoTaggingSpecificationStatus": "Staða", + "CustomFormatsSpecificationLanguage": "Tungumál", + "CustomFormatsSpecificationMaximumSize": "Hámarksstærð", + "CustomFormatsSpecificationSource": "Heimild", + "AutoTaggingSpecificationQualityProfile": "Gæðaprófíll" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index cb910e8764..8cf9592664 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1472,5 +1472,21 @@ "DefaultNotFoundMessage": "Ti devi essere perso, non c'è nulla da vedere qui.", "Completed": "Completo", "Delay": "Ritardo", - "DownloadClientUnavailable": "Il client di download non è disponibile" + "DownloadClientUnavailable": "Il client di download non è disponibile", + "AutoTaggingSpecificationGenre": "Genere/i", + "AutoTaggingSpecificationMaximumYear": "Anno Massimo", + "AutoTaggingSpecificationMinimumYear": "Anno Minimo", + "AutoTaggingSpecificationOriginalLanguage": "Lingua", + "AutoTaggingSpecificationQualityProfile": "Profilo Qualità", + "AutoTaggingSpecificationRootFolder": "Cartella Radice", + "AutoTaggingSpecificationStatus": "Stato", + "CustomFormatsSpecificationLanguage": "Lingua", + "CustomFormatsSpecificationMaximumSize": "Dimensione Massima", + "CustomFormatsSpecificationMaximumSizeHelpText": "La release deve essere minore o uguale a questa dimensione", + "CustomFormatsSpecificationMaximumYear": "Anno Massimo", + "CustomFormatsSpecificationMinimumSize": "Dimensione Minima", + "CustomFormatsSpecificationMinimumSizeHelpText": "La release deve essere maggiore di questa dimensione", + "CustomFormatsSpecificationMinimumYear": "Anno Minimo", + "CustomFormatsSpecificationResolution": "Risoluzione", + "CustomFormatsSpecificationSource": "Fonte" } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index cfb9cfe943..84f5dbf377 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1073,5 +1073,12 @@ "AllTitles": "すべてのファイル", "EditReleaseProfile": "遅延プロファイルの編集", "DownloadClientUnavailable": "ダウンロードクライアントは利用できません", - "AddReleaseProfile": "遅延プロファイルの編集" + "AddReleaseProfile": "遅延プロファイルの編集", + "AutoTaggingSpecificationOriginalLanguage": "言語", + "AutoTaggingSpecificationQualityProfile": "品質プロファイル", + "AutoTaggingSpecificationRootFolder": "ルートフォルダ", + "AutoTaggingSpecificationStatus": "状態", + "CustomFormatsSpecificationMaximumSize": "最大サイズ", + "CustomFormatsSpecificationSource": "ソース", + "CustomFormatsSpecificationLanguage": "言語" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 6c3faa9b97..90e675ad79 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1092,5 +1092,12 @@ "VideoDynamicRange": "동영상 다이나믹 레인지", "XmlRpcPath": "XML RPC 경로", "YesterdayAt": "어제 {time}", - "DownloadClientPneumaticSettingsNzbFolder": "Nzb 폴더" + "DownloadClientPneumaticSettingsNzbFolder": "Nzb 폴더", + "AutoTaggingSpecificationOriginalLanguage": "언어", + "AutoTaggingSpecificationQualityProfile": "품질 프로필", + "AutoTaggingSpecificationRootFolder": "루트 폴더", + "AutoTaggingSpecificationStatus": "상태", + "CustomFormatsSpecificationLanguage": "언어", + "CustomFormatsSpecificationMaximumSize": "최대 크기", + "CustomFormatsSpecificationSource": "출처" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index 87191e8ad7..3fe8d17a72 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -320,5 +320,10 @@ "TMDb": "TMDb", "Clone": "Lukk", "Reason": "Sesong", - "Delay": "Utsett" + "Delay": "Utsett", + "AutoTaggingSpecificationQualityProfile": "Kvaltietsprofil", + "AutoTaggingSpecificationRootFolder": "Rotmappe", + "CustomFormatsSpecificationResolution": "Oppløsning", + "AutoTaggingSpecificationOriginalLanguage": "språk", + "CustomFormatsSpecificationLanguage": "språk" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 41ca4bebe4..e405f6a186 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1240,5 +1240,18 @@ "AnnouncedMovieAvailabilityDescription": "Films worden als beschikbaar getoond zodra deze zijn toegevoegd aan {appName}.", "Completed": "Compleet", "Delay": "Uitstel", - "DownloadClientUnavailable": "Downloader is onbeschikbaar" + "DownloadClientUnavailable": "Downloader is onbeschikbaar", + "AutoTaggingSpecificationGenre": "Genre(s)", + "AutoTaggingSpecificationMaximumYear": "Maximum Jaar", + "AutoTaggingSpecificationMinimumYear": "Minimum Jaar", + "AutoTaggingSpecificationOriginalLanguage": "Taal", + "AutoTaggingSpecificationQualityProfile": "Kwaliteitsprofiel", + "AutoTaggingSpecificationRootFolder": "Hoofdmap", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationMaximumSize": "Maximum Grootte", + "CustomFormatsSpecificationMaximumYear": "Maximum Jaar", + "CustomFormatsSpecificationMinimumYear": "Minimum Jaar", + "CustomFormatsSpecificationResolution": "Resolutie", + "CustomFormatsSpecificationSource": "Bron", + "CustomFormatsSpecificationLanguage": "Taal" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 46e7fbf6c8..f13390e631 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1187,5 +1187,13 @@ "FolderNameTokens": "Tokeny nazw plików", "Clone": "Zamknij", "Delay": "Opóźnienie", - "DownloadClientUnavailable": "Klient pobierania jest niedostępny" + "DownloadClientUnavailable": "Klient pobierania jest niedostępny", + "AutoTaggingSpecificationOriginalLanguage": "Język", + "AutoTaggingSpecificationQualityProfile": "Profil jakości", + "AutoTaggingSpecificationRootFolder": "Folder główny", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationLanguage": "Język", + "CustomFormatsSpecificationMaximumSize": "Największy rozmiar", + "CustomFormatsSpecificationResolution": "Rozdzielczość", + "CustomFormatsSpecificationSource": "Źródło" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index c6236c1967..a188001aaf 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1266,5 +1266,13 @@ "CountVotes": "{votes} votos", "Completed": "Completo", "Delay": "Atraso", - "DownloadClientUnavailable": "O cliente de transferências está indisponível" + "DownloadClientUnavailable": "O cliente de transferências está indisponível", + "AutoTaggingSpecificationOriginalLanguage": "Idioma", + "AutoTaggingSpecificationQualityProfile": "Perfil de qualidade", + "AutoTaggingSpecificationRootFolder": "Pasta raiz", + "AutoTaggingSpecificationStatus": "Estado", + "CustomFormatsSpecificationLanguage": "Idioma", + "CustomFormatsSpecificationMaximumSize": "Tamanho máximo", + "CustomFormatsSpecificationResolution": "Resolução", + "CustomFormatsSpecificationSource": "Origem" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 914d27cfd2..636945d17c 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1870,5 +1870,24 @@ "NotificationsTelegramSettingsIncludeInstanceName": "Incluir nome da instância no título", "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Opcionalmente, inclua o nome da instância na notificação", "NotificationsTelegramSettingsMetadataLinks": "Links de metadados", - "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Adicione links aos metadados da série ao enviar notificações" + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Adicione links aos metadados da série ao enviar notificações", + "AutoTaggingSpecificationGenre": "Gênero(s)", + "AutoTaggingSpecificationMaximumYear": "Ano Máximo", + "AutoTaggingSpecificationMinimumYear": "Ano Mínimo", + "AutoTaggingSpecificationOriginalLanguage": "Idioma", + "AutoTaggingSpecificationQualityProfile": "Perfil de qualidade", + "AutoTaggingSpecificationRootFolder": "Pasta raiz", + "AutoTaggingSpecificationStatus": "Estado", + "CustomFormatsSpecificationLanguage": "Idioma", + "CustomFormatsSpecificationMaximumSize": "Tamanho máximo", + "CustomFormatsSpecificationMaximumSizeHelpText": "O lançamento deve ser menor ou igual a este tamanho", + "CustomFormatsSpecificationMaximumYear": "Ano Máximo", + "CustomFormatsSpecificationMinimumSize": "Tamanho Mínimo", + "CustomFormatsSpecificationMinimumSizeHelpText": "O lançamento deve ser maior que esse tamanho", + "CustomFormatsSpecificationMinimumYear": "Ano Mínimo", + "CustomFormatsSpecificationResolution": "Resolução", + "CustomFormatsSpecificationSource": "Origem", + "AutoTaggingSpecificationMaximumRuntime": "Tempo Máximo de Duração", + "AutoTaggingSpecificationMinimumRuntime": "Tempo Mínimo de Duração", + "CustomFormatsSpecificationQualityModifier": "Modificador de Qualidade" } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 47380bab39..a3433f66c4 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1152,5 +1152,12 @@ "AddReleaseProfile": "Editați profilul de întârziere", "Delay": "Întârziere", "DownloadClientUnavailable": "Client de descărcare indisponibil", - "DownloadClientSettingsOlderPriority": "Prioritate mai vechi" + "DownloadClientSettingsOlderPriority": "Prioritate mai vechi", + "AutoTaggingSpecificationQualityProfile": "Profil de Calitate", + "AutoTaggingSpecificationRootFolder": "Folder Rădăcină", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationLanguage": "Limbă", + "CustomFormatsSpecificationMaximumSize": "Dimensiune maximă", + "CustomFormatsSpecificationSource": "Sursă", + "AutoTaggingSpecificationOriginalLanguage": "Limbă" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index da7cac6cb0..71b3a4cd6c 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1791,5 +1791,21 @@ "Completed": "Завершенный", "Delay": "Задержка", "DownloadClientUnavailable": "Программа для скачивания недоступна", - "RegularExpressionsTutorialLink": "Более подробную информацию о регулярных выражениях можно найти [здесь]({url})." + "RegularExpressionsTutorialLink": "Более подробную информацию о регулярных выражениях можно найти [здесь]({url}).", + "AutoTaggingSpecificationGenre": "Жанры", + "AutoTaggingSpecificationMaximumYear": "Максимальный год", + "AutoTaggingSpecificationMinimumYear": "Минимальный год", + "AutoTaggingSpecificationOriginalLanguage": "Язык", + "AutoTaggingSpecificationQualityProfile": "Профиль качества", + "AutoTaggingSpecificationRootFolder": "Корневой каталог", + "AutoTaggingSpecificationStatus": "Статус", + "CustomFormatsSpecificationLanguage": "Язык", + "CustomFormatsSpecificationMaximumSize": "Максимальный размер", + "CustomFormatsSpecificationMaximumSizeHelpText": "Релиз должен быть меньше или равен этому размеру", + "CustomFormatsSpecificationMaximumYear": "Максимальный год", + "CustomFormatsSpecificationMinimumSize": "Минимальный размер", + "CustomFormatsSpecificationMinimumSizeHelpText": "Релиз должен быть больше этого размера", + "CustomFormatsSpecificationMinimumYear": "Минимальный год", + "CustomFormatsSpecificationResolution": "Разрешение", + "CustomFormatsSpecificationSource": "Исходный код" } diff --git a/src/NzbDrone.Core/Localization/Core/sk.json b/src/NzbDrone.Core/Localization/Core/sk.json index ad150833f8..55b4b58ec3 100644 --- a/src/NzbDrone.Core/Localization/Core/sk.json +++ b/src/NzbDrone.Core/Localization/Core/sk.json @@ -299,5 +299,10 @@ "Reason": "Séria", "Clone": "Zatvoriť", "AllTitles": "Všetky súbory", - "Delay": "Oneskorenie" + "Delay": "Oneskorenie", + "AutoTaggingSpecificationOriginalLanguage": "jazyk", + "AutoTaggingSpecificationQualityProfile": "Profil kvality", + "AutoTaggingSpecificationRootFolder": "Koreňový priečinok", + "CustomFormatsSpecificationResolution": "Rozlíšenie", + "CustomFormatsSpecificationLanguage": "jazyk" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 8af571c739..ac0c1eab72 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1100,5 +1100,12 @@ "EditReleaseProfile": "Redigera fördröjningsprofil", "AddReleaseProfile": "Redigera fördröjningsprofil", "Delay": "Fördröj", - "DownloadClientUnavailable": "Nedladdningsklient är otillgänglig" + "DownloadClientUnavailable": "Nedladdningsklient är otillgänglig", + "AutoTaggingSpecificationQualityProfile": "Kvalitetsprofil", + "AutoTaggingSpecificationRootFolder": "Rotmapp", + "AutoTaggingSpecificationStatus": "Status", + "CustomFormatsSpecificationLanguage": "Språk", + "CustomFormatsSpecificationMaximumSize": "Maximal storlek", + "CustomFormatsSpecificationSource": "Källa", + "AutoTaggingSpecificationOriginalLanguage": "Språk" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 9e13b83748..d54cb37827 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1071,5 +1071,12 @@ "AllTitles": "เอกสารทั้งหมด", "EditReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า", "AddReleaseProfile": "แก้ไขโปรไฟล์ความล่าช้า", - "DownloadClientUnavailable": "ไม่สามารถดาวน์โหลดไคลเอนต์ได้" + "DownloadClientUnavailable": "ไม่สามารถดาวน์โหลดไคลเอนต์ได้", + "AutoTaggingSpecificationOriginalLanguage": "ภาษา", + "AutoTaggingSpecificationQualityProfile": "โปรไฟล์คุณภาพ", + "AutoTaggingSpecificationRootFolder": "โฟลเดอร์รูท", + "AutoTaggingSpecificationStatus": "สถานะ", + "CustomFormatsSpecificationLanguage": "ภาษา", + "CustomFormatsSpecificationMaximumSize": "ขนาดสูงสุด", + "CustomFormatsSpecificationSource": "ที่มา" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 3422e2aa82..071bd6d0b9 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -119,7 +119,7 @@ "NoChanges": "Değişiklikler yok", "NoChange": "Değişiklik yok", "MovieTitle": "Film başlığı", - "Movies": "Filmler", + "Movies": "Film", "MovieNaming": "Film Adlandırma", "MovieEditor": "Film Editörü", "Movie": "Film", @@ -134,7 +134,7 @@ "LastWriteTime": "Son Yazma Zamanı", "Languages": "Diller", "Language": "Dil", - "InCinemas": "Sinemalarda", + "InCinemas": "Sinemada Yayınlanan", "ImportMechanismHealthCheckMessage": "Tamamlanan İndirme İşlemini Etkinleştir", "ICalLink": "iCal Bağlantısı", "History": "Geçmiş", @@ -150,7 +150,7 @@ "Edit": "Düzenle", "Downloaded": "İndirildi", "DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName} ile iletişim kurulamıyor. {errorMessage}", - "DigitalRelease": "Dijital Yayın", + "DigitalRelease": "Dijital Yayınlanan", "DelayProfiles": "Gecikme Profilleri", "CustomFilters": "Özel Filtreler", "ConnectSettingsSummary": "Bildirimler, medya sunucularına/oynatıcılara bağlantılar ve özel komut dosyaları", @@ -198,7 +198,7 @@ "DeleteTag": "Etiketi Sil", "DetailedProgressBarHelpText": "İlerleme çubuğundaki metni göster", "IncludeCustomFormatWhenRenaming": "Yeniden Adlandırırken Özel Formatı Dahil Et", - "IndexerLongTermStatusCheckSingleClientMessage": "6 saatten uzun süredir yaşanan arızalar nedeniyle indeksleyiciler kullanılamıyor: {indexerNames}", + "IndexerLongTermStatusCheckSingleClientMessage": "6 saatten uzun süren hatalar nedeniyle kullanılamayan indeksleyiciler : {indexerNames}", "IndexerStatusCheckAllClientMessage": "Hatalar nedeniyle tüm indeksleyiciler kullanılamıyor", "Level": "Seviye", "LoadingMovieCreditsFailed": "Film jeneriği yüklenemedi", @@ -412,7 +412,7 @@ "DotNetVersion": ".NET", "NoHistory": "Geçmiş bulunamadı", "AddQualityProfile": "Kalite Profili Ekle", - "NoBackupsAreAvailable": "Kullanılabilir yedek yok", + "NoBackupsAreAvailable": "Hiçbir yedekleme mevcut değil", "AddRootFolder": "Kök Klasör Ekle", "AddToDownloadQueue": "İndirme kuyruğuna ekleyin", "AfterManualRefresh": "Manüel Yenilemeden Sonra", @@ -441,7 +441,7 @@ "ImportExtraFilesMovieHelpText": "Bir film dosyasını içe aktardıktan sonra eşleşen ekstra dosyaları (altyazılar, bilgi vb.) içe aktarın", "ImportFailed": "İçe aktarma başarısız oldu: {sourceTitle}", "CouldNotConnectSignalR": "SignalR'ye bağlanılamadı, kullanıcı arayüzü güncellenmeyecek", - "ImportLibrary": "Kütüphane İçe Aktarma", + "ImportLibrary": "Kütüphaneden İçe Aktar", "AlternativeTitlesLoadError": "Alternatif başlıklar yüklenemiyor.", "WhatsNew": "Ne var ne yok?", "Uptime": "Çalışma süresi", @@ -509,7 +509,7 @@ "NoMatchFound": "Eşleşme bulunamadı!", "NotMonitored": "Takip Edilmeyen", "MinimumAge": "Minimum Geçen Süre", - "NoUpdatesAreAvailable": "Güncelleme bulunamadı", + "NoUpdatesAreAvailable": "Güncelleme mevcut değil", "AddingTag": "Etiket ekleniyor", "Age": "Yıl", "AgeWhenGrabbed": "Yıl (alındığında)", @@ -594,7 +594,7 @@ "AddRemotePathMapping": "Uzak Yol Eşleme Ekleme", "AudioInfo": "Ses Bilgisi", "Cancel": "Vazgeç", - "PhysicalRelease": "Fiziksel Salınım", + "PhysicalRelease": "Fiziksel Yayınlanan", "Port": "Port No", "Close": "Kapat", "PortNumber": "Port numarası", @@ -632,7 +632,7 @@ "Unavailable": "Kullanım dışı", "Importing": "İçe Aktarma", "NoLeaveIt": "Hayır, Bırak", - "NotAvailable": "Müsait değil", + "NotAvailable": "Yayınlanmadı", "NotificationTriggers": "Bildirim Tetikleyicileri", "Real": "Gerçek", "ClickToChangeMovie": "Filmi değiştirmek için tıklayın", @@ -689,7 +689,7 @@ "DoNotPrefer": "Tercih etmeme", "DoNotUpgradeAutomatically": "Otomatik Olarak Yükseltme", "DownloadClient": "İndirme İstemcisi", - "DownloadClientCheckNoneAvailableMessage": "İndirme istemcisi yok", + "DownloadClientCheckNoneAvailableMessage": "İndirme istemcisi mevcut değil", "DownloadClients": "İndirme İstemcileri", "DownloadClientSettings": "İndirme İstemcisi Ayarlarını", "DownloadClientsSettingsSummary": "İndirme İstemcileri, indirme işlemleri ve uzaktan yol eşlemeleri", @@ -760,7 +760,7 @@ "IgnoredHelpText": "Bir veya daha fazla terim içeriyorsa izin reddedilecektir (büyük / küçük harfe duyarlı değildir)", "Images": "Görüntüler", "IMDb": "IMDb", - "Import": "İçe aktar", + "Import": "İçe Aktarılacak", "ImportCustomFormat": "Özel Formatı İçe Aktar", "ImportedTo": "İçeri Aktarıldı", "ImportRootPath": "{appName}'ı belirli bir filmi değil, tüm filmlerinizi içeren klasöre yöneltin. Örneğin. {1} değil {0}. Ek olarak, her film kök / kitaplık klasöründe kendi klasöründe olmalıdır.", @@ -777,7 +777,7 @@ "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır", "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır", "IndexerSettings": "İndeksleyici Ayarları", - "IndexerStatusCheckSingleClientMessage": "Hatalar nedeniyle indeksleyiciler kullanılamıyor: {indexerNames}", + "IndexerStatusCheckSingleClientMessage": "Hatalar nedeniyle kullanılamayan indeksleyiciler: {indexerNames}", "InteractiveImport": "Etkileşimli İçe Aktarma", "Interval": "Periyot", "KeepAndUnmonitorMovie": "Filmi Sakla ve Takibi Bırak", @@ -797,9 +797,9 @@ "LookingForReleaseProfiles1": "Yayımlama Profilleri mi arıyorsunuz? Deneyin", "LookingForReleaseProfiles2": "yerine.", "Lowercase": "Küçük Harf", - "ManualImportSelectLanguage": "Manuel İçe Aktar - Dil Seçin", - "ManualImportSelectMovie": "Manuel İçe Aktar - Film Seçin", - "ManualImportSelectQuality": " Manuel İçe Aktar - Kaliteyi Seçin", + "ManualImportSelectLanguage": "Manuel İçe Aktar - Dil Seç", + "ManualImportSelectMovie": "Manuel İçe Aktar - Film Seç", + "ManualImportSelectQuality": " Manuel İçe Aktar - Kalite Seç", "MappedNetworkDrivesWindowsService": "Windows Hizmeti olarak çalıştırıldığında eşlenen ağ sürücüleri kullanılamaz, daha fazla bilgi için [SSS]({url}) bölümüne bakın.", "MarkAsFailedMessageText": "'{0}' başarısız olarak işaretlemek istediğinizden emin misiniz?", "MaximumLimits": "Maksimum Sınırlar", @@ -845,7 +845,7 @@ "PreviewRenameHelpText": "İpucu: Yeniden adlandırmayı önizlemek için... 'Düzenlemeden Çık'ı seçin, ardından herhangi bir film başlığına tıklayın ve", "Priority": "Öncelik", "PrioritySettings": "Öncelik: {priority}", - "ProcessingFolders": "Klasörleri İşleme", + "ProcessingFolders": "Klasörler İşleniyor", "ProxyPasswordHelpText": "Gerekirse yalnızca bir kullanıcı adı ve şifre girmeniz gerekir. Aksi takdirde boş bırakın.", "ProxyUsernameHelpText": "Gerekirse yalnızca bir kullanıcı adı ve şifre girmeniz gerekir. Aksi takdirde boş bırakın.", "PublishedDate": "Yayınlanma Tarihi", @@ -905,9 +905,9 @@ "Seconds": "Saniye", "Seeders": "Ekme makineleri", "SelectFolder": "Dosya Seç", - "SelectLanguage": "Dil Seçin", - "SelectMovie": "Film Seçin", - "SelectQuality": "Kaliteyi Seçin", + "SelectLanguage": "Dil Seç", + "SelectMovie": "Film Seç", + "SelectQuality": "Kaliteyi Seç", "SetPermissions": "İzinleri Ayarla", "SetPermissionsLinuxHelpTextWarning": "Bu ayarların ne yaptığından emin değilseniz, değiştirmeyin.", "LongDateFormat": "Uzun Tarih Formatı", @@ -963,7 +963,7 @@ "ImportList": "Listeler", "Filters": "Filtreler", "Rating": "Puan", - "SelectLanguages": "Dil Seçin", + "SelectLanguages": "Dilleri Seç", "RssSyncIntervalHelpText": "Dakika cinsinden aralık. Devre dışı bırakmak için sıfıra ayarlayın (tüm otomatik yayın almayı durduracaktır)", "AllCollectionsHiddenDueToFilter": "Uygulanan filtre nedeniyle tüm koleksiyonlar gizlendi.", "Collections": "Koleksiyon", @@ -1684,7 +1684,7 @@ "SelectDropdown": "Seçimler...", "SelectFolderModalTitle": "{modalTitle} - Klasör seç", "SelectLanguageModalTitle": "{modalTitle} - Dil Seç", - "SelectReleaseGroup": "Yayımlama Grubunu Seçin", + "SelectReleaseGroup": "Yayımlama Grubunu Seç", "TestParsing": "Ayrıştırma Testi", "SubtitleLanguages": "Altyazı Dilleri", "ShowTmdbRatingHelpText": "Posterin altında TMDb derecelendirmesini göster", @@ -1789,10 +1789,10 @@ "ShowTags": "Etiketleri göster", "ShowTagsHelpText": "Etiketleri posterin altında göster", "Any": "Herhangi", - "DeleteSelectedImportListExclusionsMessageText": "Bu içe aktarma listesi hariç tutma işlemini silmek istediğinizden emin misiniz?", - "DeleteSelectedCustomFormats": "Özel Formatı Sil", - "DeleteSelectedCustomFormatsMessageText": "Seçilen {count} içe aktarma listesini silmek istediğinizden emin misiniz?", - "ReleaseDate": "Yayın tarihleri", + "DeleteSelectedImportListExclusionsMessageText": "Seçili içe aktarma listesi hariç tutmalarını silmek istediğinizden emin misiniz?", + "DeleteSelectedCustomFormats": "Özel Format(lar)ı Sil", + "DeleteSelectedCustomFormatsMessageText": "Seçili {count} özel formatı silmek istediğinizden emin misiniz?", + "ReleaseDate": "Yayın Tarihi", "EditSelectedCustomFormats": "Seçilen Özel Formatları Düzenle", "DeleteSelected": "Seçileni Sil", "CountCustomFormatsSelected": "{count} özel format seçildi", @@ -1802,10 +1802,10 @@ "LogSizeLimit": "Log Boyutu Sınırı", "LogSizeLimitHelpText": "Arşivlemeden önce MB cinsinden maksimum log dosya boyutu. Varsayılan 1 MB'tır.", "ManageCustomFormats": "Özel Formatları Yönet", - "ShowDigitalRelease": "Sinema Çıkış Tarihini Göster", - "ShowDigitalReleaseHelpText": "Posterin altında sinemaya çıkış tarihini göster", - "ShowPhysicalRelease": "Fiziksel Yayın Tarihi", - "ShowPhysicalReleaseHelpText": "Posterin altında sinemaya çıkış tarihini göster", + "ShowDigitalRelease": "Dijital Yayın Tarihini Göster", + "ShowDigitalReleaseHelpText": "Poster altında dijital yayın tarihini göster", + "ShowPhysicalRelease": "Fiziksel Yayın Tarihini Göster", + "ShowPhysicalReleaseHelpText": "Poster altında fiziksel yayın tarihini göster", "CountVotes": "{votes} oy", "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Bildirim gönderirken film meta verilerine bir bağlantı ekleyin", "NotificationsGotifySettingsMetadataLinks": "Meta Veri Bağlantıları", @@ -1824,8 +1824,8 @@ "Logout": "Çıkış", "NoBlocklistItems": "Engellenenler listesi öğesi yok", "LastSearched": "Son Aranan", - "ShowTraktRatingPosterHelpText": "Posterin altında Tomato derecelendirmesini göster", - "FolderNameTokens": "Dosya Adı Belirteçleri", + "ShowTraktRatingPosterHelpText": "Poster altında Trakt derecelendirmesini göster", + "FolderNameTokens": "Klasör Adı Belirteçleri", "MetadataSettingsMovieImages": "Film Görüntüleri", "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Koleksiyon adını .nfo'ya ekle", "ToggleMonitoredToUnmonitored": "İzleniyor, izlemeyi bırakmak için tıklayın", @@ -1855,7 +1855,7 @@ "MetadataXmbcSettingsMovieMetadataUrlHelpText": "TMDb ve IMDb film URL'lerini .nfo'ya ekleyin", "ToggleUnmonitoredToMonitored": "İzlenmiyor, izlemek için tıklayın", "FileBrowser": "Dosya Yöneticisi", - "Completed": "Tamamla", + "Completed": "Tamamlanmış", "DownloadClientUnavailable": "İndirme istemcisi kullanılamıyor", "Delay": "Gecikme", "Fallback": "Geri Çek", @@ -1868,7 +1868,26 @@ "MetadataKometaDeprecated": "Kometa dosyaları artık oluşturulmayacak, destek v6'da tamamen kaldırılacak", "NotificationsSettingsWebhookHeaders": "Başlıklar", "NotificationsTelegramSettingsIncludeInstanceName": "Başlığa Örnek Adını Dahil Et", - "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "İsteğe bağlı olarak Örnek adını bildirime ekleyin", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "İsteğe bağlı olarak bildirime Örnek adını ekleyin", "NotificationsTelegramSettingsMetadataLinks": "Meta Veri Bağlantıları", - "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Bildirim gönderirken film meta verilerine bir bağlantı ekleyin" + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Bildirim gönderirken film meta verilerine bir bağlantı ekleyin", + "AutoTaggingSpecificationGenre": "Tür(ler)", + "AutoTaggingSpecificationMaximumYear": "Maksimum Yıl", + "AutoTaggingSpecificationMinimumYear": "Minimum Yıl", + "AutoTaggingSpecificationOriginalLanguage": "Dil", + "AutoTaggingSpecificationQualityProfile": "Kalite Profili", + "AutoTaggingSpecificationRootFolder": "Kök Klasör", + "AutoTaggingSpecificationStatus": "Durum", + "CustomFormatsSpecificationLanguage": "Dil", + "CustomFormatsSpecificationMaximumSize": "Maksimum Boyut", + "CustomFormatsSpecificationMaximumSizeHelpText": "Sürüm bu boyuttan küçük veya eşit olmalıdır", + "CustomFormatsSpecificationMaximumYear": "Maksimum Yıl", + "CustomFormatsSpecificationMinimumSize": "Minimum Boyut", + "CustomFormatsSpecificationMinimumSizeHelpText": "Sürüm bu boyuttan daha büyük olmalıdır", + "CustomFormatsSpecificationMinimumYear": "Minimum Yıl", + "CustomFormatsSpecificationResolution": "Çözünürlük", + "CustomFormatsSpecificationSource": "Kaynak", + "AutoTaggingSpecificationMaximumRuntime": "Maksimum Çalışma Süresi", + "AutoTaggingSpecificationMinimumRuntime": "Minimum Çalışma Süresi", + "CustomFormatsSpecificationQualityModifier": "Kalite Değiştirici" } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 695d4bb943..7b9680e79d 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1292,5 +1292,21 @@ "DownloadClientUnavailable": "Клієнт завантажувача недоступний", "CountIndexersSelected": "{count} індексер(-и) обрано", "AnnouncedMovieAvailabilityDescription": "Фільми вважаються доступними, щойно їх додають у {appName}.", - "CountCustomFormatsSelected": "Користувацькі формати обрано {count}" + "CountCustomFormatsSelected": "Користувацькі формати обрано {count}", + "AutoTaggingSpecificationGenre": "Жанр(и)", + "AutoTaggingSpecificationMaximumYear": "Максимальний рік", + "AutoTaggingSpecificationMinimumYear": "Мінімальний рік", + "AutoTaggingSpecificationQualityProfile": "Профіль якості", + "AutoTaggingSpecificationRootFolder": "Коренева папка", + "AutoTaggingSpecificationStatus": "Статус", + "CustomFormatsSpecificationLanguage": "Мова", + "CustomFormatsSpecificationMaximumSize": "Максимальний розмір", + "CustomFormatsSpecificationMaximumSizeHelpText": "Випуск повинен бути меншим або дорівнювати цьому розміру", + "CustomFormatsSpecificationMaximumYear": "Максимальний рік", + "CustomFormatsSpecificationMinimumSize": "Мінімальний розмір", + "CustomFormatsSpecificationMinimumSizeHelpText": "Випуск повинен бути більше цього розміру", + "CustomFormatsSpecificationMinimumYear": "Мінімальний рік", + "CustomFormatsSpecificationResolution": "Роздільна здатність", + "CustomFormatsSpecificationSource": "Джерело", + "AutoTaggingSpecificationOriginalLanguage": "Мова" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 8dd0a23297..087a251999 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1112,5 +1112,12 @@ "DownloadClientUnavailable": "Ứng dụng khách tải xuống không khả dụng", "AddReleaseProfile": "Chỉnh sửa hồ sơ độ trễ", "EditConditionImplementation": "Thêm điều kiện - {implementationName}", - "EditIndexerImplementation": "Thêm điều kiện - {implementationName}" + "EditIndexerImplementation": "Thêm điều kiện - {implementationName}", + "AutoTaggingSpecificationOriginalLanguage": "Ngôn ngữ", + "AutoTaggingSpecificationQualityProfile": "Hồ sơ chất lượng", + "AutoTaggingSpecificationRootFolder": "Thư mục gốc", + "AutoTaggingSpecificationStatus": "Trạng thái", + "CustomFormatsSpecificationLanguage": "Ngôn ngữ", + "CustomFormatsSpecificationMaximumSize": "Kích thước tối đa", + "CustomFormatsSpecificationSource": "Nguồn" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index e71fa99e01..3cc4c55728 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1867,5 +1867,21 @@ "Warning": "警告", "MetadataKometaDeprecatedSetting": "弃用", "NotificationsTelegramSettingsMetadataLinks": "元数据链接", - "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "添加一个在发送通知时指向电影元数据的链接" + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "添加一个在发送通知时指向电影元数据的链接", + "AutoTaggingSpecificationMinimumYear": "最小年份", + "AutoTaggingSpecificationOriginalLanguage": "语言", + "AutoTaggingSpecificationQualityProfile": "质量配置", + "AutoTaggingSpecificationRootFolder": "根目录", + "AutoTaggingSpecificationStatus": "状态", + "CustomFormatsSpecificationLanguage": "语言", + "CustomFormatsSpecificationMaximumSize": "最大文件体积", + "CustomFormatsSpecificationMaximumSizeHelpText": "必须小于或等于该尺寸时才会发布", + "CustomFormatsSpecificationMaximumYear": "最大年份", + "CustomFormatsSpecificationMinimumSize": "最小尺寸", + "CustomFormatsSpecificationMinimumSizeHelpText": "必须大于该尺寸才会发布", + "CustomFormatsSpecificationMinimumYear": "最小年份", + "CustomFormatsSpecificationResolution": "分辨率", + "CustomFormatsSpecificationSource": "代码", + "AutoTaggingSpecificationGenre": "类型", + "AutoTaggingSpecificationMaximumYear": "最大年份" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index 0aeb3b6852..08b5496887 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -282,5 +282,10 @@ "AuthenticationRequiredPasswordHelpTextWarning": "請輸入新密碼", "AuthenticationRequiredUsernameHelpTextWarning": "請輸入新用戶名", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "確認新密碼", - "AutoRedownloadFailedFromInteractiveSearch": "失敗時重新下載來自手動搜索的資源" + "AutoRedownloadFailedFromInteractiveSearch": "失敗時重新下載來自手動搜索的資源", + "AutoTaggingSpecificationOriginalLanguage": "語言", + "AutoTaggingSpecificationQualityProfile": "品質設定檔", + "AutoTaggingSpecificationRootFolder": "根目錄資料夾", + "CustomFormatsSpecificationLanguage": "語言", + "CustomFormatsSpecificationResolution": "解析度" } From 0e24a3e8bc1a8dbd3b3916b258cc67153a752c53 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 12 Jan 2025 13:16:07 +0000 Subject: [PATCH 170/579] Multiple Translations updated by Weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ignore-downstream Co-authored-by: Ano10 Co-authored-by: Dimitar \"Topper\" Maznekov Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Mickaël O Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: fordas Co-authored-by: xumei51201314 Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/fi.json | 42 +++++++++---------- .../Localization/Core/zh_Hans.json | 3 +- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 7ded7b0ee0..fe875e89f3 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -7,7 +7,7 @@ "About": "Tietoja", "ImportNotForDownloads": "Älä käytä tätä latausten tuontiin latauspalvelulta. Tämä on tarkoitettu vain olemassa olevien ja järjestettyjen kirjastojen, eikä lajittelemattomien tiedostojen tuontiin.", "DeleteTag": "Poista tunniste", - "IndexerLongTermStatusCheckAllClientMessage": "Mikään tietolähde ei ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi.", + "IndexerLongTermStatusCheckAllClientMessage": "Mikään hakupalvelu ei ole käytettävissä yli kuusi tuntia kestäneiden virheiden vuoksi.", "MaximumSizeHelpText": "Kaapattavien julkaisujen enimmäiskoko megatavuina. Poista rajoitus asettamalla arvoksi 0.", "Tomorrow": "Huomenna", "MovieFolderFormat": "Elokuvakansioiden kaava", @@ -41,7 +41,7 @@ "InCinemasDate": "Teatterijulkaisu", "Interval": "Ajoitus", "IncludeUnmonitored": "Sisällytä valvomattomat", - "IndexerSearchCheckNoInteractiveMessage": "Manuaalihaulle ei ole määritetty tietolähteitä, eikä {appName} sen vuoksi löydä sillä tuloksia.", + "IndexerSearchCheckNoInteractiveMessage": "Manuaalihaulle ei ole määritetty hakupalveluita, eikä {appName} sen vuoksi löydä sillä tuloksia.", "Large": "Suuri", "LinkHere": "tässä", "ListSyncLevelHelpText": "Kirjaston elokuvia käsitellään valinnan perusteella, jos ne poistuvat tai niitä ei löydy tuontilistoilta.", @@ -131,7 +131,7 @@ "ICalFeed": "iCal-syöte", "ICalFeedHelpText": "Kopioi URL-osoite kalenteripalveluusi/-sovellukseesi tai tilaa se painamalla tästä, jos selaimesi tukee Webcal-osoitteita.", "IllRestartLater": "Käynnistän uudelleen myöhemmin", - "IndexersSettingsSummary": "Tietolähteet ja julkaisurajoitukset", + "IndexersSettingsSummary": "Hakupalvelut ja julkaisurajoitukset.", "Info": "Informatiivinen", "Add": "Lisää", "AddCustomFormat": "Lisää mukautettu muoto", @@ -224,7 +224,7 @@ "Presets": "Esiasetukset", "Profiles": "Profiilit", "ProxyType": "Välityspalvelimen tyyppi", - "PtpOldSettingsCheckMessage": "Seuraavat PassThePopcorn-tietolähteet sisältävät vanhentuneita asetuksia, jotka olisi syytä päivittää: {0}", + "PtpOldSettingsCheckMessage": "Seuraavat PassThePopcorn-hakupalvelut sisältävät vanhentuneita asetuksia, jotka olisi syytä päivittää: {0}", "QualitiesHelpText": "Listalla ylempänä olevia laatuja painotetaan enemmän vaikkei niitä ole valittu. Samoissa ryhmissä olevat laadut ovat tasaveroisia. Valitse vain halutut laadut.", "QualityProfileInUseMovieListCollection": "Elokuvaan, listaan tai kokelmaan liitettyä laatuprofiilia ei voida poistaa.", "QueueIsEmpty": "Jono on tyhjä", @@ -259,8 +259,8 @@ "InCinemas": "Teatterijulkaisu", "IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimettäessä", "IndexerFlags": "Tietolähteen liput", - "IndexerLongTermStatusCheckSingleClientMessage": "Tietolähteet eivät ole käytettävissä yli 6 tuntia kestäneiden virheiden vuoksi: {indexerNames}", - "IndexerStatusCheckAllClientMessage": "Tietolähteet eivät ole käytettävissä virheiden vuoksi", + "IndexerLongTermStatusCheckSingleClientMessage": "Hakupalvelut eivät ole käytettävissä yli kuusi tuntia kestäneiden virheiden vuoksi: {indexerNames}.", + "IndexerStatusCheckAllClientMessage": "Hakupalvelut eivät ole virheiden vuoksi käytettävissä.", "Level": "Taso", "LoadingMovieCreditsFailed": "Elokuvahyvitysten lataaminen epäonnistui", "LoadingMovieExtraFilesFailed": "Elokuvan oheistiedostojen lataus epäonnistui", @@ -561,7 +561,7 @@ "Forecast": "Ennuste", "Formats": "Muodot", "SupportedListsMoreInfo": "Lue lisää tuontilistasta painamalla 'Lisätietoja'.", - "SupportedIndexersMoreInfo": "Lue lisää tietolähteestä painamalla 'Lisätietoja'.", + "SupportedIndexersMoreInfo": "Saat tietoja yksittäisistä palveluista painamalla niiden ohessa olevia lisätietopainikkeita.", "General": "Yleiset", "GeneralSettings": "Yleiset asetukset", "GeneralSettingsSummary": "Portti, SSL-salaus, käyttäjätunnus ja salasana, välityspalvelin, analytiikka ja päivitykset.", @@ -594,14 +594,14 @@ "IncludeRecommendationsHelpText": "Sisällytä {appName}in suosittelemat elokuvat etsintänäkymään", "ImportMovies": "Tuo elokuvia", "IndexerPriority": "Tietolähteiden painotus", - "IndexerPriorityHelpText": "Tietolähteen painotus, 1– 50 (korkein-alin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen kaappauspäätökseen. {appName} käyttää edelleen kaikkia käytössä olevia tietolähteitä RSS-synkronointiin ja hakuun.", + "IndexerPriorityHelpText": "Hakupalvelun painotus, 1– 50 (korkein-alin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen kaappauspäätökseen. {appName} käyttää edelleen kaikkia käytössä olevia hakupalveluita RSS-synkronointiin ja hakuun.", "IndexerRssHealthCheckNoAvailableIndexers": "RSS-syötteitä tukevat tietolähteet eivät ole hiljattaisten tietolähdevirheiden vuoksi tilapaisesti käytettävissä.", - "IndexerRssHealthCheckNoIndexers": "RSS-synkronointia varten ei ole määritetty tietolähteitä ja tämän vuoksi {appName} ei kaappaa uusia julkaisuja automaattisesti.", + "IndexerRssHealthCheckNoIndexers": "RSS-synkronoinnille ei ole määritetty hakupalveluita, eikä {appName} tämän vuoksi kaappaa uusia julkaisuja automaattisesti.", "Indexers": "Tietolähteet", - "IndexerSearchCheckNoAutomaticMessage": "Automaattihakua varten ei ole määritetty tietolähteitä ja tämän vuoksi {appName}in automaattihaku ei löydä tuloksia.", - "IndexerSearchCheckNoAvailableIndexersMessage": "Hakua tukevat tietolähteet eivät ole hiljattaisten tietolähdevirheiden vuoksi tilapaisesti käytettävissä.", + "IndexerSearchCheckNoAutomaticMessage": "Automaattihaulle ei ole määritetty hakupalveluita, eikä {appName}in automaattihaku tämän vuoksi löydä tuloksia.", + "IndexerSearchCheckNoAvailableIndexersMessage": "Hakua tukevat hakupalvelut eivät ole hiljattaisten hakupalveluvirheiden vuoksi tilapäisesti käytettävissä.", "IndexerSettings": "Tietolähdeasetukset", - "IndexerStatusCheckSingleClientMessage": "Tietolähteet eivät ole virheiden vuoksi käytettävissä: {indexerNames}", + "IndexerStatusCheckSingleClientMessage": "Hakupalvelut eivät ole virheiden vuoksi käytettävissä: {indexerNames}.", "InstallLatest": "Asenna uusin", "InteractiveImport": "Manuaalinen tuonti", "InteractiveSearch": "Etsi manuaalisesti", @@ -672,7 +672,7 @@ "PhysicalReleaseDate": "Fyysinen julkaisu", "PreferAndUpgrade": "Suosi ja päivitä", "PreferIndexerFlags": "Painotettavat tietolähdeliput", - "PreferIndexerFlagsHelpText": "Painota tietolähteen erityislipuilla merkittyjä julkaisuja.", + "PreferIndexerFlagsHelpText": "Painota hakupalvelun erityislipuilla merkittyjä julkaisuja.", "Preferred": "Suosittu", "PreviewRename": "Nimeämisen esikatselu", "Priority": "Painotus", @@ -864,7 +864,7 @@ "UiSettings": "Käyttöliittymän asetukset", "AddConditionError": "Ehdon lisäys epäonnistui. Yritä uudelleen.", "AddDownloadClientError": "Latauspalvelun lisääminen epäonnistui. Yritä uudelleen.", - "AddIndexerError": "Uuden tietolähteen lisäys epäonnistui. Yritä uudelleen.", + "AddIndexerError": "Uuden hakupalvelun lisääminen epäonnistui. Yritä uudelleen.", "AddImportListExclusionError": "Poikkeussäännön lisäys epäonnistui. Yritä uudelleen.", "AddListError": "Tuontilistan lisäys epäonnistui. Yritä uudelleen.", "AddNotificationError": "Ilmoituspalvelun lisääminen epäonnistui. Yritä uudelleen.", @@ -969,7 +969,7 @@ "From": "lähteestä", "ImportListMissingRoot": "Tuontilistalta tai -listoilta puuttuu juurikansio: {rootFolderInfo}.", "ImportListMultipleMissingRoots": "Tuontilistoilta puuttuu useita juurikansioita: {rootFoldersInfo}", - "IndexerTagMovieHelpText": "Tietolähdettä käytetään vain vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", + "IndexerTagMovieHelpText": "Hakupalvelua käytetään vain vähintään yhdellä täsmäävällä tunnisteella merkityille elokuville. Käytä kaikille jättämällä tyhjäksi.", "Letterboxd": "Letterboxd", "NotificationTriggersHelpText": "Valitse ilmoituksen laukaisevat tapahtumat.", "RemotePathMappingCheckDownloadPermissions": "{appName} näkee ladatun elokuvan \"{path}\", muttei voi avata sitä. Tämä johtuu todennäköisesti liian rajallisista käyttöoikeuksista.", @@ -1071,7 +1071,7 @@ "DeleteCustomFormatMessageText": "Haluatko varmasti poistaa mukautetun muodon \"{name}\"?", "DeleteDelayProfileMessageText": "Haluatko varmasti poistaa viiveprofiilin?", "DeleteSelectedImportLists": "Poista tuontilista(t)", - "DeleteSelectedIndexers": "Poista tietoläh(de/teet)", + "DeleteSelectedIndexers": "Poista hakupalvelu(t)", "ApplyTagsHelpTextAdd": "– \"Lisää\" syötetyt tunnisteet aiempiin tunnisteisiin", "ApplyTagsHelpTextHowToApplyIndexers": "Tunnisteiden käyttö valituille tietolähteille", "ApplyTagsHelpTextRemove": "- \"Poista\" tyhjentää syötetyt tunnisteet", @@ -1215,7 +1215,7 @@ "DeletedReasonManual": "Tiedosto poistettiin {appName}illa, joko manuaalisesti tai rajapinnan välityksellä jonkin muun työkalun pyynnöstä.", "DeletedReasonUpgrade": "Tiedosto poistettiin päivitetyn version tuomiseksi", "InteractiveImportNoMovie": "Elokuva on valittava jokaiselle valitulle tiedostolle.", - "MovieGrabbedTooltip": "Elokuva kaapattiin tietolähteestä {indexer} ja välitettiin latauspalvelulle {downloadClient}.", + "MovieGrabbedTooltip": "Elokuva kaapattiin hakupalvelusta {indexer} ja välitettiin latauspalvelulle {downloadClient}.", "CloneCondition": "Monista ehto", "AutomaticAdd": "Automaattinen lisäys", "AutoTagging": "Automaattinen tunnistemerkintä", @@ -1290,7 +1290,7 @@ "ReleaseProfiles": "Julkaisuprofiilit", "UnknownEventTooltip": "Tuntematon tapahtuma", "DeleteSelectedMovieFilesHelpText": "Haluatko varmasti poistaa valitut elokuvatiedostot?", - "ApplyTagsHelpTextHowToApplyMovies": "Miten tunnisteita käytetään valituille elokuville.", + "ApplyTagsHelpTextHowToApplyMovies": "Tunnisteiden käyttö valituille elokuville:", "Popularity": "Suosio", "IgnoreDownloadsHint": "Estää {appName}ia käsittelemästä näitä latauksia jatkossa.", "NotificationsAppriseSettingsConfigurationKey": "Apprise-määritysavain", @@ -1767,7 +1767,7 @@ "DownloadClientUnavailable": "Latauspalvelu ei ole käytettävissä", "AnnouncedMovieAvailabilityDescription": "Elokuvien käsitellään saatavilla olevina heti kun ne on lisätty {appName}iin.", "Recommended": "Suositeltu", - "ReleaseProfileIndexerHelpTextWarning": "Jos julkaisuprofiilille määritetään tietty tietolähde, koskee se vain kyseisen tietolähteen julkaisuja.", + "ReleaseProfileIndexerHelpTextWarning": "Jos julkaisuprofiilille määritetään tietty hakupalvelu, koskee se vain kyseisen palvelun julkaisuja.", "ShowTagsHelpText": "Näytä tunnisteet julisteen alla.", "NotificationsTelegramSettingsMetadataLinks": "Metatietolinkit", "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Ilmoituksiin voidaan tarvittaessa sisällyttää instannin nimi.", @@ -1786,7 +1786,7 @@ "CustomFormatsSettingsTriggerInfo": "Mukautettua muotoa sovelletaan julkaisuun tai tiedostoon, kun ainakin yksi valituista ehtotyypeistä täsmää.", "CustomFormatsSpecificationExceptLanguageHelpText": "Täsmää, jos havaitaan mikä tahansa muu kuin valittu kieli.", "DownloadClientRTorrentSettingsAddStoppedHelpText": "Tämä lisää torrentit ja magnet-linkit rTorentiin pysäytetyssä tilassa. Tämä saattaa rikkoa margnet-tiedostot.", - "DownloadClientRTorrentProviderMessage": "rTorrent ei pysäytä torrenteja niiden saavuttaessa jakomääritykset. {appName} suorittaa tietolähdeasetusten jakomäärityksiin perustuvan torrentien automaattisen poiston vain \"Poista valmistuneet\" -asetuksen ollessa käytössä. Tuonnin jälkeen se asettaa näkymän {importedView} rTorrent-näkymäksi, jota voidaan käyttää rTorrentin komentosarjojen kanssa.", + "DownloadClientRTorrentProviderMessage": "rTorrent ei pysäytä torrenteja niiden saavuttaessa jakomääritykset. {appName} suorittaa hakupalveluasetusten jakomäärityksiin perustuvan torrentien automaattisen poiston vain \"Poista valmistuneet\" -asetuksen ollessa käytössä. Tuonnin jälkeen se asettaa näkymän {importedView} rTorrent-näkymäksi, jota voidaan käyttää rTorrentin komentosarjojen kanssa.", "DownloadClientRTorrentSettingsUrlPathHelpText": "Polku XMLRPC-päätteeseen, ks. \"{url}\". Käytettäessä ruTorrentia tämä on yleensä RPC2 tai [ruTorrentin sijainti]{url2}.", "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "\"Tarkista ennen lataamista\" vaikuttaa {appName}in kykyyn valvoa uusia latauksia. Lisäksi SABnzb suosittelee tämän sijaan \"Peru lataukset, jotka eivät voi valmistua\" -asetusta, koska se on varmatoimisempi.", "DownloadClientValidationAuthenticationFailureDetail": "Vahvista käyttäjätunnuksesi ja salasanasi. Varmista myös, ettei latauspalveluun {clientName} ole määritetty sääntöjä, jotka estävät {appName}in suorittavaa laitetta tavoittamasta sitä.", @@ -1801,7 +1801,7 @@ "DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent ilmoittaa puuttuvista tiedostoista", "ExistsInLibrary": "On jo kirjastossa", "TodayAt": "Tänään klo {time}", - "IndexerSettingsMultiLanguageReleaseHelpText": "Mitkä kielet tämän tietolähteen monikielisiin julkaisuihin yleensä sisältyvät?", + "IndexerSettingsMultiLanguageReleaseHelpText": "Mitkä kielet tämän hakupalvelun monikielisiin julkaisuihin yleensä sisältyvät?", "CountCustomFormatsSelected": "{count} mukautettu(a) muoto(a) on valittu", "Install": "Asenna", "InstallMajorVersionUpdate": "Asenna päivitys", diff --git a/src/NzbDrone.Core/Localization/Core/zh_Hans.json b/src/NzbDrone.Core/Localization/Core/zh_Hans.json index b49f406e72..28374badfc 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_Hans.json +++ b/src/NzbDrone.Core/Localization/Core/zh_Hans.json @@ -3,5 +3,6 @@ "About": "关于", "Always": "总是", "Analytics": "分析", - "Username": "用户名" + "Username": "用户名", + "Activity": "111" } From c2ac49a8735940bb42a7a85b3bff7764f8c954fa Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sat, 11 Jan 2025 02:05:23 +0100 Subject: [PATCH 171/579] Additional logging for custom format score (cherry picked from commit 3c8268c428688cc703af76b648c9b3385858274f) Closes #10828 --- .../DecisionEngine/DownloadDecisionMaker.cs | 2 ++ .../CustomFormatAllowedByProfileSpecification.cs | 12 +++++++++++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index 039f44d372..b7d05f541e 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -96,6 +96,8 @@ private IEnumerable GetDecisions(List reports, bo remoteMovie.CustomFormats = _formatCalculator.ParseCustomFormat(remoteMovie, remoteMovie.Release.Size); remoteMovie.CustomFormatScore = remoteMovie?.Movie?.QualityProfile?.CalculateCustomFormatScore(remoteMovie.CustomFormats) ?? 0; + _logger.Trace("Custom Format Score of '{0}' [{1}] calculated for '{2}'", remoteMovie.CustomFormatScore, remoteMovie.CustomFormats?.ConcatToString(), report.Title); + remoteMovie.DownloadAllowed = remoteMovie.Movie != null; decision = GetDecisionForReport(remoteMovie, searchCriteria); } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs index ec62bb49d3..891a4c26d2 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs @@ -1,3 +1,4 @@ +using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Core.IndexerSearch.Definitions; using NzbDrone.Core.Parser.Model; @@ -6,6 +7,13 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { public class CustomFormatAllowedbyProfileSpecification : IDecisionEngineSpecification { + private readonly Logger _logger; + + public CustomFormatAllowedbyProfileSpecification(Logger logger) + { + _logger = logger; + } + public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; @@ -16,9 +24,11 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (score < minScore) { - return Decision.Reject("Custom Formats {0} have score {1} below Movie's minimum {2}", subject.CustomFormats.ConcatToString(), score, minScore); + return Decision.Reject("Custom Formats {0} have score {1} below Movie's profile minimum {2}", subject.CustomFormats.ConcatToString(), score, minScore); } + _logger.Trace("Custom Format Score of {0} [{1}] above Movie's profile minimum {2}", score, subject.CustomFormats.ConcatToString(), minScore); + return Decision.Accept(); } } From 99f6be3f3dd71004d4956c5db6652adc44256eeb Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sat, 11 Jan 2025 02:05:46 +0100 Subject: [PATCH 172/579] New: Show release source in history grab details (cherry picked from commit 1609f0c9647b89bf55b8c043eeffc8a61653a1e5) Closes #10830 --- .../History/Details/HistoryDetails.tsx | 34 +++++++++++++++++++ src/NzbDrone.Core/Localization/Core/en.json | 3 ++ 2 files changed, 37 insertions(+) diff --git a/frontend/src/Activity/History/Details/HistoryDetails.tsx b/frontend/src/Activity/History/Details/HistoryDetails.tsx index 3f9bcbfe90..be0eb5399a 100644 --- a/frontend/src/Activity/History/Details/HistoryDetails.tsx +++ b/frontend/src/Activity/History/Details/HistoryDetails.tsx @@ -41,6 +41,7 @@ function HistoryDetails(props: HistoryDetailsProps) { indexer, releaseGroup, movieMatchType, + releaseSource, customFormatScore, nzbInfoUrl, downloadClient, @@ -53,6 +54,31 @@ function HistoryDetails(props: HistoryDetailsProps) { const downloadClientNameInfo = downloadClientName ?? downloadClient; + let releaseSourceMessage = ''; + + switch (releaseSource) { + case 'Unknown': + releaseSourceMessage = translate('Unknown'); + break; + case 'Rss': + releaseSourceMessage = translate('Rss'); + break; + case 'Search': + releaseSourceMessage = translate('Search'); + break; + case 'UserInvokedSearch': + releaseSourceMessage = translate('UserInvokedSearch'); + break; + case 'InteractiveSearch': + releaseSourceMessage = translate('InteractiveSearch'); + break; + case 'ReleasePush': + releaseSourceMessage = translate('ReleasePush'); + break; + default: + releaseSourceMessage = ''; + } + return ( ) : null} + {releaseSource ? ( + + ) : null} + {nzbInfoUrl ? ( diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 71da4174a8..d41c025b02 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1459,7 +1459,9 @@ "ReleaseProfileTagMovieHelpText": "Release profiles will apply to movies with at least one matching tag. Leave blank to apply to all movies", "ReleaseProfiles": "Release Profiles", "ReleaseProfilesLoadError": "Unable to load Release Profiles", + "ReleasePush": "Release Push", "ReleaseRejected": "Release Rejected", + "ReleaseSource": "Release Source", "ReleaseStatus": "Release Status", "ReleaseTitle": "Release Title", "Released": "Released", @@ -1859,6 +1861,7 @@ "UsenetDelayHelpText": "Delay in minutes to wait before grabbing a release from Usenet", "UsenetDelayTime": "Usenet Delay: {usenetDelay}", "UsenetDisabled": "Usenet Disabled", + "UserInvokedSearch": "User Invoked Search", "Username": "Username", "Version": "Version", "VideoCodec": "Video Codec", From f6b364725d8357ecf673fa77a39b32967c243149 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Sat, 11 Jan 2025 02:06:05 +0100 Subject: [PATCH 173/579] Additional logging for delay profile decisions (cherry picked from commit fa0f77659cbd3e9efdae55bbedb30fd8288622a6) Closes #10831 --- .../Specifications/RssSync/DelaySpecification.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs index 0d84dd1140..d7640e25b6 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs @@ -47,11 +47,13 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (delay == 0) { - _logger.Debug("Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol); + _logger.Debug("Delay Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol); return Decision.Accept(); } - var comparer = new QualityModelComparer(profile); + _logger.Debug("Delay Profile requires a waiting period of {0} minutes for {1}", delay, subject.Release.DownloadProtocol); + + var qualityComparer = new QualityModelComparer(profile); var file = subject.Movie.MovieFile; @@ -80,7 +82,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (delayProfile.BypassIfHighestQuality) { var bestQualityInProfile = profile.LastAllowedQuality(); - var isBestInProfile = comparer.Compare(subject.ParsedMovieInfo.Quality.Quality, bestQualityInProfile) >= 0; + var isBestInProfile = qualityComparer.Compare(subject.ParsedMovieInfo.Quality.Quality, bestQualityInProfile) >= 0; if (isBestInProfile && isPreferredProtocol) { @@ -106,6 +108,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (oldest != null && oldest.Release.AgeMinutes > delay) { + _logger.Debug("Oldest pending release {0} has been delayed for {1}, longer than the set delay of {2}. Release will be accepted", oldest.Release.Title, oldest.Release.AgeMinutes, delay); return Decision.Accept(); } From b452c10da34603e6e640b19df675ab932849be04 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 14 Jan 2025 10:47:59 +0200 Subject: [PATCH 174/579] Bump SonarCloud azure extension for UI analysis to 3.X (cherry picked from commit 396b2ae7c10c7df749ea23ea93608b56482175a1) --- azure-pipelines.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index fd7a89c059..26b18fd386 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -1116,20 +1116,20 @@ stages: vmImage: ${{ variables.windowsImage }} steps: - checkout: self # Need history for Sonar analysis - - task: SonarCloudPrepare@2 + - task: SonarCloudPrepare@3 env: SONAR_SCANNER_OPTS: '' inputs: SonarCloud: 'SonarCloud' organization: 'radarr' - scannerMode: 'CLI' + scannerMode: 'cli' configMode: 'manual' cliProjectKey: 'Radarr_Radarr.UI' cliProjectName: 'RadarrUI' cliProjectVersion: '$(radarrVersion)' cliSources: './frontend' - - task: SonarCloudAnalyze@2 - + - task: SonarCloudAnalyze@3 + - job: Api_Docs displayName: API Docs dependsOn: Prepare From d58135bf1754b6185eef19a2f4069b27a918d01e Mon Sep 17 00:00:00 2001 From: kephasdev <160031725+kephasdev@users.noreply.github.com> Date: Fri, 17 Jan 2025 13:32:09 -0500 Subject: [PATCH 175/579] Fixed: Augmenting languages for releases with MULTI and other languages (#10842) --- .../Aggregators/AggregateLanguagesFixture.cs | 44 +++++++++++++++++++ .../Aggregators/AggregateLanguages.cs | 11 ++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs b/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs index 638ea84019..355e1396b8 100644 --- a/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Aggregation/Aggregators/AggregateLanguagesFixture.cs @@ -167,6 +167,50 @@ public void should_return_multi_languages_when_release_as_unknown_as_default_lan Mocker.GetMock().VerifyNoOtherCalls(); } + [Test] + public void should_return_multi_languages_when_release_as_specified_language_and_indexer_has_multi_languages_configuration() + { + var releaseTitle = "Some.Movie.2024.MULTi.VFF.VFQ.1080p.BluRay.DTS.HDMA.x264-RlsGroup"; + var indexerDefinition = new IndexerDefinition + { + Id = 1, + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } + }; + Mocker.GetMock() + .Setup(v => v.Find(1)) + .Returns(indexerDefinition); + + _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { Language.French }, releaseTitle); + _remoteMovie.Release.IndexerId = 1; + _remoteMovie.Release.Title = releaseTitle; + + Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French }); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); + Mocker.GetMock().VerifyNoOtherCalls(); + } + + [Test] + public void should_return_multi_languages_when_release_as_other_language_and_indexer_has_multi_languages_configuration() + { + var releaseTitle = "Some.Movie.2024.MULTi.GERMAN.1080p.BluRay.DTS.HDMA.x264-RlsGroup"; + var indexerDefinition = new IndexerDefinition + { + Id = 1, + Settings = new TorrentRssIndexerSettings { MultiLanguages = new List { Language.Original.Id, Language.French.Id } } + }; + Mocker.GetMock() + .Setup(v => v.Find(1)) + .Returns(indexerDefinition); + + _remoteMovie.ParsedMovieInfo = GetParsedMovieInfo(new List { Language.German }, releaseTitle); + _remoteMovie.Release.IndexerId = 1; + _remoteMovie.Release.Title = releaseTitle; + + Subject.Aggregate(_remoteMovie).Languages.Should().BeEquivalentTo(new List { _movie.MovieMetadata.Value.OriginalLanguage, Language.French, Language.German }); + Mocker.GetMock().Verify(c => c.Find(1), Times.Once()); + Mocker.GetMock().VerifyNoOtherCalls(); + } + [Test] public void should_return_original_when_indexer_has_no_multi_languages_configuration() { diff --git a/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs b/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs index 5b89aa82e2..d4d906d0e7 100644 --- a/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs +++ b/src/NzbDrone.Core/Download/Aggregation/Aggregators/AggregateLanguages.cs @@ -71,7 +71,7 @@ public RemoteMovie Aggregate(RemoteMovie remoteMovie) languages = languages.Except(languagesToRemove).ToList(); } - if ((languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown)) && releaseInfo?.Title?.IsNotNullOrWhiteSpace() == true) + if (releaseInfo?.Title?.IsNotNullOrWhiteSpace() == true) { IndexerDefinition indexer = null; @@ -88,7 +88,14 @@ public RemoteMovie Aggregate(RemoteMovie remoteMovie) if (indexer?.Settings is IIndexerSettings settings && settings.MultiLanguages.Any() && Parser.Parser.HasMultipleLanguages(releaseInfo.Title)) { // Use indexer setting for Multi-languages - languages = settings.MultiLanguages.Select(i => (Language)i).ToList(); + if (languages.Count == 0 || (languages.Count == 1 && languages.First() == Language.Unknown)) + { + languages = settings.MultiLanguages.Select(i => (Language)i).ToList(); + } + else + { + languages.AddRange(settings.MultiLanguages.Select(i => (Language)i).Except(languages).ToList()); + } } } From d4715f119da637a90c5eb98f7d97d5b0b84894fa Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 19 Jan 2025 16:54:39 +0200 Subject: [PATCH 176/579] Bump version to 5.18.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 26b18fd386..5653118cb4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.18.1' + majorVersion: '5.18.2' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 3d52f45b6a0636d2595884211687884b2713d5e9 Mon Sep 17 00:00:00 2001 From: jcassette Date: Sat, 18 Jan 2025 04:55:37 +0100 Subject: [PATCH 177/579] New: reflink support for ZFS (cherry picked from commit a840bb542362d58006b6cc27affd58ee6b965b80) --- src/NzbDrone.Common/Disk/DiskTransferService.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Common/Disk/DiskTransferService.cs b/src/NzbDrone.Common/Disk/DiskTransferService.cs index 2da930a787..f89c31b212 100644 --- a/src/NzbDrone.Common/Disk/DiskTransferService.cs +++ b/src/NzbDrone.Common/Disk/DiskTransferService.cs @@ -341,10 +341,11 @@ public TransferMode TransferFile(string sourcePath, string targetPath, TransferM var isCifs = targetDriveFormat == "cifs"; var isBtrfs = sourceDriveFormat == "btrfs" && targetDriveFormat == "btrfs"; + var isZfs = sourceDriveFormat == "zfs" && targetDriveFormat == "zfs"; if (mode.HasFlag(TransferMode.Copy)) { - if (isBtrfs) + if (isBtrfs || isZfs) { if (_diskProvider.TryCreateRefLink(sourcePath, targetPath)) { @@ -358,7 +359,7 @@ public TransferMode TransferFile(string sourcePath, string targetPath, TransferM if (mode.HasFlag(TransferMode.Move)) { - if (isBtrfs) + if (isBtrfs || isZfs) { if (isSameMount && _diskProvider.TryRenameFile(sourcePath, targetPath)) { From af0c96538a1a7837b61dfed6a72cc775185557e5 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 19 Jan 2025 14:54:47 +0000 Subject: [PATCH 178/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Dimitar \"Topper\" Maznekov Co-authored-by: GkhnGRBZ Co-authored-by: Lizandra Candido da Silva Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: ahgharaghani Co-authored-by: keysuck Co-authored-by: warkurre86 Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fa/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/bg.json | 48 +- src/NzbDrone.Core/Localization/Core/cs.json | 10 +- src/NzbDrone.Core/Localization/Core/fa.json | 4 +- src/NzbDrone.Core/Localization/Core/fi.json | 133 +- src/NzbDrone.Core/Localization/Core/ko.json | 1661 ++++++++++++----- .../Localization/Core/nb_NO.json | 9 +- .../Localization/Core/pt_BR.json | 25 +- src/NzbDrone.Core/Localization/Core/tr.json | 31 +- 8 files changed, 1389 insertions(+), 532 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index aad4c50d37..851f33ec2f 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -158,7 +158,7 @@ "DeleteRestriction": "Изтриване на ограничението", "DeleteRestrictionHelpText": "Наистина ли искате да изтриете това ограничение?", "DeleteSelectedMovieFiles": "Изтриване на избрани филмови файлове", - "DeleteTagMessageText": "Наистина ли искате да изтриете маркера '{0}'?", + "DeleteTagMessageText": "Наистина ли искате да изтриете маркера '{label}'?", "DeleteMovieFolderConfirmation": "Папката с филма „{0}“ и цялото й съдържание ще бъдат изтрити.", "DestinationPath": "Път на дестинацията", "DetailedProgressBar": "Подробна лента за напредъка", @@ -1147,5 +1147,49 @@ "ApiKeyValidationHealthCheckMessage": "Моля, актуализирайте API ключа си така, че да съдържа поне {length} знака. Можете да направите това чрез настройките или конфигурационния файл", "AudioLanguages": "Аудио езици", "CustomFormatsSpecificationExceptLanguage": "Освен езика", - "Database": "База данни" + "Database": "База данни", + "Directory": "Директория", + "Donate": "Дарете", + "DownloadClientDelugeSettingsDirectoryHelpText": "Незадължителна локация за изтеглянията, оставете празно, за да използвате мястото по подразбиране на Deluge", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "Незадължителна споделена папка, в която да се поставят изтеглянията, оставете празно, за да използвате местоположението по подразбиране на Download Station", + "DownloadClientFloodSettingsAdditionalTags": "Допълнителни тагове", + "DownloadClientFloodSettingsStartOnAdd": "Старт при добавяне", + "DownloadClientDownloadStationValidationApiVersion": "Версията на API на Download Station не се поддържа, трябва да е поне {requiredVersion} Поддържа се от {minVersion} до {maxVersion}", + "DeletedReasonManual": "Файлът беше изтрит с помощта на {appName}, ръчно или чрез друг инструмент чрез API", + "DownloadClientFloodSettingsPostImportTagsHelpText": "Добавя тагове след импортиране на изтегляне.", + "DownloadClientFloodSettingsTagsHelpText": "Първоначални тагове на изтегляне. За да бъде разпознато едно изтегляне, то трябва да има всички начални тагове. По този начин се избягват конфликти с необвързани с приложение изтегляния.", + "Destination": "Дестинация", + "DownloadClientDelugeSettingsDirectory": "Директория за изтегляне", + "DownloadClientDelugeSettingsDirectoryCompleted": "Директория за вече завършените изтегляния", + "DownloadClientDownloadStationValidationNoDefaultDestination": "Няма дестинация по подразбиране", + "BlocklistFilterHasNoItems": "Избраният филтър за блокиране не съдържа елементи", + "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Минимална резултат на персонализирания формат, необходима за пропускане на забавянето за предпочитания протокол", + "BlocklistMultipleOnlyHint": "Списък за блокиране без търсене на заместители", + "DoNotBlocklist": "Не блокирайте", + "DownloadClientFloodSettingsAddPaused": "Добави на пауза", + "DownloadClientDownloadStationValidationFolderMissing": "Папката не съществува", + "DoNotBlocklistHint": "Премахване без блокиране", + "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} не успя да добави етикета към {clientName}.", + "BlocklistOnly": "Само списък за блокиране", + "BlocklistOnlyHint": "Списък за блокиране без търсене на заместител", + "BypassDelayIfAboveCustomFormatScore": "Пропусни, ако е над рейтинга на персонализирания формат", + "BypassDelayIfAboveCustomFormatScoreHelpText": "Активиране на пропускане, когато изданието има резултат, по-висок от конфигурирания минимален резултат за потребителски формат", + "DiscordUrlInSlackNotification": "Имате настройка за известяване на Discord като Slack известие. Настройте това като известие в Discord за по-добра функционалност. Засегнатите известия са: {0}", + "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Незадължителна локация за преместване на вече завършените изтегляния, оставете празно, за да използвате мястото по подразбиране на Deluge", + "DownloadClientDelugeSettingsUrlBaseHelpText": "Добавя префикс към url адреса на deluge json, вижте {url}", + "DownloadClientDelugeTorrentStateError": "Deluge съобщава за грешка", + "DownloadClientDelugeValidationLabelPluginFailure": "Конфигурирането на етикета е неуспешно", + "DownloadClientDelugeValidationLabelPluginInactive": "Плъгинът за етикети не е активиран", + "DownloadClientDelugeValidationLabelPluginInactiveDetail": "За да използвате категориите, трябва да е активирана приставката Етикети в {clientName}.", + "DownloadClientDownloadStationProviderMessage": "{appName} не може да се свърже със Download Station, ако в DSM акаунта е разрешено двуфакторно удостоверяване", + "DownloadClientDownloadStationValidationFolderMissingDetail": "Папката '{downloadDir}' не съществува, тя трябва да бъде създадена ръчно в споделената папка '{sharedFolder}'.", + "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Трябва да влезете в Diskstation като {username} и да го настроите ръчно в настройките на DownloadStation в BT/HTTP/FTP/NZB -> Местоположение.", + "DownloadClientDownloadStationValidationSharedFolderMissing": "Споделената папка не съществува", + "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Diskstation няма споделена папка с име '{sharedFolder}', сигурни ли сте, че сте я задали правилно?", + "DownloadClientFloodSettingsPostImportTags": "Тагове след импорта", + "DownloadClientFloodSettingsAdditionalTagsHelpText": "Добавя свойствата на медията като тагове. Напътствията са примери.", + "DownloadClientFloodSettingsRemovalInfo": "{appName} ще се справи с автоматичното премахване на торенти въз основа на текущите критерии за сийд в Настройки -> Индексатори", + "DownloadClientAriaSettingsDirectoryHelpText": "Незадължително локация за изтеглянията, оставете празно, за да използвате локацията по подразбиране на Aria2", + "BlocklistReleaseHelpText": "Блокира изтеглянето на тази версия от {appName} чрез RSS или автоматично търсене", + "Disposition": "Разпореждане" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 09f8b27647..d70d079921 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -307,7 +307,7 @@ "RecyclingBinCleanup": "Recyklace koše Vyčištění", "Refresh": "Obnovit", "RefreshMovie": "Obnovit film", - "RegularExpressionsCanBeTested": "Regulární výrazy lze testovat ", + "RegularExpressionsCanBeTested": "Regulární výrazy lze testovat [zde]({url}).", "RejectionCount": "Počet odmítnutí", "RelativePath": "Relativní cesta", "Released": "Uvolněno", @@ -634,7 +634,7 @@ "Indexers": "Indexery", "IndexerSearchCheckNoAutomaticMessage": "Nejsou k dispozici žádné indexery se zapnutým automatickým vyhledáváním, {appName} neposkytne žádné automatické výsledky hledání", "IndexerSearchCheckNoAvailableIndexersMessage": "Všechny indexery podporující vyhledávání jsou dočasně nedostupné kvůli nedávným chybám indexeru", - "IndexerSearchCheckNoInteractiveMessage": "Při povoleném interaktivním vyhledávání, nejsou dostupné žádné indexovací moduly, {appName} neposkytne žádné interaktivní výsledky hledání", + "IndexerSearchCheckNoInteractiveMessage": "Se zapnutým interaktivním vyhledáváním nejsou k dispozici žádné indexery, {appName} neposkytne žádné výsledky interaktivního vyhledávání", "IndexerSettings": "Nastavení indexeru", "IndexerStatusCheckSingleClientMessage": "Indexery nedostupné z důvodu selhání: {indexerNames}", "InstallLatest": "Nainstalujte nejnovější", @@ -663,7 +663,7 @@ "ManualImportSelectLanguage": "Ruční import - vyberte jazyk", "ManualImportSelectMovie": "Ruční import - vyberte Film", "ManualImportSelectQuality": " Ruční import - vyberte kvalitu", - "MappedNetworkDrivesWindowsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v častých dotazech", + "MappedNetworkDrivesWindowsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v [FAQ]({url}).", "MarkAsFailedMessageText": "Opravdu chcete označit „{0}“ jako neúspěšné?", "MassMovieSearch": "Hromadné vyhledávání filmů", "MaximumLimits": "Maximální limity", @@ -1261,5 +1261,7 @@ "External": "Externí", "NotificationsGotifySettingsAppToken": "Token aplikace", "UsenetBlackholeNzbFolder": "Složka Nzb", - "DownloadClientFloodSettingsAdditionalTags": "Další štítky" + "DownloadClientFloodSettingsAdditionalTags": "Další štítky", + "ManualImportSetReleaseGroup": "Ruční import - nastavte skupinu vydání", + "NotificationTriggersHelpText": "Vyber, které události mají vyvolat toto upozornění" } diff --git a/src/NzbDrone.Core/Localization/Core/fa.json b/src/NzbDrone.Core/Localization/Core/fa.json index 0967ef424b..0d96703016 100644 --- a/src/NzbDrone.Core/Localization/Core/fa.json +++ b/src/NzbDrone.Core/Localization/Core/fa.json @@ -1 +1,3 @@ -{} +{ + "About": "درباره" +} diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index fe875e89f3..63e8e78997 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -26,7 +26,7 @@ "DeleteQualityProfile": "Poista laatuprofiili", "DeleteSelectedMovieFiles": "Poista valitut elokuvatiedostot", "DestinationPath": "Kohdesijainti", - "EditImportListExclusion": "Muokkaa poikkeussääntöä", + "EditImportListExclusion": "Muokkaa poikkeusta", "EnableAutomaticAdd": "Käytä automaattilisäystä", "ExistingTag": "Tunniste on jo olemassa", "ExtraFileExtensionsHelpText": "Pilkuin eroteltu listaus tuotavista oheistiedostoista (.nfo-tiedostot tuodaan \".nfo-orig\"-nimellä).", @@ -71,13 +71,13 @@ "Time": "Aika", "BrowserReloadRequired": "Vaatii selaimen sivupäivityksen (F5).", "UiSettingsSummary": "Kalenterin, päiväyksen ja kellonajan, sekä kielen ja heikentyneelle värinäölle sopivan tilan asetukset.", - "AddCustomFormatError": "Mukautetun muodon lisäys epäonnistui. Yritä uudelleen.", + "AddCustomFormatError": "Virhe lisättäessä mukautettua muotoa. Yritä uudelleen.", "UpdateCheckUINotWritableMessage": "Päivityksen asennus ei onnistu, koska käyttäjällä {userName} ei ole kirjoitusoikeutta käyttöliittymäkansioon \"{uiFolder}\".", "UpdateScriptPathHelpText": "Polku komentosarjaan, joka käsittelee puretun päivitystiedoston ja hoitaa asennuksen loppuosuuden.", "Version": "Versio", - "AddExclusion": "Lisää poikkeussääntö", + "AddExclusion": "Lisää poikkeus", "AddNew": "Lisää uusi", - "AudioInfo": "Äänitiedot", + "AudioInfo": "Äänen tiedot", "BeforeUpdate": "Ennen päivitystä", "DownloadPropersAndRepacksHelpTextCustomFormat": "\"Älä suosi\" käyttää Proper-/Repack-julkaisujen sijaan mukautettujen muotojen pisteytystä.", "Day": "Päivä", @@ -95,7 +95,7 @@ "CalendarOptions": "Kalenterin asetukset", "Certification": "Varmennus", "ChangeFileDate": "Muuta tiedoston päiväys", - "AddIndexer": "Lisää tietolähde", + "AddIndexer": "Lisää hakupalvelu", "CheckForFinishedDownloadsInterval": "Valmistuneiden latausten takistusväli", "AutomaticSearch": "Automaattihaku", "Announced": "Julkistettu", @@ -199,7 +199,7 @@ "NextExecution": "Seuraava suoritus", "NoAlternativeTitles": "Ei vaihtoehtoisia nimikkeitä.", "NoEventsFound": "Tapahtumia ei löytynyt", - "NoLinks": "Ei linkkejä", + "NoLinks": "Linkkejä ei ole", "NoMinimumForAnyRuntime": "Ei toistoajan vähimmäiskestoa", "NoMoveFilesSelf": " Ei, siirrän tiedostot itse", "NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.", @@ -242,7 +242,7 @@ "SuggestTranslationChange": "Ehdota käännösmuutosta", "Queued": "Lisätty jonoon", "TMDb": "TMDB", - "AlternativeTitlesLoadError": "Vaihtoehtoisten nimien lataus epäonnistui", + "AlternativeTitlesLoadError": "Virhe ladattaessa vaihtoehtoisia nimiä.", "Released": "Julkaistu", "ReleasedMovieDescription": "Elokuva julkaistaan", "ReplaceWithDash": "Korvaa yhdysmerkillä", @@ -341,7 +341,7 @@ "Uptime": "Käyttöaika", "NoLogFiles": "Lokitiedostoja ei ole", "NoMatchFound": "Hakua ei löytynyt!", - "NotMonitored": "Valvomaton", + "NotMonitored": "Ei valvota", "NoUpdatesAreAvailable": "Päivityksiä ei ole saatavilla", "OAuthPopupMessage": "Selaimesi estää ponnahdukset", "Ok": "Ok", @@ -420,7 +420,7 @@ "ClickToChangeMovie": "Vaihda elokuvaa painamalla tästä", "ClickToChangeQuality": "Vaihda laatua painamalla tästä", "CloneCustomFormat": "Monista mukautettu muoto", - "CloneIndexer": "Monista tietolähde", + "CloneIndexer": "Monista hakupalvelu", "CloneProfile": "Monista profiili", "Close": "Sulje", "CloseCurrentModal": "Sulje nykyinen ikkuna", @@ -496,7 +496,7 @@ "DoNotUpgradeAutomatically": "Älä päivitä automaattisesti", "DownloadClient": "Latauspalvelu", "DownloadClientCheckNoneAvailableMessage": "Latauspalveluita ei ole käytettävissä", - "DownloadClientCheckUnableToCommunicateMessage": "Viestintä latauspalvelun \"{downloadClientName}\" kanssa epäonnistui. {errorMessage}", + "DownloadClientCheckUnableToCommunicateMessage": "Virhe viestittäessä latauspalvelun \"{downloadClientName}\" kanssa. {errorMessage}.", "DownloadClients": "Latauspalvelut", "DownloadClientSettings": "Latauspalveluasetukset", "EditCustomFormat": "Muokkaa mukautettua muotoa", @@ -526,7 +526,7 @@ "EnableColorImpairedModeHelpText": "Vaihtoehtoinen tyyli, joka auttaa erottamaan värikoodatut tiedot paremmin.", "EnableCompletedDownloadHandlingHelpText": "Tuo valmistuneet lataukset latauspalvelusta automaattisesti.", "ListEnabledHelpText": "Käytä listaa valitsemalla tämä.", - "SearchIsNotSupportedWithThisIndexer": "Tämä tietolähde ei tue hakua.", + "SearchIsNotSupportedWithThisIndexer": "Tämä hakupalvelu ei tue hakutoimintoa.", "AnalyseVideoFilesHelpText": "Pura videotiedostoista resoluution, keston ja koodekkien kaltaisia tietoja. Tätä varten {appName}in on luettava osia tiedostoista, joka saattaa kasvattaa levyn tai verkon kuormitusta tarkistusten aikana.", "EnableRss": "RSS-syöte", "Ended": "Päättynyt", @@ -561,7 +561,7 @@ "Forecast": "Ennuste", "Formats": "Muodot", "SupportedListsMoreInfo": "Lue lisää tuontilistasta painamalla 'Lisätietoja'.", - "SupportedIndexersMoreInfo": "Saat tietoja yksittäisistä palveluista painamalla niiden ohessa olevia lisätietopainikkeita.", + "SupportedIndexersMoreInfo": "Saat lisätietoja yksittäisistä palveluista niiden ohessa olevilla painikkeilla.", "General": "Yleiset", "GeneralSettings": "Yleiset asetukset", "GeneralSettingsSummary": "Portti, SSL-salaus, käyttäjätunnus ja salasana, välityspalvelin, analytiikka ja päivitykset.", @@ -588,7 +588,7 @@ "ImportCustomFormat": "Tuo mukautettu muoto", "ImportedTo": "Tuontikohde", "ImportRootPath": "Osoita {appName}ille kansio, joka sisältää kaikki tuotavat elokuvat, ei vain yksittäistä elokuvaa (esim. \"{0}\" ei \"{1}\"). Lisäksi jokaisen elokuvan on oltava omissa kansioissaan juuri-/kirjastokansion alla.", - "ImportTipsMessage": "Joitakin vinkkejä, joiden avulla homma sujuu:", + "ImportTipsMessage": "Muutama vinkki, joiden avulla homma sujuu:", "InCinemasMovieDescription": "Elokuva on elokuvateattereissa", "IncludeRadarrRecommendations": "Sisällytä {appName}-suositukset", "IncludeRecommendationsHelpText": "Sisällytä {appName}in suosittelemat elokuvat etsintänäkymään", @@ -613,7 +613,7 @@ "LastUsed": "Viimeksi käytetty", "LastWriteTime": "Edellinen tallennus", "LaunchBrowserHelpText": " Avaa {appName}in verkkokäyttöliittymä verkkoselaimeen käynnistyksen yhteydessä.", - "Links": "Linkit", + "Links": "Linkkejä", "ImportLists": "Tuontilistat", "ImportListSettings": "Tuontilistojen yleisasetukset", "ImportListsSettingsSummary": "Sisällön tuonti muista {appName}-instansseista tai palveluista, ja poikkeuslistojen hallinta.", @@ -645,10 +645,10 @@ "MinutesNinety": "90 minuuttia: {ninety}", "Mode": "Tila", "Monitor": "Valvonta", - "Monitored": "Valvonta", + "Monitored": "Valvottu", "MonitoredOnly": "Vain valvotut", "MonitoredStatus": "Valvottu/tila", - "MonitorMovie": "Elokuvan valvonta", + "MonitorMovie": "Elokuvien valvonta", "Months": "Kuukaudet", "MoreInfo": "Lisätietoja", "Movie": "Elokuva", @@ -671,7 +671,7 @@ "OutputPath": "Tallennussijainti", "PhysicalReleaseDate": "Fyysinen julkaisu", "PreferAndUpgrade": "Suosi ja päivitä", - "PreferIndexerFlags": "Painotettavat tietolähdeliput", + "PreferIndexerFlags": "Painotettavat hakupalveluliput", "PreferIndexerFlagsHelpText": "Painota hakupalvelun erityislipuilla merkittyjä julkaisuja.", "Preferred": "Suosittu", "PreviewRename": "Nimeämisen esikatselu", @@ -687,7 +687,7 @@ "QualityDefinitions": "Laatumääritykset", "QualityLimitsMovieRuntimeHelpText": "Rajoitukset suhteutetaan automaattisesti elokuvan kestoon.", "QualitySettingsSummary": "Laatukoot ja nimeäminen", - "SupportedIndexers": "{appName} tukee kaikkien Newznab-yhteensopivien tietolähteiden ohella myös monia muita alla listattuja tietolähteitä.", + "SupportedIndexers": "{appName} tukee kaikkien Newznab-yhteensopivien hakupalveluiden ohella myös monia muita alla listattuja palveluita.", "SupportedCustomConditions": "{appName} tukee alla oleviin julkaisujen ominaisuuksiin perustuvia mukautettuja ehtoja.", "Ratings": "Arviot", "RecentChanges": "Uusimmat muutokset", @@ -743,9 +743,9 @@ "RootFolderCheckSingleMessage": "Juurikansio puuttuu: {rootFolderPath}.", "RootFolders": "Juurikansiot", "Rss": "RSS", - "RssIsNotSupportedWithThisIndexer": "Tämän tietolähteen kanssa ei voida käyttää RSS-syötettä.", + "RssIsNotSupportedWithThisIndexer": "Tämän hakupalvelun kanssa ei voida käyttää RSS-syötettä.", "RssSyncInterval": "RSS-synkronoinnin ajoitus", - "RssSyncIntervalHelpTextWarning": "Tämä koskee kaikkia tietolähteitä. Noudata niiden asettamia sääntöjä.", + "RssSyncIntervalHelpTextWarning": "Tämä koskee kaikkia hakupalveluita. Noudata niiden asettamia sääntöjä.", "Save": "Tallenna", "SaveChanges": "Tallenna muutokset", "SaveSettings": "Tallenna asetukset", @@ -842,7 +842,7 @@ "Test": "Testaa", "TestAll": "Kaikkien testaus", "TheLogLevelDefault": "Lokikirjauksen oletusarvoinen laajuus on \"Informatiivinen\". Laajuutta voidaan muuttaa [Yleisistä asetuksista](/settings/general).", - "ThisCannotBeCancelled": "Tämän peruminen on aloituksen jälkeen mahdollista vain poistamalla kaikki tietolähteet käytöstä.", + "ThisCannotBeCancelled": "Tämän peruminen on aloituksen jälkeen mahdollista vain poistamalla kaikki hakupalvelut käytöstä.", "Title": "Nimike", "Titles": "Nimikkeet", "TMDBId": "TMDB ID", @@ -862,31 +862,31 @@ "UiLanguage": "Käyttöliittymän kieli", "UiLanguageHelpText": "{appName}in käyttöliittymän kieli.", "UiSettings": "Käyttöliittymän asetukset", - "AddConditionError": "Ehdon lisäys epäonnistui. Yritä uudelleen.", - "AddDownloadClientError": "Latauspalvelun lisääminen epäonnistui. Yritä uudelleen.", - "AddIndexerError": "Uuden hakupalvelun lisääminen epäonnistui. Yritä uudelleen.", - "AddImportListExclusionError": "Poikkeussäännön lisäys epäonnistui. Yritä uudelleen.", - "AddListError": "Tuontilistan lisäys epäonnistui. Yritä uudelleen.", - "AddNotificationError": "Ilmoituspalvelun lisääminen epäonnistui. Yritä uudelleen.", - "AddQualityProfileError": "Laatuprofiilin lisäys epäonnistui. Yritä uudelleen.", - "AddRemotePathMappingError": "Etäsijainnin kartoituksen lisäys epäonnistui. Yritä uudelleen.", + "AddConditionError": "Virhe lisättäessä ehtoa. Yritä uudelleen.", + "AddDownloadClientError": "Virhe lisättäessä latauspalvelua. Yritä uudelleen.", + "AddIndexerError": "Virhe lisättäessä hakupalvelua. Yritä uudelleen.", + "AddImportListExclusionError": "Virhe lisättäessä listapoikkeusta. Yritä uudelleen.", + "AddListError": "Virhe lisättäessä tuontilistaa. Yritä uudelleen.", + "AddNotificationError": "Virhe lisättäessä ilmoituspalvelua. Yritä uudelleen.", + "AddQualityProfileError": "Virhe lisättäessä laatuprofiilia. Yritä uudelleen.", + "AddRemotePathMappingError": "Virhe lisättäessä etäsijainnin kohdistusta. Yritä uudelleen.", "BackupsLoadError": "Varmuuskopioinnin lataus epäonnistui", "CustomFormatsLoadError": "Mukautettujen muotojen lataus epäonnistui", "DelayProfilesLoadError": "Viiveprofiilien lataus epäonnistui", "Unlimited": "Rajoittamaton", "DownloadClientOptionsLoadError": "Latauspalveluasetusten lataus epäonnistui", - "GeneralSettingsLoadError": "Yleisasetusten lataus epäonnistui", + "GeneralSettingsLoadError": "Virhe ladattaessa yleisasetuksia.", "IndexerOptionsLoadError": "Tietolähdeasetusten lataus epäonnistui", "IndexersLoadError": "Tietolähteiden lataus epäonnistui", "ImportListExclusionsLoadError": "Tuontilistapoikkeusten lataus epäonnistui", - "ListOptionsLoadError": "Lista-asetusten lataus epäonnistui", + "ListOptionsLoadError": "Virhe ladattaessa lista-asetuksia.", "ImportListsLoadError": "Tuontilistojen lataus epäonnistui", - "UnableToLoadManualImportItems": "Manuaalituonnin kohteiden lataus epäonnistui", + "UnableToLoadManualImportItems": "Virhe ladattaessa manuaalisesti tuotavia kohteita.", "MediaManagementSettingsLoadError": "Mediatiedostojen hallinta-asetusten lataus epäonnistui", "MetadataLoadError": "Metatietojen lataus epäonnistui", "UnableToLoadMovies": "Elokuvien lataus epäonnistui", "NamingSettingsLoadError": "Nimeämisasetusten lataus epäonnistui", - "NotificationsLoadError": "Ilmoituspalveluiden lataus epäonnistui", + "NotificationsLoadError": "Virhe ladattaessa ilmoituspalveluita.", "QualityDefinitionsLoadError": "Laatumääritysten lataus epäonnistui", "QualityProfilesLoadError": "Laatuprofiilien lataus epäonnistui", "RemotePathMappingsLoadError": "Etäsijaintien kohdistusten lataus epäonnistui", @@ -898,7 +898,7 @@ "Ungroup": "Pura ryhmä", "UnmappedFilesOnly": "Vain kohdistamattomat tiedostot", "UnmappedFolders": "Kohdistamattomat kansiot", - "Unmonitored": "Valvomattomat", + "Unmonitored": "Valvomaton", "ICalIncludeUnmonitoredMoviesHelpText": "Sisällytä valvomattomat elokuvat iCal-syötteeseen.", "Unreleased": "Julkaisematon", "UnsavedChanges": "Muutoksia ei ole tallennettu", @@ -1001,7 +1001,7 @@ "ClickToChangeReleaseGroup": "Vaihda julkaisuryhmää painamalla tästä", "Filters": "Suodattimet", "TmdbRating": "TMDB-arvio", - "IndexerJackettAll": "Jackettin ei-tuettua \"all\"-päätettä käyttävät tietolähteet: {indexerNames}.", + "IndexerJackettAll": "Jackettin ei-tuettua \"all\"-päätettä käyttävät hakupalvelut: {indexerNames}.", "TmdbVotes": "TMDB-äänet", "ImdbRating": "IMDb-arvio", "ImdbVotes": "IMDb-äänet", @@ -1066,14 +1066,14 @@ "ResetDefinitionTitlesHelpText": "Palauta määritysten nimet ja arvot.", "ResetQualityDefinitionsMessageText": "Haluatko varmasti palauttaa laatumääritykset?", "DeleteImportListExclusionMessageText": "Haluatko varmasti poistaa tuontilistapoikkeuksen?", - "CountIndexersSelected": "{count} tietolähde(ttä) on valittu", + "CountIndexersSelected": "{count} hakupalvelu(a) on valittu", "DeleteConditionMessageText": "Haluatko varmasti poistaa ehdon \"{name}\"?", "DeleteCustomFormatMessageText": "Haluatko varmasti poistaa mukautetun muodon \"{name}\"?", "DeleteDelayProfileMessageText": "Haluatko varmasti poistaa viiveprofiilin?", "DeleteSelectedImportLists": "Poista tuontilista(t)", "DeleteSelectedIndexers": "Poista hakupalvelu(t)", "ApplyTagsHelpTextAdd": "– \"Lisää\" syötetyt tunnisteet aiempiin tunnisteisiin", - "ApplyTagsHelpTextHowToApplyIndexers": "Tunnisteiden käyttö valituille tietolähteille", + "ApplyTagsHelpTextHowToApplyIndexers": "Tunnisteiden käyttö valituille hakupalveluille", "ApplyTagsHelpTextRemove": "- \"Poista\" tyhjentää syötetyt tunnisteet", "ApplyTagsHelpTextReplace": "- \"Korvaa\" nykyiset tunnisteet syötetyillä tai tyhjennä kaikki tunnisteet jättämällä tyhjäksi", "DeleteSelectedDownloadClients": "Poista valitut latauspalvelu(t)", @@ -1099,7 +1099,7 @@ "AddConnection": "Lisää ilmoituspavelu", "AddDownloadClientImplementation": "Lisätään latauspalvelua – {implementationName}", "AddImportList": "Lisää tuontilista", - "AddIndexerImplementation": "Lisätään tietolähdettä – {implementationName}", + "AddIndexerImplementation": "Lisätään hakupalvelua – {implementationName}", "RemoveCompletedDownloads": "Poista valmistuneet lataukset", "RootFolderPath": "Juurikansion sijainti", "AutoTaggingRequiredHelpText": "Tämän \"{implementationName}\" -ehdon on täsmättävä automaattimerkinnän säännön käyttämiseksi. Muutoin yksittäinen \"{implementationName}\" -vastaavuus riittää.", @@ -1112,7 +1112,7 @@ "DeleteImportListMessageText": "Haluatko varmasti poistaa listan \"{name}\"?", "DeleteQualityProfileMessageText": "Haluatko varmasti poistaa laatuprofiilin \"{name}\"?", "DeleteSelectedDownloadClientsMessageText": "Haluatko varmasti poistaa {count} valittua latauspalvelua?", - "DeleteSelectedIndexersMessageText": "Haluatko varmasti poistaa {count} valit(un/tua) tietoläh(teen/dettä)?", + "DeleteSelectedIndexersMessageText": "Haluatko varmasti poistaa {count} valit(un/tua) hakupalvelu(n/a)?", "DownloadIgnored": "Lataus ohitettiin", "FailedToFetchUpdates": "Päivitysten nouto epäonnistui", "FailedToUpdateSettings": "Asetusten päivitys epäonnistui", @@ -1125,8 +1125,8 @@ "FullColorEvents": "Täysin väritetyt tapahtumat", "InfoUrl": "Tietojen URL", "LogFilesLocation": "Lokitiedostojen tallennussijainti: {location}", - "ManageDownloadClients": "Hallitse latauspalveluita", - "ManageIndexers": "Hallitse tietolähteitä", + "ManageDownloadClients": "Palveluiden hallinta", + "ManageIndexers": "Palveluiden hallinta", "MovieImportedTooltip": "Elokuva ladattiin ja poimittiin latauspalvelulta.", "NoIndexersFound": "Tietolähteitä ei löytynyt", "NotificationStatusSingleClientHealthCheckMessage": "Ilmoituspalvelut eivät ole ongelmien vuoksi käytettävissä: {notificationNames}.", @@ -1151,7 +1151,7 @@ "AddImportListImplementation": "Lisätään tuontilistaa – {implementationName}", "AllTitles": "Kaikki nimikkeet", "EditDownloadClientImplementation": "Muokataan latauspalvelua – {implementationName}", - "IndexerDownloadClientHealthCheckMessage": "Tietolähteet virheellisillä latauspalveluilla: {indexerNames}.", + "IndexerDownloadClientHealthCheckMessage": "Hakupalvelut virheellisillä latauspalveluilla: {indexerNames}.", "RemoveQueueItem": "Poistetaan – {sourceTitle}", "TablePageSizeMaximum": "Sivukohtainen kohdemäärä ei voi olla suurempi kuin {maximumValue}.", "TablePageSizeMinimum": "Sivukohtaisen kohdemäärän on oltava vähintään {minimumValue}.", @@ -1165,7 +1165,7 @@ "DeleteRootFolderMessageText": "Haluatko varmasti poistaa juurikansion \"{path}\"?", "DisabledForLocalAddresses": "Ei käytössä paikallisissa osoitteissa", "NoDownloadClientsFound": "Latauspalveluita ei löytynyt", - "ManageFiles": "Hallitse tiedostoja", + "ManageFiles": "Tiedostojen hallinta", "OrganizeLoadError": "Virhe ladattaessa esikatseluita", "OrganizeModalHeader": "Järjestele ja uudelleennimeä", "RemoveQueueItemConfirmation": "Haluatko varmasti poistaa kohteen \"{sourceTitle}\" jonosta?", @@ -1198,7 +1198,7 @@ "EditIndexerImplementation": "Muokataan tietolähdettä – {implementationName}", "PendingDownloadClientUnavailable": "Odottaa – Latauspalvelu ei ole käytettävissä", "ApplyChanges": "Toteuta muutokset", - "AddRootFolderError": "Virhe lisättäessä juurikansiota", + "AddRootFolderError": "Virhe lisättäessä juurikansiota.", "FormatAgeDay": "päivä", "InteractiveImportNoQuality": "Jokaisen valitun tiedoston laatu on määritettävä.", "FormatShortTimeSpanMinutes": "{minutes} minuutti(a)", @@ -1206,7 +1206,7 @@ "DownloadClientQbittorrentSettingsContentLayout": "Sisällön rakenne", "InteractiveImportNoImportMode": "Tuontitila on valittava.", "InteractiveImportLoadError": "Manuaalituonnin kohteiden lataus epäonnistui", - "ReleaseProfilesLoadError": "Julkaisuprofiilien lataus epäonnistui", + "ReleaseProfilesLoadError": "Virhe ladattaessa julkaisuprofiileja.", "SelectDownloadClientModalTitle": "{modalTitle} – Valitse latauspalvelu", "VideoDynamicRange": "Videon dynaaminen alue", "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Vahvista uusi salasana", @@ -1266,8 +1266,8 @@ "OnHealthRestored": "Terveystilan vakautuessa", "EnableProfile": "Käytä profiilia", "DownloadClientQbittorrentSettingsContentLayoutHelpText": "Määrittää käytetäänkö qBittorrentista määritettyä rakennetta, torrentin alkuperäistä rakennetta vai luodaanko uusi alikansio (qBittorrent 4.3.2+).", - "ManageLists": "Listojen hallunta", - "ManageImportLists": "Tuontilistojen hallinta", + "ManageLists": "Listojen hallinta", + "ManageImportLists": "Listojen hallinta", "SelectDropdown": "Valitse...", "Unknown": "Tuntematon", "HealthMessagesInfoBox": "Saat lisätietoja näiden vakausviestien syistä painamalla rivin lopussa olevaa wikilinkkiä (kirjakuvake) tai tarkastelemalla [lokitietoja]({link}). Mikäli et osaa tulkita näitä viestejä, tavoitat tukemme alla olevilla linkeillä.", @@ -1296,7 +1296,7 @@ "NotificationsAppriseSettingsConfigurationKey": "Apprise-määritysavain", "NotificationsAppriseSettingsNotificationType": "Apprisen ilmoitustyyppi", "NotificationsPushBulletSettingSenderIdHelpText": "Lähettävän laitteen ID-tunniste. Käytä laitteen pushbullet.com-URL-osoitteen \"device_iden\"-arvoa. Lähetä itseltäsi jättämällä tyhjäksi.", - "AutoTaggingLoadError": "Automaattimerkinnän lataus epäonnistui", + "AutoTaggingLoadError": "Virhe ladattaessa automaattimerkintää.", "NotificationsJoinSettingsDeviceIdsHelpText": "Vanhentunut, käytä tämän sijaan laitteiden nimiä. Pilkuin eroteltu listaus laitteiden ID-tunnisteista, joihin ilmoitukset lähetetään. Jos ei määritetty, lähetetään kaikkiin laitteisiin.", "NotificationsTelegramSettingsTopicIdHelpText": "Lähetä ilmoitus tiettyyn ketjuun määrittämällä ketjun ID-tunniste. Käytä yleistä aihetta jättämällä tyhjäksi (vain superryhmille).", "NotificationsNtfySettingsTopics": "Topikit", @@ -1363,7 +1363,7 @@ "IMDbId": "IMDb ID", "ImportScriptPath": "Tuontikomentosarjan sijainti", "ListRefreshInterval": "Listan päivityksen ajoitus", - "ManageClients": "Hallitse työkaluja", + "ManageClients": "Palveluiden hallinta", "MovieMatchType": "Elokuvan kohdistustyyppi", "NotificationsEmailSettingsFromAddress": "Lähetysosoite", "NotificationsDiscordSettingsAvatarHelpText": "Muuta ilmoituksissa käytettävää käyttäjäkuvaketta.", @@ -1561,7 +1561,7 @@ "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} ei voinut lisätä Label-tunnistetta palveluun {clientName}.", "DownloadClientQbittorrentTorrentStateStalled": "Lataus on jäätynyt, koska yhdistettyjä lähteitä ei ole.", "MovieIsPopular": "Elokuva on suosittu TMDB:ssä", - "MovieIsTrending": "Elokuva on nousussa TMDB:ssä", + "MovieIsTrending": "Elokuva trendaa TMDB:ssä", "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "Magnet-linkeille käytettävä tiedostopääte. Oletus on \".magnet\".", "DownloadClientDelugeValidationLabelPluginFailure": "Label-tunnisteen määritys epäonnistui.", "DownloadClientDownloadStationProviderMessage": "{appName} ei voi muodostaa yhteyttä Download Stationiin, jos DSM-tili on määritetty käyttämään kaksivaiheista tunnistautumista.", @@ -1641,7 +1641,7 @@ "MediaInfoFootNote": "MediaInfo Full, AudioLanguages ja SubtitleLanguages tukevat \":EN+FI\"-tyylisiä jälkiliitteitä, joiden avulla tiedostonimeen voidaan lisätä videon sisältämiä kieliä. \"-\" ohittaa tietyt kielet (esim. \"-EN\") ja \"+\"-pääte (esim. \":FI+\") tuottaa ohitettavista kielistä riippuen \"[FI]\", \"[FI+--]\" tai \"[--]\". Esimerkiksi \"{MediaInfo Full:FI+EN}\".", "DownloadClientDownloadStationValidationFolderMissing": "Kansiota ei ole olemassa", "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "Sinun on kirjauduttava Diskstationillesi tunnuksella {username} ja määritettävä se manuaalisesti Download Stationin asetusten kohtaan \"BT/HTTP/FTP/NZB\" > \"Location\".", - "DownloadClientFloodSettingsRemovalInfo": "{appName} suorittaa torrenttien automaattisen poiston sen tietolähdeastuksissa määritettyjen jakoasetusten perusteella.", + "DownloadClientFloodSettingsRemovalInfo": "{appName} suorittaa torrenttien automaattisen poiston sen hakupalveluastuksissa määritettyjen jakoasetusten perusteella.", "DownloadClientFloodSettingsTagsHelpText": "Latauksen alkuperäiset tunnisteet, jotka tarvitaan sen tunnistamiseen. Tämä välttää ristiriidat muiden latausten kanssa.", "OrganizeRelativePaths": "Kaikki tiedostosijainnit on suhteutettu sijaintiin: \"{path}\".", "PopularityIndex": "Tämänhetkinen suosioarvo", @@ -1696,17 +1696,17 @@ "Repack": "Uudelleenpaketoitu", "Release": "Julkaisu", "RegularExpressionsTutorialLink": "Lisätietoja säännöllisistä lausekkeista löytyy [täältä]({url}).", - "ReleaseProfileIndexerHelpText": "Määritä mitä tietolähdettä profiili koskee.", + "ReleaseProfileIndexerHelpText": "Määritä mitä hakupalvelua profiili koskee.", "ReleaseProfileTagMovieHelpText": "Julkaisuprofiileja sovelletaan elokuviin, jotka on merkitty ainakin yhdellä täsmäävällä tunnisteella. Käytä kaikille elokuville jättämällä tyhjäksi.", "SearchMoviesOnAdd": "Etsi elokuvia kun ne lisätään", - "ClickToChangeIndexerFlags": "Muuta tietolähteen lippuja painamalla tästä", + "ClickToChangeIndexerFlags": "Muuta hakupalvelun lippuja painamalla tästä", "CustomFormatsSpecificationFlag": "Lippu", - "SelectIndexerFlags": "Valitse tietolähteen liput", - "SetIndexerFlagsModalTitle": "{modalTitle} – Aseta tietolähteen liput", + "SelectIndexerFlags": "Valitse hakupalvelun liput", + "SetIndexerFlagsModalTitle": "{modalTitle} – Aseta hakupalvelun liput", "CustomFilter": "Mukautettu suodatin", "Label": "Nimi", "LabelIsRequired": "Nimi on pakollinen", - "SetIndexerFlags": "Aseta tietolähteen liput", + "SetIndexerFlags": "Aseta hakupalvelun liput", "Lists": "Listat", "External": "Ulkoinen", "MissingLoadError": "Virhe ladattaessa puuttuvia kohteita.", @@ -1716,7 +1716,7 @@ "CutoffUnmetNoItems": "Katkaisutasoa saavuttamattomia kohteita ei ole", "DownloadClientDelugeSettingsDirectoryHelpText": "Vaihtoehtoinen latausten tallennussijainti. Käytä Delugen oletusta jättämällä tyhjäksi.", "DownloadClientVuzeValidationErrorVersion": "Protokollaversiota ei tueta. Käytä vähintään Vuzen versiota 5.0.0.0 Vuze Web Remote -lisäosan kanssa.", - "MassSearchCancelWarning": "Tämä on mahdollista keskeyttää vain käynnistämällä {appName} uudelleen tai poistamalla kaikki tietolähteet käytöstä.", + "MassSearchCancelWarning": "Tämä on mahdollista keskeyttää vain käynnistämällä {appName} uudelleen tai poistamalla kaikki hakupalvelut käytöstä.", "MissingNoItems": "Puuttuvia kohteita ei ole", "MonitorSelected": "Valvo valittuja", "UnmonitorSelected": "Lopeta valittujen valvonta", @@ -1782,7 +1782,7 @@ "MetadataSettingsMovieImages": "Elokuvien kuvitukset", "MetadataSettingsMovieMetadataLanguage": "Elokuvien metatietojen kieli", "BlocklistFilterHasNoItems": "Valitulla estolistasuodattimella ei löydy kohteita", - "IncludeTrendingMoviesHelpText": "Sisällytä TMDB:n nousussa olevat elokuvat", + "IncludeTrendingMoviesHelpText": "Sisällytä TMDB:n trendaavat elokuvat.", "CustomFormatsSettingsTriggerInfo": "Mukautettua muotoa sovelletaan julkaisuun tai tiedostoon, kun ainakin yksi valituista ehtotyypeistä täsmää.", "CustomFormatsSpecificationExceptLanguageHelpText": "Täsmää, jos havaitaan mikä tahansa muu kuin valittu kieli.", "DownloadClientRTorrentSettingsAddStoppedHelpText": "Tämä lisää torrentit ja magnet-linkit rTorentiin pysäytetyssä tilassa. Tämä saattaa rikkoa margnet-tiedostot.", @@ -1797,7 +1797,7 @@ "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Lisää lähetettäviin ilmoituksiin linkit elokuvien metatietoihin.", "NotificationsTelegramSettingsIncludeInstanceName": "Sisällytä instanssin nimi otsikkoon", "SkipFreeSpaceCheckHelpText": "Käytä, kun {appName} ei kykene tunnistamaan juurikansiosi käytettävissä olevaa vapaata tallennustilaa.", - "UnableToImportAutomatically": "Automaattinen tuonti ei onnistu", + "UnableToImportAutomatically": "Virhe automaattituonnissa.", "DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent ilmoittaa puuttuvista tiedostoista", "ExistsInLibrary": "On jo kirjastossa", "TodayAt": "Tänään klo {time}", @@ -1812,7 +1812,7 @@ "LogSizeLimit": "Lokin kokorajoitus", "LogSizeLimitHelpText": "Lokitiedoston enimmäiskoko ennen pakkausta. Oletusarvo on 1 Mt.", "IncludePopular": "Sisällytä suositut", - "IncludePopularMoviesHelpText": "Sisällytä TMDB:n suositut elokuvat", + "IncludePopularMoviesHelpText": "Sisällytä TMDB:n suositut elokuvat.", "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName} toivoo jokaisen latauksen olevan omassa kansiossaan. Jos kansioon/polkuun lisätään tähtimerkki (*) SABnzbd ei luo näitä työkansioita. Korjaa tämä SABnzb:stä.", "DownloadClientValidationSslConnectFailure": "Salattua SSL-yhteyttä ei voida muodostaa", "TraktVotes": "Trakt-äänet", @@ -1822,13 +1822,13 @@ "Popular": "Suosittu", "DownloadClientSabnzbdValidationDevelopVersionDetail": "Kehitysversioita käytettäessä {appName} ei välttämättä tue SABnzbd:n uusia ominaisuuksia.", "DownloadClientDelugeSettingsDirectory": "Latauskansio", - "ManageCustomFormats": "Hallitse mukautettuja muotoja", + "ManageCustomFormats": "Muotojen hallinta", "MovieDownloaded": "Elokuva on ladattu", "NewNonExcluded": "Uusi ei-ohitettava", "NoCustomFormatsFound": "Mukautettuja muotoja ei löytynyt", "DownloadClientSabnzbdValidationCheckBeforeDownload": "Poista SABnbzd:n \"Tarkista ennen lataamista\" -asetus käytöstä", "DownloadClientValidationSslConnectFailureDetail": "{appName} ei voi muodostaa salattua SSL-yhteyttä latauspalveluun {clientName}. Tämä voi olla laitekohtainen ongelma. Kokeile muodostaa yhteys määrittämällä {appName} ja latauspalvelu {clientName} käyttämään suojaamatonta yhteyttä.", - "IncludeTrending": "Sisällytä nuosevat", + "IncludeTrending": "Sisällytä trendaavat", "MetadataKometaDeprecated": "Kometa-tiedostoja ei enää luoda ja tuki poistuu täysin versiossa 6.", "MetadataKometaDeprecatedSetting": "Poistunut", "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Sisällytä elokuvan TMDB- ja IMDb-osoitteet .nfo-tiedostoon.", @@ -1852,7 +1852,7 @@ "ShowTags": "Näytä tunnisteet", "TomorrowAt": "Huomenna klo {time}", "TraktRating": "Trakt-arvio", - "Trending": "Nousussa", + "Trending": "Trendaava", "Warning": "Varoitus", "LastSearched": "Edellinen haku", "OnExcludedList": "Ohitettavien listalla", @@ -1869,7 +1869,7 @@ "ShowTraktRating": "Näytä Trakt-arviot", "NotificationsGotifySettingsMetadataLinks": "Metatietolinkit", "NotificationsGotifySettingsPreferredMetadataLink": "Ensisijainen metatietolinkki", - "ManageFormats": "Hallitse muotoja", + "ManageFormats": "Muotojen hallinta", "Disposition": "Poikkeama", "AutoTaggingSpecificationQualityProfile": "Laatuprofiili", "AutoTaggingSpecificationRootFolder": "Juurikansio", @@ -1889,5 +1889,8 @@ "AutoTaggingSpecificationOriginalLanguage": "Kieli", "AutoTaggingSpecificationMaximumRuntime": "Enimmäiskesto", "AutoTaggingSpecificationMinimumRuntime": "Vähimmäiskesto", - "CustomFormatsSpecificationQualityModifier": "Laatumuuttuja" + "CustomFormatsSpecificationQualityModifier": "Laatumuuttuja", + "ReleaseSource": "Julkaisulähde", + "UserInvokedSearch": "Käyttäjä herätti haun", + "ReleasePush": "Julkaisun työntö" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 90e675ad79..08234a2be0 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1,7 +1,7 @@ { "EditMovieFile": "영화 파일 편집", "ImportExtraFilesMovieHelpText": "동영상 파일을 가져온 후 일치하는 추가 파일 (자막, nfo 등) 가져오기", - "ImportFailed": "가져오기 실패 : {0}", + "ImportFailed": "가져오기 실패: {0}", "ImportLibrary": "라이브러리 가져오기", "AddExclusion": "예외 추가", "About": "정보", @@ -11,10 +11,10 @@ "ApiKey": "API 키", "Analytics": "분석", "BackupNow": "지금 백업", - "BackupRetentionHelpText": "보존 기간보다 오래된 자동 백업은 자동으로 정리됩니다.", + "BackupRetentionHelpText": "보존 기간보다 오래된 자동 백업은 자동으로 정리됩니다", "Backups": "백업", "Cast": "캐스트", - "MinimumCustomFormatScoreHelpText": "다운 불러올 수있는 최소 사용자 지정 형식 점수", + "MinimumCustomFormatScoreHelpText": "다운 로드할 수있는 최소 사용자 정의 형식 점수", "MovieIsRecommend": "최근 추가 한 동영상을 기준으로 추천 영화", "None": "없음", "QualitySettings": "품질 설정", @@ -22,71 +22,71 @@ "MovieFolderFormat": "영화 폴더 형식", "IncludeCustomFormatWhenRenamingHelpText": "{Custom Formats} 이름 변경 형식에 포함", "ProtocolHelpText": "사용할 프로토콜을 선택하고 동일한 출시 중에서 선택할 때 선호하는 프로토콜을 선택합니다.", - "RecyclingBinCleanupHelpTextWarning": "선택한 일 수보다 오래된 휴지통에있는 파일은 자동으로 정리됩니다.", - "NoChanges": "변경 사항 없음", - "ConnectionLost": "연결이 끊어졌습니다.", + "RecyclingBinCleanupHelpTextWarning": "선택한 일 수보다 오래된 휴지통에 있는 파일은 자동으로 정리됩니다", + "NoChanges": "변경 사항 저장", + "ConnectionLost": "연결이 끊어짐", "ConsideredAvailable": "사용 가능한 것으로 간주", - "CopyUsingHardlinksMovieHelpText": "아직 시드중인 토렌트에서 파일을 복사하려고 할 때 하드 링크 사용", - "CreateEmptyMovieFolders": "빈 동영상 폴더 만들기", + "CopyUsingHardlinksMovieHelpText": "하드링크를 사용하면 {appName}이(가) 추가 디스크 공간을 차지하거나 파일의 전체 내용을 복사하지 않고도 시드 제공 중인 토런트를 영화 폴더로 가져올 수 있습니다. 하드링크는 원본와 대상이 같은 볼륨에 있는 경우에만 작동합니다", + "CreateEmptyMovieFolders": "빈 영화 폴더 만들기", "CustomFormatsSettings": "사용자 정의 형식 설정", - "UpgradeUntilCustomFormatScoreMovieHelpText": "이 사용자 지정 형식 점수에 도달하면 {appName}는 더 이상 영화를 다운로드 하지 않습니다.", + "UpgradeUntilCustomFormatScoreMovieHelpText": "이 사용자 정의 형식 점수에 도달하면 {appName}은(는) 더 이상 영화를 다운로드 하지 않습니다.", "DefaultDelayProfileMovie": "이것이 기본 프로필입니다. 명시적인 프로필이 없는 모든 영화에 적용됩니다.", "Deleted": "삭제됨", "DeleteEmptyFoldersHelpText": "디스크 스캔 중 및 동영상 파일 삭제 시 빈 동영상 폴더 삭제", - "DeleteMovieFiles": "{0} 영화 파일 삭제", + "DeleteMovieFiles": "{movieFileCount}개의 영화 파일 삭제", "DeleteNotification": "알림 삭제", - "DestinationPath": "목적지 경로", - "DownloadWarning": "다운로드 경고 : {0}", + "DestinationPath": "대상 경로", + "DownloadWarning": "다운로드 경고: {0}", "EnableAutomaticAdd": "자동 추가 활성화", "EnableCompletedDownloadHandlingHelpText": "다운로드 클라이언트에서 완료된 다운로드를 자동으로 가져오기", "EnableInteractiveSearch": "대화형 검색 활성화", - "EnableSslHelpText": " 적용하려면 관리자로 실행을 다시 시작해야합니다.", + "EnableSslHelpText": " 적용하려면 관리자로 실행을 재시작해야합니다.", "ErrorLoadingContents": "콘텐츠로드 오류", "ErrorRestoringBackup": "백업 복원 오류", - "ExternalUpdater": "{appName}는 외부 업데이트 메커니즘을 사용하도록 구성됩니다.", + "ExternalUpdater": "{appName}은(는) 외부 업데이트 메커니즘을 사용하도록 설정되었습니다", "FileManagement": "파일 관리", "Filter": "필터", "Folder": "폴더", - "FreeSpace": "여유 공간", + "FreeSpace": "여분 공간", "Genres": "장르", - "GrabReleaseMessageText": "{appName}는 이 출시의 영화를 확인할 수 없습니다. {appName}는 이 출시를 자동으로 가져오지 못할 수 있습니다. '{0}'을(를) 잡으시겠습니까?", - "Ignored": "무시 됨", + "GrabReleaseMessageText": "{appName}은(는) 이 출시의 영화를 확인할 수 없음 {appName}은(는) 이 출시를 자동으로 가져오지 못할 수 있습니다. '{0}'을(를) 잡으시겠습니까?", + "Ignored": "무시", "IgnoreDeletedMovies": "삭제된 영화 모니터링 해제", "IgnoredHelpText": "하나 이상의 용어가 포함된 경우 출시가 거부됩니다 (대소문자 구분 안함).", - "ImportRootPath": "특정 영화가 아닌 모든 영화가 포함된 폴더를 {appName}로 지정합니다. 예 : {1}이 아닌 {0}입니다. 또한 각 동영상은 루트 / 라이브러리 폴더 내의 자체 폴더에 있어야합니다.", + "ImportRootPath": "특정 영화가 아닌 모든 영화가 포함된 폴더를 {appName}로 지정합니다. 예: {1}이 아닌 {0}입니다. 또한 각 동영상은 루트 / 라이브러리 폴더 내의 자체 폴더에 있어야합니다.", "InCinemasDate": "영화관 날짜", "IncludeUnmonitored": "모니터링되지 않는 항목 포함", - "IndexerSearchCheckNoAutomaticMessage": "자동 검색이 활성화 된 상태에서 사용할 수있는 인덱서가 없습니다. {appName}는 자동 검색 결과를 제공하지 않습니다.", - "IndexerSearchCheckNoInteractiveMessage": "대화형 검색이 활성화 된 상태에서 사용할 수있는 인덱서가 없습니다. {appName}는 대화형 검색 결과를 제공하지 않습니다.", + "IndexerSearchCheckNoAutomaticMessage": "자동 검색이 활성화 된 상태에서 사용할 수있는 인덱서가 없음, {appName}은(는) 자동 검색 결과를 제공하지 않습니다", + "IndexerSearchCheckNoInteractiveMessage": "상호작용 검색이 활성화 된 상태에서 사용할 수있는 인덱서가 없음, {appName}은(는) 대화형 검색 결과를 제공하지 않습니다", "InteractiveSearch": "대화형 검색", - "Interval": "간격", - "MinimumAgeHelpText": "유즈넷 전용 : NZB를 잡기 전 최소 연령 (분). 이를 사용하여 새 출시가 유즈넷 공급자에게 전파 할 시간을 제공하십시오.", - "MinutesHundredTwenty": "120 분 : {0}", + "Interval": "인터벌", + "MinimumAgeHelpText": "유즈넷 전용: NZB를 잡기 전 최소 연령 (분). 이를 사용하여 새 출시가 유즈넷 공급자에게 전파 할 시간을 제공하세요.", + "MinutesHundredTwenty": "120 분: {0}", "Months": "개월", - "NoListRecommendations": "목록 항목이나 권장 사항이 없습니다. 시작하려면 새 영화를 추가하거나 기존 영화를 가져 오거나 목록을 추가해야 합니다.", - "PreviewRenameHelpText": "팁 : 이름 변경을 미리 보려면 ... '취소'를 선택한 다음 영화 제목을 클릭하고", + "NoListRecommendations": "목록 항목이나 권장 사항이 없음 시작하려면 새 영화를 추가하거나 기존 영화를 가져 오거나 목록을 추가해야 합니다.", + "PreviewRenameHelpText": "팁: 이름 변경을 미리 보려면 ... '취소'를 선택한 다음 영화 제목을 클릭하고", "RemoveMovieAndDeleteFiles": "영화 제거 및 파일 삭제", - "RescanAfterRefreshHelpTextWarning": "{appName}는 '항상'으로 설정되지 않은 경우 파일 변경 사항을 자동으로 감지하지 않습니다.", + "RescanAfterRefreshHelpTextWarning": "{appName}은(는) '항상'으로 설정되지 않은 경우 파일 변경 사항을 자동으로 감지하지 않습니다.", "Restrictions": "제한", "Result": "결과", - "SearchCutoffUnmet": "컷오프 미충족 검색", - "FirstDayOfWeek": "주의 첫날", - "WeekColumnHeaderHelpText": "주가 활성보기 일 때 각 열 위에 표시됩니다.", - "SkipFreeSpaceCheck": "여유 공간 확인 건너 뛰기", - "SomeResultsHiddenFilter": "적용된 필터에 의해 일부 결과가 숨겨집니다.", - "TableOptions": "테이블 옵션", - "AddNotificationError": "새 알림을 추가 할 수 없습니다. 다시 시도하십시오.", - "BackupsLoadError": "백업을 불러올 수 없습니다.", - "IndexersLoadError": "인덱서를 불러올 수 없습니다.", - "QualityDefinitionsLoadError": "품질 정의를 불러올 수 없습니다.", - "TagsLoadError": "태그를 불러올 수 없습니다.", - "ICalIncludeUnmonitoredMoviesHelpText": "iCal 피드에 모니터링되지 않는 동영상 포함", - "UpdateCheckUINotWritableMessage": "사용자 '{1}'이 (가) UI 폴더 '{0}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.", - "UpdateScriptPathHelpText": "추출 된 업데이트 패키지를 사용하고 나머지 업데이트 프로세스를 처리하는 사용자 지정 스크립트에 대한 경로", + "SearchCutoffUnmet": "조건 미충족 검색", + "FirstDayOfWeek": "주의 첫 번째 날", + "WeekColumnHeaderHelpText": "주가 활성 화면일 때 각 열 위에 표시됨", + "SkipFreeSpaceCheck": "여유 공간 확인 건너뛰기", + "SomeResultsHiddenFilter": "적용된 필터에 의해 일부 결과가 숨겨집니다", + "TableOptions": "표 설정", + "AddNotificationError": "새 알림을 추가 할 수 없음 재시도해주세요.", + "BackupsLoadError": "백업을 로드할 수 없습니다", + "IndexersLoadError": "인덱서를 로드할 수 없음", + "QualityDefinitionsLoadError": "품질 정의를 로드할 수 없ㅇ", + "TagsLoadError": "태그를 로드할 수 없음", + "ICalIncludeUnmonitoredMoviesHelpText": "iCal 피드에 모니터링 해제된 영화 포함", + "UpdateCheckUINotWritableMessage": "사용자 '{userName}'이(가) UI 폴더 '{uiFolder}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없음", + "UpdateScriptPathHelpText": "추출한 업데이트 패키지를 사용하고 나머지 업데이트 프로세스를 처리하는 사용자 정의 스크립트에 대한 경로", "UpgradeUntil": "품질까지 업그레이드", - "Usenet": "유즈넷", - "VisitTheWikiForMoreDetails": "자세한 내용은 위키를 방문하세요: ", - "YouCanAlsoSearch": "영화의 TMDb ID 또는 IMDb ID를 사용하여 검색 할 수도 있습니다. 예 : `tmdb : 71663`", + "Usenet": "유즈넷 지연: {usenetDelay}", + "VisitTheWikiForMoreDetails": "상세 내용은 위키를 방문하세요: ", + "YouCanAlsoSearch": "영화의 TMDb ID 또는 IMDb ID를 사용하여 검색할 수도 있습니다. 예: `tmdb: 71663`", "OverviewOptions": "개요 옵션", "PackageVersion": "패키지 버전", "PendingChangesMessage": "저장하지 않은 변경 사항이 있습니다.이 페이지에서 나가시겠습니까?", @@ -96,9 +96,9 @@ "CertificationCountry": "인증 국가", "Dates": "날짜", "Day": "일", - "DatabaseMigration": "DB 마이그레이션", - "AcceptConfirmationModal": "확인 모달 수락", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Propers / Repacks보다 사용자 지정 형식 점수별로 정렬하려면 '선호 안함'을 사용하십시오.", + "DatabaseMigration": "데이터베이스 마이그레이션", + "AcceptConfirmationModal": "수락 확인 모달", + "DownloadPropersAndRepacksHelpTextCustomFormat": "Propers/Repack보다사용자 정의 형식 점수별로 정렬하려면 '선호 안함'을 사용", "Announced": "발표됨", "BindAddressHelpText": "모든 인터페이스에 유효한 IP4 주소 또는 '*'", "ClientPriority": "클라이언트 우선 순위", @@ -107,28 +107,28 @@ "CloseCurrentModal": "현재 모달 닫기", "AddNewMovie": "새 영화 추가", "Add": "추가", - "AddCustomFormat": "사용자 지정 형식 추가", + "AddCustomFormat": "사용자 정의 형식 추가", "AddDelayProfile": "지연 프로필 추가", "AddDownloadClient": "다운로드 클라이언트 추가", "AddedToDownloadQueue": "다운로드 대기열에 추가됨", "LastDuration": "lastDuration", - "Manual": "설명서", + "Manual": "수동", "AddQualityProfile": "품질 프로필 추가", - "MoreDetails": "자세한 내용은", - "MovieInfoLanguageHelpTextWarning": "브라우저 새로 고침 필요", - "Proxy": "대리", + "MoreDetails": "보다 상세히", + "MovieInfoLanguageHelpTextWarning": "브라우저 새로고침 필요", + "Proxy": "프록시", "AllFiles": "모든 파일", - "AllMoviesInPathHaveBeenImported": "{0}의 모든 영화를 가져왔습니다.", + "AllMoviesInPathHaveBeenImported": "{path}의 모든 영화를 가져왔습니다", "AlternativeTitle": "대체 제목", "Always": "항상", "AnalyseVideoFiles": "비디오 파일 분석", - "ICalShowAsAllDayEventsHelpText": "일정은 달력에서 종일 일정으로 표시됩니다.", + "ICalShowAsAllDayEventsHelpText": "일정은 캘린더에서 종일 일정으로 표시됩니다", "AuthBasic": "기본 (브라우저 팝업)", "Authentication": "인증", "ApplyTags": "태그 적용", "AppDataDirectory": "AppData 디렉토리", "Apply": "적용", - "ChangeHasNotBeenSavedYet": "변경 사항이 아직 저장되지 않았습니다.", + "ChangeHasNotBeenSavedYet": "변경 사항이 아직 저장되지 않았습니다", "Clear": "지우기", "AuthenticationMethodHelpText": "{appName}에 접근하려면 사용자 이름과 암호가 필요합니다", "AuthForm": "양식 (로그인 페이지)", @@ -138,91 +138,91 @@ "AvailabilityDelay": "가용성 지연", "BackupIntervalHelpText": "자동 백업 간격", "BeforeUpdate": "업데이트 전", - "DeleteCustomFormat": "사용자 지정 형식 삭제", + "DeleteCustomFormat": "사용자 정의 형식 삭제", "BindAddress": "바인드 주소", "ExcludeMovie": "영화 제외", - "Branch": "분기", + "Branch": "브랜치", "CantFindMovie": "내 영화를 찾을 수 없는 이유는 무엇입니까?", "ChangeFileDate": "파일 날짜 변경", - "CheckDownloadClientForDetails": "자세한 내용은 다운로드 클라이언트를 확인하십시오.", + "CheckDownloadClientForDetails": "상세 내용은 다운로드 클라이언트를 확인하세요", "CheckForFinishedDownloadsInterval": "완료된 다운로드 간격 확인", "AgeWhenGrabbed": "연령 (잡았을 때)", "All": "모두", "AutomaticSearch": "자동 검색", "Date": "날짜", - "CouldNotConnectSignalR": "SignalR에 연결할 수 없습니다. UI가 업데이트되지 않습니다.", + "CouldNotConnectSignalR": "SignalR에 연결할 수 없습니다, UI가 업데이트되지 않습니다", "AddRootFolder": "루트 폴더 추가", - "AddToDownloadQueue": "다운로드 대기열에 추가됨", - "AfterManualRefresh": "수동 새로 고침 후", - "AllResultsHiddenFilter": "적용된 필터에 의해 모든 결과가 숨겨집니다.", + "AddToDownloadQueue": "다운로드 대기열에 추가", + "AfterManualRefresh": "수동 새로고침 후", + "AllResultsHiddenFilter": "적용된 필터에 의해 모든 결과가 숨겨집니다", "AptUpdater": "apt를 사용하여 업데이트 설치", "AudioInfo": "오디오 정보", "BuiltIn": "내장", - "CalendarOptions": "달력 옵션", + "CalendarOptions": "캘린더 옵션", "CancelProcessing": "처리 취소", "CertificateValidation": "인증서 검증", - "CertificateValidationHelpText": "HTTPS 인증 유효성 검사의 엄격한 방법 변경", + "CertificateValidationHelpText": "HTTPS 인증 검증의 엄격성을 변경하세요. 위험을 이해하지 않는 한 변경하지 마세요.", "CertValidationNoLocal": "로컬 주소에 대해 비활성화됨", - "CustomFormatUnknownCondition": "알 수 없는 맞춤 형식 조건 '{0}'", + "CustomFormatUnknownCondition": "알 수 없는 사용자 정의 형식 조건 '{implementation}'", "EditGroups": "그룹 편집", - "ExcludeTitle": "{0}을(를) 제외 하시겠습니까? 이렇게하면 {appName}가 목록 동기화를 통해 자동으로 추가하지 못합니다.", - "ChownGroupHelpTextWarning": "{appName}를 실행하는 사용자가 파일의 소유자인 경우에만 작동합니다. 다운로드 클라이언트가 {appName}와 동일한 그룹을 사용하는지 확인하는 것이 좋습니다.", + "ExcludeTitle": "{0}을(를) 제외 하시겠습니까? 이렇게하면 {appName}이(가) 목록 동기화를 통해 자동으로 추가하지 못합니다.", + "ChownGroupHelpTextWarning": "{appName}을(를) 실행하는 사용자가 파일의 소유자인 경우에만 작동합니다. 다운로드 클라이언트가 {appName}와(과) 동일한 그룹을 사용하는지 확인하는 것이 좋습니다.", "CleanLibraryLevel": "정리 라이브러리 수준", "ImportErrors": "가져오기 오류", "ImportExistingMovies": "기존 영화 가져오기", "ImportExtraFiles": "추가 파일 가져오기", "InCinemas": "영화관에서", - "IncludeCustomFormatWhenRenaming": "이름을 바꿀 때 사용자 지정 형식 포함", + "IncludeCustomFormatWhenRenaming": "이름을 바꿀 때 사용자 정의 형식 포함", "Indexer": "인덱서", "CertificationCountryHelpText": "영화 인증 국가 선택", "NextExecution": "다음 실행", - "NoAlternativeTitles": "대체 제목이 없습니다.", - "NoEventsFound": "이벤트가 없습니다.", - "NoLinks": "링크 없음", + "NoAlternativeTitles": "대체 제목이 없음", + "NoEventsFound": "이벤트가 없음", + "NoLinks": "상위 계층 드롭다운 메뉴 링크 비활성화 하기", "ImportHeader": "{appName}에 동영상을 추가하기 위해 기존의 구성 라이브러리 가져오기", - "ImportIncludeQuality": "파일 이름에 품질이 포함되어 있는지 확인하십시오. 예 : {0}", + "ImportIncludeQuality": "파일 이름에 품질이 포함되어 있는지 확인하세요. 예: {0}", "AvailabilityDelayHelpText": "영화를 검색 할 수 있는 날짜 전후의 시간", - "BackupFolderHelpText": "상대 경로는 {appName}의 AppData 디렉토리에 있습니다.", + "BackupFolderHelpText": "상대 경로는 {appName}의 AppData 디렉토리에 있습니다", "CreateEmptyMovieFoldersHelpText": "디스크 스캔 중 누락된 동영상 폴더 생성", "DeleteBackup": "백업 삭제", "QualityProfile": "품질 프로필", "QualityProfiles": "품질 프로필", "AddIndexer": "인덱서 추가", "Age": "연령", - "DeletedMovieDescription": "TMDb에서 영화가 삭제되었습니다.", + "DeletedMovieDescription": "TMDb에서 영화가 삭제되었습니다", "DeleteDownloadClient": "다운로드 클라이언트 삭제", "AnalyticsEnabledHelpText": "익명의 사용 및 오류 정보를 {appName}의 서버에 보냅니다. 여기에는 브라우저에 대한 정보, 사용하는 {appName} WebUI 페이지, 오류 보고, OS 및 런타임 버전이 포함됩니다. 이 정보를 사용하여 기능 및 버그 수정의 우선 순위를 지정합니다.", "DeleteMovieFolder": "영화 폴더 삭제", - "DockerUpdater": "Docker 컨테이너를 업데이트하여 업데이트를 받으십시오.", - "Enabled": "활성화 됨", + "DockerUpdater": "Docker 컨테이너를 업데이트하여 업데이트를 받으세요", + "Enabled": "활성화됨", "FailedDownloadHandling": "실패한 다운로드 처리", "FileNameTokens": "파일 이름 토큰", "HaveNotAddedMovies": "아직 영화를 추가하지 않았습니다. 먼저 영화의 일부 또는 전체를 가져 오시겠습니까?", - "HomePage": "홈 페이지", + "HomePage": "홈페이지", "Hours": "시간", "HttpHttps": "HTTP (S)", "ICalFeed": "iCal 피드", - "ICalFeedHelpText": "이 URL을 클라이언트에 복사하거나 브라우저가 webcal을 지원하는 경우 구독하려면 클릭하십시오.", - "Imported": "수입", + "ICalFeedHelpText": "이 URL을 클라이언트에 복사하거나 브라우저가 (webcal을 지원하는 경우) 구독하려면 클릭", + "Imported": "가져오기 완료", "ImportMechanismHealthCheckMessage": "완료된 다운로드 처리 활성화", - "IllRestartLater": "나중에 다시 시작하겠습니다", + "IllRestartLater": "나중에 재시작하겠습니다", "IndexersSettingsSummary": "인덱서 및 출시 제한", "Info": "정보", "InvalidFormat": "잘못된 형식", "LastExecution": "마지막 실행", "ChmodFolder": "chmod 폴더", "ChmodFolderHelpText": "8 진수, 미디어 폴더 및 파일로 가져오기 / 이름 변경 중에 적용됨 (실행 비트 없음)", - "ChmodFolderHelpTextWarning": "{appName}를 실행하는 사용자가 파일의 소유자인 경우에만 작동합니다. 다운로드 클라이언트가 권한을 올바르게 설정하는지 확인하는 것이 좋습니다.", - "ChownGroupHelpText": "그룹 이름 또는 gid. 원격 파일 시스템에 gid를 사용하십시오.", + "ChmodFolderHelpTextWarning": "{appName}을(를) 실행하는 사용자가 파일의 소유자인 경우에만 작동합니다. 다운로드 클라이언트가 권한을 올바르게 설정하는지 확인하는 것이 좋습니다.", + "ChownGroupHelpText": "그룹 이름 또는 gid. 원격 파일 시스템에 gid를 사용하세요.", "ListSyncLevelHelpTextWarning": "영화 파일이 영구적으로 삭제됩니다. 목록이 비어있는 경우 라이브러리가 삭제될 수 있습니다.", "ListTagsHelpText": "태그 목록 항목이 추가됩니다.", "Max": "최대", - "Medium": "매질", + "Medium": "중간", "MinAvailability": "최소 가용성", - "MinimumAge": "최소 연령", + "MinimumAge": "최소 연령 설정", "MinimumFreeSpace": "최소 여유 공간", "MinimumLimits": "최소 한도", - "Minutes": "의사록", + "Minutes": "분", "ImportListExclusions": "제외 목록", "Monday": "월요일", "MoveFiles": "파일 이동", @@ -232,14 +232,14 @@ "NegateHelpText": "선택하면이 {0} 조건이 일치하면 맞춤 형식이 적용되지 않습니다.", "NoMinimumForAnyRuntime": "런타임에 대한 최소값 없음", "NoMoveFilesSelf": " 아니요, 파일을 직접 이동하겠습니다.", - "NoMoviesExist": "영화를 찾을 수 없습니다. 시작하려면 새 영화를 추가하거나 기존 영화를 가져와야합니다.", - "NoResultsFound": "검색 결과가 없습니다", + "NoMoviesExist": "영화를 찾을 수 없음 시작하려면 새 영화를 추가하거나 기존 영화를 가져와야합니다.", + "NoResultsFound": "결과를 찾을 수 없습니다", "BranchUpdate": "{appName} 업데이트에 사용할 파생 버전", - "Calendar": "달력", + "Calendar": "캘린더", "CancelPendingTask": "이 보류 중인 작업을 취소하시겠습니까?", "OnGrab": "잡기", "OnHealthIssue": "건강 문제", - "OnLatestVersion": "최신 버전의 {appName}가 이미 설치되어 있습니다.", + "OnLatestVersion": "최신 버전의 {appName}이(가) 이미 설치되어 있습니다", "OnlyTorrent": "토렌트 만", "OnlyUsenet": "유즈넷 만", "OnRename": "이름 변경시", @@ -254,21 +254,21 @@ "ProxyType": "프록시 유형", "PtpOldSettingsCheckMessage": "다음 PassThePopcorn 인덱서에는 더 이상 사용되지 않는 설정이 있으며 업데이트해야합니다. {0}", "QualitiesHelpText": "목록에서 더 높은 자질이 더 선호됩니다. 같은 그룹 내의 자질은 동일합니다. 확인 된 품질 만 원합니다.", - "QualityProfileInUseMovieListCollection": "영화에 첨부 된 품질 프로필을 삭제할 수 없습니다.", - "QueueIsEmpty": "대기열이 비어 있습니다.", - "CalendarFeed": "{appName} 달력 피드", - "ReadTheWikiForMoreInformation": "자세한 내용은 Wiki를 참조하십시오.", + "QualityProfileInUseMovieListCollection": "영화에 첨부 된 품질 프로필을 삭제할 수 없음", + "QueueIsEmpty": "제거 대기열이 비어 있습니다", + "CalendarFeed": "{appName} 캘린더 피드", + "ReadTheWikiForMoreInformation": "상세 내용은 Wiki를 참조하세요.", "Reason": "이유", - "RecyclingBinCleanup": "재활용 빈 정리", - "Refresh": "새롭게 하다", - "RefreshMovie": "영화 새로 고침", - "RegularExpressionsCanBeTested": "정규식을 테스트 할 수 있습니다. ", + "RecyclingBinCleanup": "휴지통 정리", + "Refresh": "새로고침", + "RefreshMovie": "영화 새로고침", + "RegularExpressionsCanBeTested": "[여기]({url})에서정규식을 테스트 할 수 있습니다.", "RejectionCount": "거부 횟수", - "Released": "출시", + "Released": "작성일자", "ReleasedMovieDescription": "영화 개봉", "ReleaseRejected": "출시 거부", - "ReplaceWithDash": "대시로 교체", - "New": "새로운", + "ReplaceWithDash": "대시로 바꾸기", + "New": "신규", "LocalPath": "로컬 경로", "RemotePath": "원격 경로", "ShowCertification": "인증 표시", @@ -277,31 +277,31 @@ "TestAllClients": "모든 클라이언트 테스트", "TestAllIndexers": "모든 인덱서 테스트", "TestAllLists": "모든 목록 테스트", - "Queued": "대기 중", + "Queued": "대기열", "TMDb": "TMDb", "Tomorrow": "내일", - "AlternativeTitlesLoadError": "대체 제목을 불러올 수 없습니다.", + "AlternativeTitlesLoadError": "대체 제목을 로드할 수 없음", "Updates": "업데이트", "UpgradesAllowed": "허용되는 업그레이드", - "WhatsNew": "무엇이 새로운가요?", - "Uptime": "가동 시간", + "WhatsNew": "새로운 소식?", + "Uptime": "가동", "Name": "이름", "PreferredSize": "선호하는 크기", - "Pending": "보류 중", + "Pending": "대기중", "DeleteTag": "태그 삭제", "DetailedProgressBarHelpText": "진행률 표시줄에 텍스트 표시", "EnableSsl": "SSL 활성화", "IndexerFlags": "인덱서 플래그", - "IndexerLongTermStatusCheckAllClientMessage": "6 시간 이상 오류로 인해 모든 인덱서를 사용할 수 없습니다.", - "IndexerLongTermStatusCheckSingleClientMessage": "6 시간 이상 오류로 인해 인덱서를 사용할 수 없음 : {indexerNames}", - "IndexerStatusCheckAllClientMessage": "오류로 인해 모든 인덱서를 사용할 수 없습니다.", - "Level": "수평", - "LoadingMovieCreditsFailed": "영화 크레딧을 불러오지 못했습니다.", - "LoadingMovieExtraFilesFailed": "영화 추가 파일을 불러오지 못했습니다.", - "LoadingMovieFilesFailed": "영화 파일을 불러오지 못했습니다.", - "Local": "현지", + "IndexerLongTermStatusCheckAllClientMessage": "6 시간 이상 오류로 인해 모든 인덱서를 사용할 수 없음", + "IndexerLongTermStatusCheckSingleClientMessage": "6 시간 이상 오류로 인해 인덱서를 사용할 수 없음: {indexerNames}", + "IndexerStatusCheckAllClientMessage": "오류로 인해 모든 인덱서를 사용할 수 없음", + "Level": "레벨", + "LoadingMovieCreditsFailed": "영화 크레딧을 로드하지 못함", + "LoadingMovieExtraFilesFailed": "영화 추가 파일을 로드하지 못함", + "LoadingMovieFilesFailed": "영화 파일을 로드하지 못함", + "Local": "로컬", "Location": "위치", - "ManualImport": "수동 가져오기", + "ManualImport": "수동 가져 오기", "MarkAsFailed": "실패로 표시", "MaximumSizeHelpText": "확보 할 출시의 최대 크기 (MB)입니다. 무제한으로 설정하려면 0으로 설정", "Mechanism": "기구", @@ -312,18 +312,18 @@ "MediaManagementSettings": "미디어 관리 설정", "MediaManagementSettingsSummary": "이름 지정 및 파일 관리 설정", "Hostname": "호스트 이름", - "MinutesSixty": "60 분 : {0}", - "Missing": "잃어버린", - "Month": "달", + "MinutesSixty": "60 분: {0}", + "Missing": "누락됨", + "Month": "월", "MountMovieHealthCheckMessage": "동영상 경로가 포함된 마운트는 읽기 전용으로 마운트됩니다. ", "MovieID": "영화 ID", "MovieIndex": "영화 색인", - "MovieInfoLanguageHelpText": "{appName}가 UI의 영화 정보에 사용할 언어", + "MovieInfoLanguageHelpText": "{appName}이(가) UI의 영화 정보에 사용할 언어", "MovieIsDownloading": "영화 다운로드 중", "MovieIsMonitored": "영화가 모니터링됩니다.", "MovieIsUnmonitored": "영화가 모니터링되지 않음", "AddMovies": "영화 추가", - "DownloadClientStatusCheckAllClientMessage": "실패로 인해 모든 다운로드 클라이언트를 사용할 수 없습니다.", + "DownloadClientStatusCheckAllClientMessage": "실패로 인해 모든 다운로드 클라이언트를 사용할 수 없음", "Movies": "영화", "MoviesSelectedInterp": "선택한 영화 {0} 개", "MovieTitle": "영화 제목", @@ -331,24 +331,24 @@ "Actions": "동작", "Added": "추가됨", "AddNew": "새로 추가하기", - "AddNewMessage": "새 영화를 쉽게 추가할 수 있습니다. 추가하려는 영화 제목을 입력하기만 하면 됩니다.", - "AddNewTmdbIdMessage": "영화의 TMDb ID를 사용하여 검색 할 수도 있습니다. 예 : 'tmdb : 71663'", + "AddNewMessage": "새 영화를 쉽게 추가할 수 있습니다. 추가하려는 영화 제목을 입력하기만 하면 됩니다", + "AddNewTmdbIdMessage": "영화의 TMDb ID를 사용하여 검색 할 수도 있습니다. 예: 'tmdb: 71663'", "Agenda": "일정", - "Failed": "실패한", + "Failed": "실패", "MovieYear": "영화 연도", "MovieYearToExcludeHelpText": "제외 할 영화 연도", "MustContain": "포함해야 함", "MustNotContain": "포함해서는 안 됨", "NamingSettings": "이름 지정 설정", "DotNetVersion": ".NET", - "NoBackupsAreAvailable": "사용 가능한 백업이 없습니다.", + "NoBackupsAreAvailable": "사용 가능한 백업이 없음", "NoChange": "변경 없음", "RelativePath": "상대 경로", "NoHistory": "내역 없음", - "NoLogFiles": "로그 파일 없음", + "NoLogFiles": "업데이트 도구 로그 파일", "NoMatchFound": "일치하는 항목이 없습니다!", "NotMonitored": "모니터링되지 않음", - "NoUpdatesAreAvailable": "사용 가능한 업데이트가 없습니다.", + "NoUpdatesAreAvailable": "사용 가능한 업데이트가 없음", "OAuthPopupMessage": "브라우저에서 팝업을 차단하고 있습니다.", "Ok": "확인", "Events": "이벤트", @@ -358,9 +358,9 @@ "Cancel": "취소", "AddMovie": "영화 추가", "AddRestriction": "제한 추가", - "Password": "암호", + "Password": "비밀번호", "Path": "경로", - "Paused": "일시 중지됨", + "Paused": "일시중지", "Permissions": "권한", "AllMoviesHiddenDueToFilter": "적용된 필터로 인해 모든 영화가 숨겨집니다.", "AllowHardcodedSubs": "하드 코딩된 자막 허용", @@ -372,65 +372,65 @@ "Proper": "적절한", "Protocol": "프로토콜", "EditDelayProfile": "지연 프로필 편집", - "ProxyBypassFilterHelpText": "','를 구분 기호로 사용하고 '*'를 사용하십시오. 하위 도메인에 대한 와일드 카드로", - "AllowHardcodedSubsHelpText": "감지된 하드 코딩된 자막은 자동으로 다운로드됩니다.", + "ProxyBypassFilterHelpText": "','를 구분 기호로 사용하고 '*'를 사용하세요. 하위 도메인에 대한 와일드 카드로", + "AllowHardcodedSubsHelpText": "감지된 하드 코딩된 자막은 자동으로 다운로드됩니다", "QuickImport": "빠른 가져오기", - "SupportedDownloadClients": "{appName}는 Newznab 표준을 사용하는 모든 다운로드 클라이언트와 아래 나열된 다른 다운로드 클라이언트를 지원합니다.", - "SupportedListsMovie": "{appName}는 모든 RSS 영화 목록과 아래에 명시된 목록을 지원합니다.", + "SupportedDownloadClients": "{appName}은(는) Newznab 표준을 사용하는 모든 다운로드 클라이언트와 아래 나열된 다른 다운로드 클라이언트를 지원합니다.", + "SupportedListsMovie": "{appName}은(는) 모든 RSS 영화 목록과 아래에 명시된 목록을 지원합니다.", "RadarrTags": "{appName} 태그", - "AlreadyInYourLibrary": "이미 라이브러리에 있습니다.", - "RecyclingBinHelpText": "영화 파일은 영구적으로 삭제되지 않고 삭제되면 여기로 이동합니다.", - "RefreshAndScan": "새로 고침 및 스캔", - "RequiredHelpText": "이 {0} 조건은 적용 할 맞춤 형식에 대해 일치해야합니다. 그렇지 않으면 단일 {1} 일치로 충분합니다.", + "AlreadyInYourLibrary": "이미 라이브러리에 있습니다", + "RecyclingBinHelpText": "영화 파일은 영구적으로 삭제되지 않고 삭제되면 여기로 이동합니다", + "RefreshAndScan": "새로고침 및 스캔", + "RequiredHelpText": "이 {implementationName} 조건은 적용 할 맞춤 형식에 대해 일치해야합니다. 그렇지 않으면 단일 {implementationName} 일치로 충분합니다.", "AddNewRestriction": "새로운 제한 추가", - "AppDataLocationHealthCheckMessage": "업데이트 시 AppData 삭제를 방지하기 위해 업데이트 할 수 없습니다.", - "RestartRequiredHelpTextWarning": "적용하려면 다시 시작해야합니다.", + "AppDataLocationHealthCheckMessage": "업데이트 시 AppData 삭제를 방지하기 위해 업데이트 할 수 없습니다", + "RestartRequiredHelpTextWarning": "적용하려면 재시작해야합니다", "Restore": "복원", "RestoreBackup": "백업 복원", "RootFolder": "루트 폴더", - "RootFolderCheckMultipleMessage": "여러 루트 폴더가 누락 됨 : {rootFolderPaths}", + "RootFolderCheckMultipleMessage": "여러 루트 폴더가 누락 됨: {rootFolderPaths}", "SendAnonymousUsageData": "익명 사용 데이터 보내기", - "FileBrowserPlaceholderText": "입력을 시작하거나 아래 경로를 선택하세요.", + "FileBrowserPlaceholderText": "입력을 시작하거나 아래 경로를 선택하세요", "StartupDirectory": "시작 디렉토리", "System": "시스템", - "SystemTimeHealthCheckMessage": "시스템 시간이 1 일 이상 꺼져 있습니다. 예약 된 작업은 시간이 수정 될 때까지 올바르게 실행되지 않을 수 있습니다.", + "SystemTimeHealthCheckMessage": "시스템 시간이 1 일 이상 차이납니다. 예약된 작업은 시간이 수정될 때까지 올바르게 실행되지 않을 수 있습니다", "Posters": "포스터", "PosterSize": "포스터 크기", - "TagCannotBeDeletedWhileInUse": "사용 중에는 삭제할 수 없습니다.", + "TagCannotBeDeletedWhileInUse": "사용 중에는 삭제할 수 없습니다", "TimeFormat": "시간 형식", - "Timeleft": "Timeleft", + "Timeleft": "남은 시간", "TotalFileSize": "총 파일 크기", "AddListExclusionMovieHelpText": "영화가 목록별로 {appName}에 추가되지 않도록 방지", - "ImportListStatusCheckAllClientMessage": "실패로 인해 모든 목록을 사용할 수 없습니다.", - "ImportListStatusCheckSingleClientMessage": "실패로 인해 사용할 수없는 목록 : {importListNames}", + "ImportListStatusCheckAllClientMessage": "실패로 인해 모든 목록을 사용할 수 없음", + "ImportListStatusCheckSingleClientMessage": "실패로 인해 사용할 수없는 목록: {importListNames}", "TotalSpace": "총 공간", - "UpdateCheckStartupNotWritableMessage": "'{userName}' 사용자가 시작 폴더 '{startupFolder}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없습니다.", - "UpgradesAllowedHelpText": "비활성화 된 자질은 업그레이드되지 않습니다.", + "UpdateCheckStartupNotWritableMessage": "'{userName}' 사용자가 시작 폴더 '{startupFolder}'에 쓸 수 없기 때문에 업데이트를 설치할 수 없음", + "UpgradesAllowedHelpText": "비활성화할 경우 품질은 업그레이드되지 않습니다", "Backup": "백업", - "Username": "사용자 이름", - "WaitingToImport": "가져오기를 기다리는 중", + "Username": "사용자이르", + "WaitingToImport": "가져오기 대기 중", "DigitalRelease": "디지털 출시", "Disabled": "비활성화됨", - "Peers": "동료", - "UiSettingsLoadError": "UI 설정을 불러올 수 없습니다.", + "Peers": "피어", + "UiSettingsLoadError": "UI 설정을 로드할 수 없음", "Unavailable": "사용 불가능", - "VideoCodec": "비디오 코덱", + "VideoCodec": "동영상 코덱", "View": "화면", - "Importing": "가져오기", - "NoLeaveIt": "아니, 놔둬", + "Importing": "가져오는 중", + "NoLeaveIt": "%s에게 답장 남기기", "NoLimitForAnyRuntime": "런타임 제한 없음", - "NotAvailable": "사용할 수 없습니다", + "NotAvailable": "사용 불가", "NotificationTriggers": "알림 트리거", - "Real": "레알", + "Real": "헤알", "ChooseAnotherFolder": "다른 폴더 선택", - "ClickToChangeLanguage": "언어를 변경하려면 클릭하세요", - "CloneCustomFormat": "사용자 지정 형식 복제", + "ClickToChangeLanguage": "언어를 변경하려면 클릭", + "CloneCustomFormat": "사용자 정의 형식 복제", "CloneIndexer": "인덱서 복제", "CloneProfile": "프로필 복제", "Close": "닫기", "Collection": "컬렉션", - "ColonReplacement": "결장 교체", - "ColonReplacementFormatHelpText": "{appName}가 콜론 교체를 처리하는 방법 변경", + "ColonReplacement": "콜론 바꾸기", + "ColonReplacementFormatHelpText": "{appName}이(가) 콜론 바꾸기를 처리하는 방법 변경", "Columns": "열", "CompletedDownloadHandling": "완료된 다운로드 처리", "Conditions": "조건", @@ -439,53 +439,53 @@ "Connections": "연결", "ConnectSettings": "연결 설정", "EditMovie": "영화 편집", - "ConnectSettingsSummary": "알림, 미디어 서버 / 플레이어에 대한 연결 및 사용자 지정 스크립트", + "ConnectSettingsSummary": "알림, 미디어 서버 / 플레이어에 대한 연결 및 사용자 정의 스크립트", "CopyToClipboard": "클립 보드에 복사", "CopyUsingHardlinksHelpTextWarning": "간혹 파일 잠금으로 인해 시드중인 파일의 이름을 바꾸지 못할 수 있습니다. 일시적으로 시드를 비활성화하고 {appName}의 이름 바꾸기 기능을 해결 방법으로 사용할 수 있습니다.", - "CouldNotFindResults": "'{0}'에 대한 결과를 찾을 수 없습니다.", + "CouldNotFindResults": "'{term}'에 대한 결과를 찾을 수 없음", "CreateGroup": "그룹 만들기", "Crew": "크루", "CurrentlyInstalled": "현재 설치됨", - "Custom": "사용자 지정", - "CustomFilters": "사용자 지정 필터", + "Custom": "사용자 정의", + "CustomFilters": "사용자 정의 필터", "CustomFormat": "사용자 정의 형식", - "CustomFormatHelpText": "{appName}는 일치하는 사용자 지정 형식에 대한 점수 합계를 사용하여 각 출시의 점수를 매깁니다. 새 출시가 동일하거나 더 나은 품질로 점수를 향상시키면 {appName}가 점수를 획득합니다.", + "CustomFormatHelpText": "{appName}은(는) 일치하는 사용자 정의 형식에 대한 점수 합계를 사용하여 각 출시의 점수를 매깁니다. 새 출시가 동일하거나 더 나은 품질로 점수를 향상시키면 {appName}이(가) 점수를 획득합니다.", "CustomFormats": "사용자 정의 형식", - "CustomFormatScore": "사용자 지정 형식 점수", + "CustomFormatScore": "사용자 정의 형식 점수", "CustomFormatsSettingsSummary": "사용자 정의 형식 및 설정", - "CustomFormatUnknownConditionOption": "조건 '{1}'에 대해 알 수 없는 옵션 '{0}'", + "CustomFormatUnknownConditionOption": "조건 '{implementation}'에 대해 알 수 없는 옵션 '{key}'", "Cutoff": "중단점", - "UpgradeUntilMovieHelpText": "이 품질에 도달하면 {appName}는 더 이상 영화를 다운로드 하지 않습니다.", - "CutoffUnmet": "중단점 미충족", + "UpgradeUntilMovieHelpText": "이 품질에 도달하면 {appName}은(는) 더 이상 영화를 다운로드 하지 않습니다.", + "CutoffUnmet": "조건 미충족", "Days": "일", "Debug": "디버그", - "DefaultCase": "기본 케이스", + "DefaultCase": "기본 대소문자", "DelayProfile": "지연 프로필", "DelayProfiles": "지연 프로필", "Delete": "삭제", - "DeleteBackupMessageText": "백업 '{0}'을(를) 삭제하시겠습니까?", + "DeleteBackupMessageText": "정말로 백업 '{name}'을(를) 삭제하시겠습니까?", "DeleteDelayProfile": "지연 프로필 삭제", - "DeleteDownloadClientMessageText": "다운로드 클라이언트 '{0}'을(를) 삭제하시겠습니까?", + "DeleteDownloadClientMessageText": "정말로 다운로드 클라이언트 '{name}'을(를) 삭제하시겠습니까?", "DeleteEmptyFolders": "빈 폴더 삭제", "DeleteFile": "파일 삭제", "DeleteMovieFilesHelpText": "동영상 파일 및 동영상 폴더 삭제", - "DeleteHeader": "삭제-{0}", + "DeleteHeader": "삭제 - {0}", "DeleteImportListExclusion": "가져오기 목록 제외 삭제", "DeleteIndexer": "인덱서 삭제", - "DeleteIndexerMessageText": "인덱서 '{0}'을(를) 삭제하시겠습니까?", + "DeleteIndexerMessageText": "정말로 인덱서 '{name}'을(를) 삭제하시겠습니까?", "DeleteMovieFolderHelpText": "동영상 폴더 및 내용 삭제", - "DeleteNotificationMessageText": "알림 '{0}'을(를) 삭제하시겠습니까?", + "DeleteNotificationMessageText": "정말로 알림 '{name}'을(를) 삭제하시겠습니까?", "DeleteQualityProfile": "품질 프로필 삭제", "DeleteRestriction": "제한 삭제", "DeleteRestrictionHelpText": "이 제한을 삭제하시겠습니까?", "DeleteSelectedMovie": "선택한 영화 삭제", - "DeleteSelectedMovieFiles": "선택한 동영상 파일 삭제", - "DeleteTagMessageText": "'{0}' 태그를 삭제하시겠습니까?", - "DeleteMovieFolderConfirmation": "동영상 폴더 '{0}' 및 모든 콘텐츠가 삭제됩니다.", + "DeleteSelectedMovieFiles": "선택한 영화 파일 삭제", + "DeleteTagMessageText": "정말로 '{label}' 태그를 삭제하시겠습니까?", + "DeleteMovieFolderConfirmation": "동영상 폴더 '{path}' 및 모든 콘텐츠가 삭제됩니다.", "DestinationRelativePath": "대상 상대 경로", - "DetailedProgressBar": "자세한 진행률 표시줄", - "Details": "세부 정보", - "Discord": "불일치", + "DetailedProgressBar": "상세 진행률 표시줄", + "Details": "세부 사항", + "Discord": "Discord", "Discover": "둘러보기", "DiskSpace": "디스크 공간", "Docker": "Docker", @@ -494,12 +494,12 @@ "DoNotPrefer": "선호하지 않음", "DoNotUpgradeAutomatically": "자동 업그레이드 안함", "DownloadClient": "클라이언트 다운로드", - "DownloadClientCheckNoneAvailableMessage": "사용 가능한 다운로드 클라이언트가 없습니다.", - "DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName}와(과) 통신할 수 없습니다.", + "DownloadClientCheckNoneAvailableMessage": "사용 가능한 다운로드 클라이언트가 없음", + "DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName}와(과) 통신할 수 없음 {errorMessage}", "DownloadClients": "클라이언트 다운로드", "DownloadClientSettings": "클라이언트 설정 다운로드", "DownloadClientsSettingsSummary": "클라이언트 다운로드, 다운로드 처리 및 원격 경로 매핑", - "DownloadClientStatusCheckSingleClientMessage": "실패로 인해 다운 불러올 수 없는 클라이언트 : {downloadClientNames}", + "DownloadClientStatusCheckSingleClientMessage": "실패로 인해 다운 로드할 수 없는 클라이언트: {downloadClientNames}", "Downloaded": "다운로드됨", "DownloadedAndMonitored": "다운로드됨 (모니터링됨)", "DownloadedButNotMonitored": "다운로드됨 (모니터링되지 않음)", @@ -507,9 +507,9 @@ "Downloading": "다운로드 중", "DownloadPropersAndRepacks": "적절하고 재 포장", "DownloadPropersAndRepacksHelpText": "Propers / Repacks로 자동 업그레이드할지 여부", - "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks 로의 자동 업그레이드를 위해 사용자 지정 형식 사용", + "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks 로의 자동 업그레이드를 위해 사용자 정의 형식 사용", "EditCustomFormat": "사용자 정의 형식 편집", - "Edition": "판", + "Edition": "에디션", "EditImportListExclusion": "목록 제외 편집", "EditPerson": "사람 편집", "EditQualityProfile": "품질 프로필 편집", @@ -518,51 +518,51 @@ "Enable": "활성화", "EnableAutomaticAddMovieHelpText": "활성화하면이 목록에서 영화가 자동으로 {appName}에 추가됩니다.", "EnableAutomaticSearch": "자동 검색 활성화", - "EnableAutomaticSearchHelpText": "UI 또는 {appName}를 통해 자동 검색을 수행 할 때 사용됩니다.", + "EnableAutomaticSearchHelpText": "UI 또는 {appName}을(를) 통해 자동 검색을 수행 할 때 사용됩니다.", "EnableColorImpairedMode": "색 장애 모드 활성화", "EnableColorImpairedModeHelpText": "색상 장애가있는 사용자가 색상 코드 정보를 더 잘 구별 할 수 있도록 스타일 변경", "ListEnabledHelpText": "{appName}에서 사용하기 위해이 목록 활성화", - "EnableMetadataHelpText": "이 메타 데이터 유형에 대한 메타 데이터 파일 생성 활성화", + "EnableMetadataHelpText": "이 메타데이터 유형에 대한 메타데이터 파일 생성 활성화", "EnableInteractiveSearchHelpText": "대화형 검색을 사용할 때 사용됩니다.", - "SearchIsNotSupportedWithThisIndexer": "이 인덱서에서는 검색이 지원되지 않습니다.", - "AnalyseVideoFilesHelpText": "파일에서 해상도, 런타임 및 코덱 정보와 같은 비디오 정보를 추출합니다. 이를 위해서는 {appName}가 스캔 중에 높은 디스크 또는 네트워크 활동을 유발할 수있는 파일의 일부를 읽어야합니다.", + "SearchIsNotSupportedWithThisIndexer": "이 인덱서에서는 검색이 지원되지 않습니다", + "AnalyseVideoFilesHelpText": "파일에서 해상도, 런타임 및 코덱 정보와 같은 비디오 정보를 추출합니다. 이를 위해서는 {appName}이(가) 스캔 중에 높은 디스크 또는 네트워크 활동을 유발할 수있는 파일의 일부를 읽어야합니다.", "EnableRss": "RSS 활성화", - "Ended": "종료됨", + "Ended": "끝남", "Error": "오류", - "EventType": "이벤트 유형", + "EventType": "이벤트 타입", "Exception": "예외", - "Excluded": "제외됨", - "Existing": "기존", + "Excluded": "제외 됨", + "Existing": "기존 파일", "ExistingMovies": "기존 영화", "ExistingTag": "기존 태그", - "ExportCustomFormat": "사용자 지정 형식 내보내기", - "Extension": "확장자", + "ExportCustomFormat": "사용자 정의 형식 내보내기", + "Extension": "확장", "ExtraFileExtensionsHelpText": "가져올 추가 파일의 쉼표로 구분 된 목록 (.nfo는 .nfo-orig로 가져옴)", - "ExtraFileExtensionsHelpTextsExamples": "예 : '.sub, .nfo'또는 'sub, nfo'", - "FailedLoadingSearchResults": "검색 결과를 불러오지 못했습니다. 다시 시도하십시오.", - "FailedToLoadMovieFromAPI": "API에서 영화를 불러오지 못했습니다.", + "ExtraFileExtensionsHelpTextsExamples": "예: '.sub, .nfo'또는 'sub, nfo'", + "FailedLoadingSearchResults": "검색 결과를 로드하지 못함 재시도하세요.", + "FailedToLoadMovieFromAPI": "API에서 영화를 로드하지 못함", "FeatureRequests": "기능 요청", "ChangeFileDateHelpText": "가져오기 / 재검색시 파일 날짜 변경", - "Filename": "파일 이름", + "Filename": "파일이름", "FileNames": "파일 이름", "Files": "파일", "FilterPlaceHolder": "영화 검색", - "Fixed": "결정된", + "Fixed": "고정됨", "FocusSearchBox": "포커스 검색 창", "FolderMoveRenameWarning": "설정에서 동영상 폴더 형식에 따라 동영상 폴더의 이름도 변경됩니다.", "Folders": "폴더", "FollowPerson": "사람을 따르십시오", "Forecast": "예보", "Formats": "형식", - "SupportedDownloadClientsMoreInfo": "개별 다운로드 클라이언트에 대한 자세한 내용을 보려면 정보 버튼을 클릭하십시오.", - "SupportedListsMoreInfo": "개별 가져오기 목록에 대한 자세한 내용을 보려면 정보 버튼을 클릭하십시오.", - "SupportedIndexersMoreInfo": "개별 인덱서에 대한 자세한 내용을 보려면 정보 버튼을 클릭하십시오.", + "SupportedDownloadClientsMoreInfo": "개별 다운로드 클라이언트에 대한 상세 내용을 보려면 정보 버튼을 클릭하세요.", + "SupportedListsMoreInfo": "개별 가져오기 목록에 대한 상세 내용을 보려면 정보 버튼을 클릭하세요.", + "SupportedIndexersMoreInfo": "개별 인덱서에 대한 상세 내용을 보려면 정보 버튼을 클릭하세요.", "General": "일반", "GeneralSettings": "일반 설정", "GeneralSettingsSummary": "포트, SSL, 사용자 이름 / 암호, 프록시, 분석 및 업데이트", "Global": "글로벌", "GoToInterp": "{0}로 이동", - "Grab": "붙잡다", + "Grab": "잡아", "Grabbed": "잡았다", "GrabRelease": "그랩 출시", "GrabSelected": "선택한 항목 잡아", @@ -570,10 +570,10 @@ "HardlinkCopyFiles": "하드 링크 / 복사 파일", "Health": "건강", "NoIssuesWithYourConfiguration": "구성에 문제 없음", - "HiddenClickToShow": "숨김, 클릭하여 표시", + "HiddenClickToShow": "숨김 항목, 표시하려면 클릭", "HideAdvanced": "고급 숨기기", "History": "내역", - "Host": "주최자", + "Host": "호스트", "ICalLink": "iCal 링크", "IconForCutoffUnmet": "Cutoff Unmet 아이콘", "IgnoredAddresses": "무시 된 주소", @@ -588,85 +588,85 @@ "IncludeRecommendationsHelpText": "검색보기에 {appName} 추천 영화 포함", "ImportMovies": "영화 가져오기", "IndexerPriority": "인덱서 우선 순위", - "IndexerPriorityHelpText": "인덱서 우선 순위는 1 (가장 높음)에서 50 (가장 낮음)까지입니다. 기본값 : 25.", - "IndexerRssHealthCheckNoAvailableIndexers": "최근 인덱서 오류로 인해 모든 RSS 지원 인덱서를 일시적으로 사용할 수 없습니다.", - "IndexerRssHealthCheckNoIndexers": "RSS 동기화가 활성화 된 상태에서 사용할 수있는 인덱서가 없습니다. {appName}는 새 출시를 자동으로 가져 오지 않습니다.", + "IndexerPriorityHelpText": "인덱서 우선 순위는 1 (가장 높음)에서 50 (가장 낮음)까지입니다. 기본값: 25.", + "IndexerRssHealthCheckNoAvailableIndexers": "최근 인덱서 오류로 인해 모든 RSS 지원 인덱서를 일시적으로 사용할 수 없음", + "IndexerRssHealthCheckNoIndexers": "RSS 동기화가 활성화 된 상태에서 사용할 수있는 인덱서가 없음, {appName}은(는) 새 출시를 자동으로 가져 오지 않습니다", "Indexers": "인덱서", - "IndexerSearchCheckNoAvailableIndexersMessage": "최근 인덱서 오류로 인해 모든 검색 가능 인덱서를 일시적으로 사용할 수 없습니다.", + "IndexerSearchCheckNoAvailableIndexersMessage": "최근 인덱서 오류로 인해 모든 검색 가능 인덱서를 일시적으로 사용할 수 없음", "InteractiveImport": "대화형 가져오기", - "IndexerSettings": "인덱서 설정", - "IndexerStatusCheckSingleClientMessage": "오류로 인해 인덱서를 사용할 수 없음 : {indexerNames}", + "IndexerSettings": "인덱스 설정", + "IndexerStatusCheckSingleClientMessage": "오류로 인해 인덱서를 사용할 수 없음: {indexerNames}", "InstallLatest": "최신 설치", "KeepAndUnmonitorMovie": "영화 유지 및 모니터링 해제", "KeyboardShortcuts": "키보드 단축키", "Language": "언어", "LanguageHelpText": "출시 용 언어", "Languages": "언어", - "Large": "큰", - "LastUsed": "마지막 사용", + "Large": "크게", + "LastUsed": "최근 사용", "LastWriteTime": "마지막 쓰기 시간", "LaunchBrowserHelpText": " 웹 브라우저를 열고 앱 시작시 {appName} 홈페이지로 이동합니다.", "LinkHere": "여기", - "Links": "연결", + "Links": "링크", "ImportLists": "기울기", "ImportListSettings": "목록 설정", - "ImportListsSettingsSummary": "가져오기 목록, 목록 제외", + "ImportListsSettingsSummary": "다른 {appName} 인스턴스 또는 Trakt 목록에서 가져오기 및 목록 제외 관리", "ListSyncLevelHelpText": "목록에없는 경우 라이브러리의 영화가 제거되거나 모니터링되지 않습니다.", "LogFiles": "로그 파일", - "Logging": "벌채 반출", - "LogLevel": "로그 수준", + "Logging": "로그 기록", + "LogLevel": "로그 레벨", "LogLevelTraceHelpTextWarning": "추적 로깅은 일시적으로 만 활성화해야합니다.", "LogOnly": "로그 만", "Logs": "로그", "LookingForReleaseProfiles1": "출시 프로필을 찾고 계십니까? 시험", - "LookingForReleaseProfiles2": "대신.", + "LookingForReleaseProfiles2": "파일을 이동하는 대신 {appName}에 복사 또는 하드링크(설정/시스템 구성에 따라 다름)를 지시합니다", "Lowercase": "소문자", "ManualImportSelectLanguage": "수동 가져오기 - 언어 선택", "ManualImportSelectMovie": "수동 가져오기 - 동영상 선택", "ManualImportSelectQuality": " 수동 가져오기-품질 선택", - "MappedNetworkDrivesWindowsService": "Windows 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다. 자세한 내용은 FAQ를 참조하십시오.", + "MappedNetworkDrivesWindowsService": "윈도우 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다, 상세 내용은 FAQ를 참조하세요.", "MarkAsFailedMessageText": "'{0}'을(를) 실패한 것으로 표시 하시겠습니까?", "MassMovieSearch": "대량 영화 검색", "MaximumLimits": "최대 한도", "MaximumSize": "최대 크기", "MegabytesPerMinute": "분당 메가 바이트", "Message": "메시지", - "Metadata": "메타 데이터", - "MetadataSettings": "메타 데이터 설정", - "MetadataSettingsMovieSummary": "동영상을 가져오거나 새로 고칠 때 메타 데이터 파일 생성", + "Metadata": "메타데이터", + "MetadataSettings": "메타데이터 설정", + "MetadataSettingsMovieSummary": "동영상을 가져오거나 새로 고칠 때 메타데이터 파일 생성", "MIA": "MIA", "Min": "최소", "MinimumAvailability": "최소 가용성", - "MinimumCustomFormatScore": "최소 사용자 지정 형식 점수", + "MinimumCustomFormatScore": "최소 사용자 정의 형식 점수", "MinimumFreeSpaceHelpText": "사용 가능한 디스크 공간을 이보다 적게 남겨 둘 경우 가져오기 방지", - "MinutesNinety": "90 분 : {0}", - "Mode": "방법", - "Monitor": "감시 장치", + "MinutesNinety": "90 분: {0}", + "Mode": "모드", + "Monitor": "모니터", "Monitored": "모니터링", "MonitoredHelpText": "가능한 경우 영화 다운로드", "MonitoredOnly": "모니터링 만", "MonitoredStatus": "모니터링 됨 / 상태", "MonitorMovie": "영화 모니터링", - "MoreInfo": "더 많은 정보", + "MoreInfo": "더많은 정보", "MoveFolders1": "동영상 폴더를 '{0}'(으)로 이동 하시겠습니까?", "Movie": "영화", "MovieAlreadyExcluded": "이미 제외된 영화", "MovieChat": "영화 채팅", - "MovieDetailsNextMovie": "영화 세부 정보 : 다음 영화", - "MovieIndexScrollBottom": "영화 색인 : 아래로 스크롤", - "MovieIndexScrollTop": "영화 색인 : 상단 스크롤", + "MovieDetailsNextMovie": "영화 세부 사항: 다음 영화", + "MovieIndexScrollBottom": "영화 색인: 아래로 스크롤", + "MovieIndexScrollTop": "영화 색인: 상단 스크롤", "MovieInfoLanguage": "영화 정보 언어", - "MovieInvalidFormat": "영화 : 잘못된 형식", + "MovieInvalidFormat": "영화: 잘못된 형식", "MovieIsOnImportExclusionList": "영화가 수입 제외 목록에 있습니다.", "MultiLanguage": "다국어", - "Negate": "부정", + "Negate": "Negate", "Negated": "부정", - "NoTagsHaveBeenAddedYet": "아직 추가 된 태그가 없습니다.", + "NoTagsHaveBeenAddedYet": "아직 추가 된 태그가 없음", "Options": "옵션", - "Organize": "구성", + "Organize": "편성", "OrganizeConfirm": "선택한 {0} 개의 영화에있는 모든 파일을 정리 하시겠습니까?", "OrganizeSelectedMovies": "선택한 영화 구성", - "Original": "실물", + "Original": "원본", "OutputPath": "출력 경로", "PhysicalReleaseDate": "실제 출시일", "PosterOptions": "포스터 옵션", @@ -675,42 +675,42 @@ "PreferIndexerFlagsHelpText": "특수 플래그로 출시 우선 순위 지정", "Preferred": "선호", "PreviewRename": "이름 변경 미리보기", - "Priority": "우선 순위", - "PrioritySettings": "우선 순위 : {0}", + "Priority": "우선순위", + "PrioritySettings": "우선 순위: {0}", "ProcessingFolders": "처리 폴더", - "ProxyCheckBadRequestMessage": "프록시를 테스트하지 못했습니다. StatusCode : {statusCode}", - "ProxyCheckFailedToTestMessage": "프록시 테스트 실패 : {url}", - "ProxyCheckResolveIpMessage": "구성된 프록시 호스트 {proxyHostName}의 IP 주소를 확인하지 못했습니다.", + "ProxyCheckBadRequestMessage": "프록시를 테스트하지 못함 StatusCode: {statusCode}", + "ProxyCheckFailedToTestMessage": "프록시 테스트 실패: {url}", + "ProxyCheckResolveIpMessage": "구성된 프록시 호스트 {proxyHostName}의 IP 주소를 확인하지 못함", "ProxyPasswordHelpText": "필요한 경우 사용자 이름과 암호 만 입력하면됩니다. 그렇지 않으면 공백으로 두십시오.", "ProxyUsernameHelpText": "필요한 경우 사용자 이름과 암호 만 입력하면됩니다. 그렇지 않으면 공백으로 두십시오.", - "PublishedDate": "발행일", + "PublishedDate": "게시 날짜 표시", "Qualities": "자질", "Quality": "품질", "QualityDefinitions": "품질 정의", "QualityLimitsMovieRuntimeHelpText": "동영상 런타임에 대한 제한이 자동으로 조정됩니다.", "QualitySettingsSummary": "품질 크기 및 이름 지정", - "Queue": "열", - "SupportedIndexers": "{appName}는 Newznab 표준을 사용하는 모든 인덱서와 아래 나열된 다른 인덱서를 지원합니다.", - "SupportedCustomConditions": "{appName}는 아래 출시 속성에 대한 사용자 지정 조건을 지원합니다.", - "Ratings": "등급", + "Queue": "큐", + "SupportedIndexers": "{appName}은(는) Newznab 표준을 사용하는 모든 인덱서와 아래 나열된 다른 인덱서를 지원합니다.", + "SupportedCustomConditions": "{appName}은(는) 아래 출시 속성에 대한 사용자 정의 조건을 지원합니다.", + "Ratings": "평점", "RecentChanges": "최근 변경 사항", "RecentFolders": "최근 폴더", - "RecyclingBinCleanupHelpText": "자동 정리를 사용하지 않으려면 0으로 설정하십시오.", - "RecyclingBin": "재활용 빈", - "RefreshInformationAndScanDisk": "정보 새로 고침 및 디스크 스캔", - "RefreshLists": "목록 새로 고침", - "ReleaseBranchCheckOfficialBranchMessage": "{0} 분기는 유효한 {appName} 출시 분기가 아닙니다. 업데이트를받을 수 없습니다.", + "RecyclingBinCleanupHelpText": "자동 정리를 사용하지 않으려면 0으로 설정하세요.", + "RecyclingBin": "휴지통", + "RefreshInformationAndScanDisk": "정보 새로고침 및 디스크 스캔", + "RefreshLists": "목록 새로고침", + "ReleaseBranchCheckOfficialBranchMessage": "분기 {0}은(는) 유효한 {appName} 출시 분기가 아님, 업데이트를 받을 수 없습니다", "ReleaseDates": "출시일", "ReleaseGroup": "출시 그룹", "ReleaseStatus": "출시 상태", "ReleaseTitle": "출시 제목", - "Reload": "새로 고침", + "Reload": "새로고침", "RemotePathMappings": "원격 경로 매핑", "Remove": "제거", "RemoveCompletedDownloadsHelpText": "다운로드 클라이언트 기록에서 가져온 다운로드 제거", "RemovedFromTaskQueue": "작업 대기열에서 제거됨", - "RemovedMovieCheckMultipleMessage": "영화 {movies}이 (가) TMDb에서 삭제되었습니다.", - "RemovedMovieCheckSingleMessage": "영화 {movie}이 (가) TMDb에서 삭제되었습니다.", + "RemovedMovieCheckMultipleMessage": "영화 {movies}이(가) TMDb에서 삭제되었습니다", + "RemovedMovieCheckSingleMessage": "영화 {movie}이(가) TMDb에서 삭제되었습니다", "RemoveFailedDownloadsHelpText": "다운로드 클라이언트 기록에서 실패한 다운로드 제거", "RemoveFilter": "필터 제거", "RemoveFromDownloadClient": "다운로드 클라이언트에서 제거", @@ -718,52 +718,52 @@ "RemoveHelpTextWarning": "제거하면 다운로드 클라이언트에서 다운로드 및 파일이 제거됩니다.", "RemoveMovieAndKeepFiles": "영화 제거 및 파일 유지", "RemoveRootFolder": "루트 폴더 제거", - "RemoveSelected": "선택 제거", - "RemovingTag": "태그 제거", + "RemoveSelected": "선택된 항목 제거", + "RemovingTag": "삭제", "Renamed": "이름이 변경됨", "RenameFiles": "파일 이름 바꾸기", - "RenameMovies": "영화 이름 변경", - "RenameMoviesHelpText": "{appName}는 이름 변경이 비활성화 된 경우 기존 파일 이름을 사용합니다.", - "Reorder": "재 주문", - "Replace": "바꾸다", - "ReplaceIllegalCharacters": "잘못된 문자 교체", - "ReplaceIllegalCharactersHelpText": "잘못된 문자를 바꿉니다. 선택하지 않으면 {appName}가 대신 제거합니다.", - "ReplaceWithSpaceDash": "스페이스 대시로 교체", - "ReplaceWithSpaceDashSpace": "Space Dash Space로 바꾸기", + "RenameMovies": "영화 이름 바꾸기", + "RenameMoviesHelpText": "{appName}은(는) 이름 바꾸기가 비활성화된 경우 기존 파일 이름을 사용합니다", + "Reorder": "재정렬", + "Replace": "바꾸기", + "ReplaceIllegalCharacters": "잘못된 문자 바꾸기", + "ReplaceIllegalCharactersHelpText": "잘못된 문자를 바꾸세요. 선택하지 않으면 {appName}이(가) 대신 제거합니다", + "ReplaceWithSpaceDash": "공백 대시로 바꾸기", + "ReplaceWithSpaceDashSpace": "공백 대시 공백으로 바꾸기", "Required": "필수", - "RequiredRestrictionHelpText": "출시에는 다음 용어 중 하나 이상이 포함되어야합니다 (대소문자 구분 안함).", - "RescanAfterRefreshMovieHelpText": "영화를 새로 고친 후 영화 폴더를 다시 스캔하십시오.", - "RescanMovieFolderAfterRefresh": "새로 고침 후 영화 폴더 다시 스캔", - "ResetAPIKey": "API 키 재설정", + "RequiredRestrictionHelpText": "출시에는 다음 용어 중 하나 이상이 포함되어야합니다 (대소문자 구분 안함)", + "RescanAfterRefreshMovieHelpText": "영화를 새로 고친 후 영화 폴더를 재스캔하세요", + "RescanMovieFolderAfterRefresh": "새로고침 후 영화 폴더 재스캔", + "ResetAPIKey": "API 키 초기화", "Restart": "재시작", - "RestartNow": "지금 다시 시작", - "RestartRadarr": "{appName} 다시 시작", - "RestartReloadNote": "참고 : {appName}는 복원 프로세스 중에 UI를 자동으로 다시 시작하고 다시로드합니다.", - "Retention": "보유", - "RetentionHelpText": "Usenet 전용 : 무제한 보존을 설정하려면 0으로 설정하십시오.", - "RootFolderCheckSingleMessage": "누락 된 루트 폴더 : {rootFolderPath}", + "RestartNow": "지금 재시작", + "RestartRadarr": "{appName} 재시작", + "RestartReloadNote": "참고: {appName}은(는) 복원 프로세스 중에 UI를 자동으로 재시작하고 다시로드합니다.", + "Retention": "보유기간", + "RetentionHelpText": "유즈넷 전용: 무제한 보존을 설정하려면 0으로 설정하세요", + "RootFolderCheckSingleMessage": "누락 된 루트 폴더: {rootFolderPath}", "RootFolders": "루트 폴더", "Rss": "RSS", - "RssIsNotSupportedWithThisIndexer": "이 인덱서에서는 RSS가 지원되지 않습니다.", + "RssIsNotSupportedWithThisIndexer": "이 인덱서에서는 RSS가 지원되지 않습니다", "RssSync": "RSS 동기화", "RssSyncInterval": "RSS 동기화 간격", - "RssSyncIntervalHelpTextWarning": "이는 모든 인덱서에 적용됩니다. 해당 인덱서가 정한 규칙을 따르십시오.", - "Runtime": "실행 시간", + "RssSyncIntervalHelpTextWarning": "이는 모든 인덱서에 적용됩니다, 해당 인덱서가 정한 규칙을 따라주세요", + "Runtime": "런타임", "Save": "저장", - "SaveChanges": "변경 사항을 저장하다", + "SaveChanges": "변경 사항 저장", "SaveSettings": "설정 저장", - "Scheduled": "예정", + "Scheduled": "예정된 작업", "Score": "점수", "Script": "스크립트", "ScriptPath": "스크립트 경로", "SearchAll": "모두 검색", - "SearchFailedPleaseTryAgainLater": "검색에 실패했습니다. 나중에 다시 시도하십시오.", - "SearchFiltered": "필터링 된 검색", - "SearchForMissing": "누락 된 항목 검색", + "SearchFailedPleaseTryAgainLater": "검색에 실패했습니다. 나중에 재시도해주세요.", + "SearchFiltered": "필터 적용된 항목 검색", + "SearchForMissing": "누락된 항목 검색", "SearchForMovie": "영화 검색", - "SearchMissing": "누락 된 검색", + "SearchMissing": "누락된 항목 검색", "SearchMovie": "영화 검색", - "SearchOnAdd": "추가에서 검색", + "SearchOnAdd": "추가 시 검색", "ListSearchOnAddMovieHelpText": "{appName}에 추가되면이 목록에서 영화 검색", "SearchSelected": "선택 검색", "Seconds": "초", @@ -775,142 +775,142 @@ "SelectMovie": "영화 선택", "SelectQuality": "품질 선택", "SetPermissions": "권한 설정", - "SetPermissionsLinuxHelpText": "파일을 가져 오거나 이름을 바꿀 때 chmod를 실행해야합니까?", - "SetPermissionsLinuxHelpTextWarning": "이러한 설정의 기능을 잘 모르겠 으면 변경하지 마십시오.", + "SetPermissionsLinuxHelpText": "파일을 가져 오거나 이름을 바꿀 때 chmod를 실행해야 합니까?", + "SetPermissionsLinuxHelpTextWarning": "이러한 설정의 기능을 잘 모르겠으면 변경하지 마세요.", "SetTags": "태그 설정", "Settings": "설정", "LongDateFormat": "긴 날짜 형식", "RemotePathMappingHostHelpText": "원격 다운로드 클라이언트에 지정한 것과 동일한 호스트", - "RemotePathMappingLocalPathHelpText": "{appName}가 원격 경로에 로컬로 액세스하는 데 사용해야 하는 경로", + "RemotePathMappingLocalPathHelpText": "{appName}이(가) 원격 경로에 로컬로 액세스하는 데 사용해야 하는 경로", "RemotePathMappingRemotePathHelpText": "다운로드 클라이언트가 액세스하는 디렉토리의 루트 경로", "RuntimeFormat": "런타임 형식", "ShortDateFormat": "짧은 날짜 형식", "ShowRelativeDates": "상대 날짜 표시", "ShowRelativeDatesHelpText": "상대 (오늘 / 어제 / 기타) 또는 절대 날짜 표시", "WeekColumnHeader": "주 열 헤더", - "ListMonitorMovieHelpText": "활성화하면이 목록에 추가 된 영화가 추가되고 모니터링됩니다.", - "ShowAdvanced": "고급보기", + "ListMonitorMovieHelpText": "활성화하면이 목록에 추가된 영화가 추가되고 모니터링이 설정됩니다", + "ShowAdvanced": "고급 설정 표시", "ICalShowAsAllDayEvents": "종일 이벤트로 표시", "IconForCutoffUnmetHelpText": "컷오프가 충족되지 않은 경우 파일 아이콘 표시", - "ShowDateAdded": "추가 된 날짜 표시", - "ShowMonitored": "모니터링 표시", + "ShowDateAdded": "최초 등록일", + "ShowMonitored": "모니터링 설정/해제 표시", "ShowMonitoredHelpText": "포스터 아래에 모니터링 상태 표시", - "ShowMovieInformation": "영화 정보보기", + "ShowMovieInformation": "영화 정보 보기", "ShowMovieInformationHelpText": "영화 장르 및 인증 표시", "ShownClickToHide": "표시됨, 숨기려면 클릭", "ShowPath": "경로 표시", - "ShowQualityProfile": "품질 프로필보기", + "ShowQualityProfile": "품질 프로필 보기", "ShowQualityProfileHelpText": "포스터 아래에 품질 프로필 표시", "ShowRatings": "등급 표시", - "ShowSearch": "검색 표시", - "ShowSearchHelpText": "마우스 오버시 검색 버튼 표시", + "ShowSearch": "검색 링크 표시", + "ShowSearchHelpText": "호버 시 검색 버튼 표시", "ShowSizeOnDisk": "디스크에 크기 표시", - "ShowStudio": "쇼 스튜디오", - "ShowTitle": "쇼 제목", + "ShowStudio": "스튜디오 표시", + "ShowTitle": "제목 표시", "ShowTitleHelpText": "포스터 아래에 영화 제목 표시", - "ShowUnknownMovieItems": "알 수없는 영화 항목 표시", - "ShowYear": "상영 연도", - "Shutdown": "종료", - "SizeOnDisk": "디스크 크기", - "Small": "작은", + "ShowUnknownMovieItems": "알 수 없는 영화 항목 표시", + "ShowYear": "연도 표시", + "Shutdown": "끄기", + "SizeOnDisk": "디스크 상 크기", + "Small": "작게", "Socks4": "Socks4", "Socks5": "Socks5 (TOR 지원)", - "SorryThatMovieCannotBeFound": "죄송합니다. 해당 영화를 찾을 수 없습니다.", + "SorryThatMovieCannotBeFound": "죄송합니다, 해당 영화를 찾을 수 없음", "Sort": "정렬", - "Source": "출처", - "SourcePath": "소스 경로", - "SourceRelativePath": "소스 상대 경로", - "SourceTitle": "소스 제목", + "Source": "원본", + "SourcePath": "원본 경로", + "SourceRelativePath": "원본 상대 경로", + "SourceTitle": "원본 제목", "SslCertPassword": "SSL 인증서 비밀번호", "SslCertPasswordHelpText": "pfx 파일의 비밀번호", "SslCertPath": "SSL 인증서 경로", - "SslCertPathHelpText": "pfx 파일 경로", + "SslCertPathHelpText": "pfx 파일의 경로", "SslPort": "SSL 포트", "StandardMovieFormat": "표준 영화 형식", - "StartImport": "가져오기 시작", + "StartImport": "가져오기", "StartProcessing": "처리 시작", - "StartSearchForMissingMovie": "누락 된 영화 검색 시작", + "StartSearchForMissingMovie": "누락된 영화 검색 시작", "Status": "상태", "Studio": "스튜디오", "Style": "스타일", - "SubfolderWillBeCreatedAutomaticallyInterp": "'{0}'하위 폴더가 자동으로 생성됩니다.", + "SubfolderWillBeCreatedAutomaticallyInterp": "'{0}' 하위 폴더가 자동으로 생성됩니다", "Sunday": "일요일", - "Table": "표", - "TableOptionsColumnsMessage": "표시되는 열과 표시되는 순서 선택", - "TagDetails": "태그 세부 정보-{0}", - "TagIsNotUsedAndCanBeDeleted": "태그는 사용되지 않으며 삭제할 수 있습니다.", + "Table": "테이블", + "TableOptionsColumnsMessage": "표시되는 열과 표시되는 순서를 선택하세요", + "TagDetails": "태그 세부 사항 - {label}", + "TagIsNotUsedAndCanBeDeleted": "태그는 사용되지 않으며 삭제할 수 있습니다", "Tags": "태그", - "ICalTagsMoviesHelpText": "일치하는 태그가 하나 이상있는 영화에 적용됩니다.", - "TagsSettingsSummary": "모든 태그와 사용 방법을 확인하십시오. 사용하지 않는 태그는 제거 할 수 있습니다.", - "Tasks": "과제", + "ICalTagsMoviesHelpText": "일치하는 태그가 하나 이상 있는 영화에 적용됩니다", + "TagsSettingsSummary": "모든 태그와 사용 방법을 확인하세요. 사용하지 않는 태그는 제거할 수 있습니다", + "Tasks": "작업", "Test": "테스트", "TestAll": "모두 테스트", - "TheLogLevelDefault": "로그 수준의 기본값은 '정보'이며 다음에서 변경할 수 있습니다.", - "ThisCannotBeCancelled": "{appName}를 다시 시작하지 않고 시작한 후에는 취소 할 수 없습니다.", + "TheLogLevelDefault": "로그 수준의 기본값은 '정보'이며 [일반 설정](/settings/general)에서 변경할 수 있습니다", + "ThisCannotBeCancelled": "인덱서를 모두 비활성화하지 않고는 이 작업을 시작한 후에는 취소할 수 없음", "Time": "시간", "Title": "제목", "Titles": "제목", - "TMDBId": "TMDb ID", + "TMDBId": "TMDb Id", "TmdbIdExcludeHelpText": "제외 할 영화의 TMDb ID", "Today": "오늘", "TorrentDelay": "토렌트 지연", "TorrentDelayHelpText": "토렌트를 잡기 전에 대기까지 소요되는 지연 (분)", - "TorrentDelayTime": "토렌트 지연: {0torrentDelay}", + "TorrentDelayTime": "토렌트 지연: {torrentDelay}", "Torrents": "토렌트", - "TorrentsDisabled": "토렌트 비활성화", - "Trace": "자취", + "TorrentsDisabled": "토렌트 비활성화됨", + "Trace": "추적", "Trailer": "트레일러", "Trakt": "Trakt", - "Trigger": "트리거", + "Trigger": "트렌딩", "Type": "유형", "Ui": "UI", "UiLanguage": "UI 언어", - "UiLanguageHelpText": "{appName}가 UI에 사용할 언어", - "BrowserReloadRequired": "브라우저 새로 고침 필요", + "UiLanguageHelpText": "{appName}이(가) UI에 사용할 언어", + "BrowserReloadRequired": "브라우저 새로고침 필요", "UiSettings": "UI 설정", - "UiSettingsSummary": "달력, 날짜 및 색상 장애 옵션", - "AddConditionError": "새 조건을 추가 할 수 없습니다. 다시 시도해주세요.", - "AddCustomFormatError": "새 사용자 정의 형식을 추가 할 수 없습니다. 다시 시도하십시오.", - "AddDownloadClientError": "새 다운로드 클라이언트를 추가 할 수 없습니다. 다시 시도하십시오.", - "AddIndexerError": "새 인덱서를 추가 할 수 없습니다. 다시 시도해주세요.", - "AddImportListExclusionError": "새 목록 제외를 추가 할 수 없습니다. 다시 시도하십시오.", - "AddListError": "새 목록을 추가 할 수 없습니다. 다시 시도하십시오.", - "AddQualityProfileError": "새 품질 프로필을 추가 할 수 없습니다. 다시 시도하십시오.", - "AddRemotePathMappingError": "새 원격 경로 매핑을 추가 할 수 없습니다. 다시 시도하십시오.", - "CustomFormatsLoadError": "사용자 정의 형식을 불러올 수 없습니다.", - "DelayProfilesLoadError": "지연 프로필을 불러올 수 없습니다.", - "DownloadClientOptionsLoadError": "다운로드 클라이언트 옵션을 불러올 수 없습니다.", - "GeneralSettingsLoadError": "일반 설정을 불러올 수 없습니다.", - "IndexerOptionsLoadError": "인덱서 옵션을 불러올 수 없습니다.", + "UiSettingsSummary": "캘린더, 날짜 및 색상 장애 옵션", + "AddConditionError": "새 조건을 추가 할 수 없음 재시도해주세요.", + "AddCustomFormatError": "새 사용자 정의 형식을 추가 할 수 없음 재시도해주세요.", + "AddDownloadClientError": "새 다운로드 클라이언트를 추가 할 수 없음 재시도해주세요.", + "AddIndexerError": "새 인덱서를 추가 할 수 없음 재시도해주세요.", + "AddImportListExclusionError": "새 목록 제외를 추가 할 수 없음 재시도해주세요.", + "AddListError": "새 목록을 추가 할 수 없음 재시도해주세요.", + "AddQualityProfileError": "새 품질 프로필을 추가 할 수 없음 재시도해주세요.", + "AddRemotePathMappingError": "새 원격 경로 매핑을 추가 할 수 없음 재시도해주세요.", + "CustomFormatsLoadError": "사용자 정의 형식을 로드할 수 없습니다", + "DelayProfilesLoadError": "지연 프로필을 로드할 수 없", + "DownloadClientOptionsLoadError": "다운로드 클라이언트 옵션을 로드할 수 없음", + "GeneralSettingsLoadError": "일반 설정을 로드할 수 없", + "IndexerOptionsLoadError": "인덱서 옵션을 로드할 수 없음", "Unlimited": "무제한", - "ImportListExclusionsLoadError": "목록 예외를 불러올 수 없습니다.", - "ListOptionsLoadError": "목록 옵션을 불러올 수 없습니다.", - "ImportListsLoadError": "목록을 불러올 수 없습니다.", - "UnableToLoadManualImportItems": "수동 가져오기 항목을 불러올 수 없습니다.", - "MediaManagementSettingsLoadError": "미디어 관리 설정을 불러올 수 없습니다.", - "MetadataLoadError": "메타 데이터를 불러올 수 없습니다.", - "UnableToLoadMovies": "영화를 불러올 수 없습니다.", - "NamingSettingsLoadError": "이름 지정 설정을 불러올 수 없습니다.", - "NotificationsLoadError": "알림을 불러올 수 없습니다.", - "QualityProfilesLoadError": "품질 프로필을 불러올 수 없습니다.", - "RemotePathMappingsLoadError": "원격 경로 매핑을 불러올 수 없습니다.", - "UnableToLoadRestrictions": "제한을 불러올 수 없습니다.", - "UnableToLoadRootFolders": "루트 폴더를 불러올 수 없습니다.", - "CalendarLoadError": "달력을 불러올 수 없습니다.", - "UpdateAppDirectlyLoadError": "{appName}를 직접 업데이트 할 수 없습니다.", + "ImportListExclusionsLoadError": "가져오기 목록 제외를 로드할 수 없음", + "ListOptionsLoadError": "목록 옵션을 로드할 수 없음", + "ImportListsLoadError": "가져오기 목록을 로드할 수 없음", + "UnableToLoadManualImportItems": "수동 가져오기 항목을 로드할 수 없습니다", + "MediaManagementSettingsLoadError": "미디어 관리 설정을 로드할 수 없음", + "MetadataLoadError": "메타데이터를 로드할 수 없음", + "UnableToLoadMovies": "영화를 로드할 수 없습니다", + "NamingSettingsLoadError": "이름 지정 설정을 로드할 수 없음", + "NotificationsLoadError": "알림을 로드할 수 없음", + "QualityProfilesLoadError": "품질 프로필을 로드할 수 없음", + "RemotePathMappingsLoadError": "원격 경로 매핑을 로드할 수 없음", + "UnableToLoadRestrictions": "제한을 로드할 수 없습니다", + "UnableToLoadRootFolders": "루트 폴더를 로드할 수 없습니다", + "CalendarLoadError": "캘린더를 로드할 수 없음", + "UpdateAppDirectlyLoadError": "{appName}을(를) 직접 업데이트 할 수 없음", "Ungroup": "그룹 해제", - "UnmappedFilesOnly": "매핑되지 않은 파일 만", + "UnmappedFilesOnly": "매핑되지 않은 파일만", "UnmappedFolders": "매핑되지 않은 폴더", - "Unmonitored": "모니터링되지 않음", - "Unreleased": "없는", + "Unmonitored": "모니터링 되지 않음", + "Unreleased": "비공개(Unreleased)", "UnsavedChanges": "저장되지 않은 변경 사항", "UnselectAll": "모두 선택 해제", "UpdateAll": "모두 업데이트", - "UpdateAutomaticallyHelpText": "업데이트를 자동으로 다운로드하고 설치합니다. 시스템 : 업데이트에서 계속 설치할 수 있습니다.", - "UpdateCheckStartupTranslocationMessage": "시작 폴더 '{startupFolder}'이 (가) App Translocation 폴더에 있으므로 업데이트를 설치할 수 없습니다.", + "UpdateAutomaticallyHelpText": "업데이트를 자동으로 다운로드하고 설치하세요. 시스템: 업데이트에서 계속 설치할 수 있습니다", + "UpdateCheckStartupTranslocationMessage": "시작 폴더 '{startupFolder}'이 (가) App Translocation 폴더에 있으므로 업데이트를 설치할 수 없음", "UpdateMechanismHelpText": "{appName}의 내장 업데이트 도구 또는 스크립트 사용", "UpdateSelected": "선택한 항목 업데이트", - "UpgradeUntilCustomFormatScore": "사용자 지정 형식 점수까지 업그레이드", + "UpgradeUntilCustomFormatScore": "사용자 정의 형식 점수까지 업그레이드", "UpgradeUntilThisQualityIsMetOrExceeded": "이 품질이 충족되거나 초과 될 때까지 업그레이드", "Uppercase": "대문자", "UrlBase": "URL 기반", @@ -918,7 +918,7 @@ "UseHardlinksInsteadOfCopy": "복사 대신 하드 링크 사용", "UsenetDelay": "유즈넷 지연", "UsenetDelayHelpText": "Usenet에서 출시를 가져오기 전에 대기하는 데 몇 분 지연", - "UsenetDelayTime": "유즈넷 지연 : {0}", + "UsenetDelayTime": "유즈넷 지연: {usenetDelay}", "UsenetDisabled": "유즈넷 비활성화", "UseProxy": "프록시 사용", "Version": "버전", @@ -927,7 +927,7 @@ "Warn": "경고", "Week": "주", "Weeks": "주", - "WhitelistedHardcodedSubsHelpText": "여기에 설정된 자막 태그는 하드 코딩 된 것으로 간주되지 않습니다.", + "WhitelistedHardcodedSubsHelpText": "여기에 설정된 자막 태그는 하드 코딩 된것으로 간주되지 않습니다", "WhitelistedSubtitleTags": "허용된 자막 태그", "Wiki": "위키", "WouldYouLikeToRestoreBackup": "'{name}' 백업을 복원하시겠습니까?", @@ -935,31 +935,31 @@ "YesCancel": "예, 취소합니다", "YesMoveFiles": "예, 파일을 이동합니다", "Yesterday": "어제", - "MaintenanceRelease": "유지 관리 출시 : 버그 수정 및 기타 개선. 자세한 내용은 Github 커밋 내역을 참조하십시오.", + "MaintenanceRelease": "유지 관리 출시: 버그 수정 및 기타 개선. 상세 내용은 Github 커밋 내역을 참조하세요.", "MissingMonitoredAndConsideredAvailable": "누락 (모니터링 됨)", "MissingNotMonitored": "누락 (모니터링되지 않음)", "MoveFolders2": "동영상 파일을 '{0}'에서 '{1}'(으)로 이동 하시겠습니까?", - "MovieDetailsPreviousMovie": "영화 정보 : 이전 영화", + "MovieDetailsPreviousMovie": "영화 정보: 이전 영화", "MovieEditor": "영화 편집기", "MovieExcludedFromAutomaticAdd": "자동 추가에서 제외된 영화", "Search": "검색", - "Edit": "편집하다", - "SqliteVersionCheckUpgradeRequiredMessage": "현재 설치된 SQLite 버전 {0}은 더 이상 지원되지 않습니다. SQLite를 최소한 {1} 버전으로 업그레이드하십시오.", + "Edit": "편집", + "SqliteVersionCheckUpgradeRequiredMessage": "현재 설치된 SQLite 버전 {0}은(는) 더 이상 지원되지 않습니다. SQLite를 최소한 {1} 버전으로 업그레이드해주세요.", "ShowReleaseDateHelpText": "포스터 아래에 출시일 표시", "ShowCinemaRelease": "영화 개봉일 표시", "ShowReleaseDate": "출시일 표시", "OnMovieFileDeleteForUpgrade": "영화 파일에서 업그레이드를 위해 삭제", "OnMovieDelete": "영화 삭제 시", "OnMovieFileDelete": "영화 파일 삭제", - "Reddit": "레딧", - "More": "더보기", + "Reddit": "Reddit", + "More": "더 보기", "Download": "다운로드", "DownloadClientRootFolderHealthCheckMessage": "다운로드 클라이언트 {downloadClientName} 은(는) 루트 폴더 {rootFolderPath}에 다운로드를 저장합니다. 루트 폴더에 다운로드해서는 안됩니다.", - "Blocklist": "블랙리스트", - "BlocklistRelease": "블랙리스트 릴리스", + "Blocklist": "차단 목록", + "BlocklistRelease": "차단 목록 출시", "RemoveFromBlocklist": "블랙리스트에서 제거", "Blocklisted": "블랙리스트", - "BlocklistReleases": "블랙리스트 릴리스", + "BlocklistReleases": "블랙리스트 출시", "SelectLanguages": "언어 선택", "Rating": "등급", "Filters": "필터", @@ -967,109 +967,109 @@ "AllCollectionsHiddenDueToFilter": "적용된 필터로 인해 모든 영화가 숨겨집니다.", "MonitorMovies": "영화 모니터링", "Collections": "컬렉션", - "NoCollections": "영화를 찾을 수 없습니다. 시작하려면 새 영화를 추가하거나 기존 영화를 가져와야합니다.", - "RssSyncIntervalHelpText": "간격 (분)입니다. 사용하지 않으려면 0으로 설정합니다 (모든 자동 릴리스 잡기가 중지됨).", + "NoCollections": "컬렉션을 찾을 수 없음, 시작하려면 새 영화를 추가하거나 기존 영화를 가져와야합니다", + "RssSyncIntervalHelpText": "분단위 간격. 비활성화 하려면 0으로 설정하세요 (모든 자동 출시 잡기가 중지됩니다)", "File": "파일", "DeleteRemotePathMapping": "원격 경로 매핑 편집", - "DeleteCustomFormatMessageText": "인덱서 '{name}'을 (를) 삭제 하시겠습니까?", + "DeleteCustomFormatMessageText": "인덱서 '{name}'을(를) 삭제 하시겠습니까?", "DeleteDelayProfileMessageText": "이 지연 프로필을 삭제하시겠습니까?", - "ResetAPIKeyMessageText": "API 키를 재설정하시겠습니까?", - "DeleteConditionMessageText": "'{0}' 태그를 삭제하시겠습니까?", - "DeleteFormatMessageText": "형식 태그 {0}을(를) 삭제하시겠습니까?", + "ResetAPIKeyMessageText": "API 키를 초기화하시겠습니까?", + "DeleteConditionMessageText": "정말로 '{name}' 태그를 삭제하시겠습니까?", + "DeleteFormatMessageText": "정말로 형식 태그 {0}을(를) 삭제하시겠습니까?", "DeleteImportListExclusionMessageText": "이 가져오기 목록 제외를 삭제하시겠습니까?", "DeleteSelectedDownloadClients": "다운로드 클라이언트 삭제", "DeleteSelectedIndexers": "인덱서 삭제", "RemoveSelectedItemQueueMessageText": "대기열에서 {0} 항목 {1}을 제거하시겠습니까?", - "RemoveSelectedItemsQueueMessageText": "대기열에서 {0} 항목 {1}을 제거하시겠습니까?", - "ApplyTagsHelpTextAdd": "추가 : 기존 태그 목록에 태그를 추가합니다.", - "ApplyTagsHelpTextHowToApplyIndexers": "선택한 동영상에 태그를 적용하는 방법", - "ApplyTagsHelpTextRemove": "제거 : 입력한 태그를 제거합니다.", - "ApplyTagsHelpTextReplace": "바꾸기 : 태그를 입력 한 태그로 바꿉니다 (모든 태그를 지우려면 태그를 입력하지 않음)", + "RemoveSelectedItemsQueueMessageText": "대기열에서 {selectedCount}개의 항목을 제거하시겠습니까?", + "ApplyTagsHelpTextAdd": "추가: 기존 태그 목록에 태그를 추가하세요", + "ApplyTagsHelpTextHowToApplyIndexers": "선택한 인덱서에 태그를 적용하는 방법", + "ApplyTagsHelpTextRemove": "제거: 입력한 태그를 제거하세요", + "ApplyTagsHelpTextReplace": "바꾸기: 태그를 입력 한 태그로 바꾸세요 (모든 태그를 지우려면 태그를 입력하지 않음)", "StopSelecting": "선택 취소", "EditMovies": "일괄 수정하기", "EditSelectedMovies": "선택된 영화 수정하기", - "QueueLoadError": "대기열을 불러오지 못했습니다.", + "QueueLoadError": "대기열을 로드하지 못함", "IncludeHealthWarnings": "건강 경고 포함", - "AutoRedownloadFailed": "다운로드 실패함", + "AutoRedownloadFailed": "재다운로드에 실패함", "AddListExclusion": "목록 예외 추가", - "RestartLater": "나중에 다시 시작하겠습니다", + "RestartLater": "나중에 재시작하겠습니다", "DeleteSpecification": "알림 삭제", - "DeleteSpecificationHelpText": "품질 프로필 {0}을 (를) 삭제 하시겠습니까?", - "HistoryLoadError": "기록을로드 할 수 없습니다.", - "DeleteImportListMessageText": "품질 프로필 {0}을 (를) 삭제 하시겠습니까?", - "DeletedReasonUpgrade": "업그레이드를 가져오기 위해 파일이 삭제되었습니다.", + "DeleteSpecificationHelpText": "정말로 사양 '{name}'을(를) 삭제하시겠습니까?", + "HistoryLoadError": "기록을 로드 할 수 없음", + "DeleteImportListMessageText": "정말로 목록 '{name}'을(를) 삭제하시겠습니까?", + "DeletedReasonUpgrade": "업그레이드를 가져오기 위해 파일이 삭제되었습니다", "MoveAutomatically": "빠른 가져오기", - "DelayingDownloadUntil": "{0}까지 {1}에 다운로드 지연", + "DelayingDownloadUntil": "{date} {time}까지 다운로드 지연 중", "DisabledForLocalAddresses": "로컬 주소에 대해 비활성화됨", - "BypassDelayIfAboveCustomFormatScoreMinimumScore": "최소 사용자 지정 형식 점수", - "DeleteQualityProfileMessageText": "품질 프로필 {0}을 (를) 삭제 하시겠습니까?", + "BypassDelayIfAboveCustomFormatScoreMinimumScore": "최소 사용자 정의 형식 점수", + "DeleteQualityProfileMessageText": "정말로 품질 프로필 '{name}을(를) 삭제하시겠습니까?", "InteractiveSearchModalHeader": "대화형 검색", - "NotificationStatusAllClientHealthCheckMessage": "실패로 인해 모든 목록을 사용할 수 없습니다.", - "ApplyTagsHelpTextHowToApplyDownloadClients": "선택한 동영상에 태그를 적용하는 방법", + "NotificationStatusAllClientHealthCheckMessage": "실패로 인해 모든 목록을 사용할 수 없음", + "ApplyTagsHelpTextHowToApplyDownloadClients": "선택한 다운로드 클라이언트에 태그를 적용하는 방법", "ConnectionLostReconnect": "Radarr가 자동으로 연결을 시도하거나 아래에서 새로고침을 클릭할 수 있습니다.", - "ConnectionLostToBackend": "Radarr는 백엔드와의 연결이 끊어졌으며 기능을 복원하려면 다시 로딩해야 합니다.", - "DeleteReleaseProfile": "지연 프로필 삭제", - "DeleteReleaseProfileMessageText": "품질 프로필 {0}을 (를) 삭제 하시겠습니까?", - "OrganizeNothingToRename": "성공! 내 작업이 완료되었으며 이름을 바꿀 파일이 없습니다.", - "ReleaseGroups": "릴리스 그룹", - "AutoTaggingNegateHelpText": "선택하면이 {0} 조건이 일치하면 맞춤 형식이 적용되지 않습니다.", - "DelayProfileMovieTagsHelpText": "일치하는 태그가 하나 이상있는 영화에 적용됩니다.", + "ConnectionLostToBackend": "{appName}이(가) 백엔드와의 연결이 끊어졌으며 기능을 복원하려면 재로딩해야 합니다.", + "DeleteReleaseProfile": "출시 프로필 삭제", + "DeleteReleaseProfileMessageText": "정말로 출시 프로필 '{name}'을(를) 삭제 하시겠습니까?", + "OrganizeNothingToRename": "성공! 내 작업이 완료되었으며 이름을 바꿀 파일이 없음", + "ReleaseGroups": "출시 그룹", + "AutoTaggingNegateHelpText": "{implementationName}선택하면 이 {implementationName} 조건이 일치하면 자동 태그 지정 규칙이 적용되지 않습니다.", + "DelayProfileMovieTagsHelpText": "일치하는 태그가 하나 이상있는 영화에 적용됨", "TablePageSizeHelpText": "각 페이지에 표시 할 항목 수", - "OrganizeLoadError": "미리보기를로드하는 중에 오류가 발생했습니다.", - "RetryingDownloadOn": "{1}에 {0} 다운로드 재시도", - "BlocklistLoadError": "블랙리스트를로드 할 수 없습니다.", - "NotificationStatusSingleClientHealthCheckMessage": "실패로 인해 사용할 수없는 목록 : {notificationNames}", + "OrganizeLoadError": "미리보기를 로드하는 중에 오류가 발생함", + "RetryingDownloadOn": "{date} {time}에 다운로드 재시도", + "BlocklistLoadError": "차단 목록을 로드할 수 없음", + "NotificationStatusSingleClientHealthCheckMessage": "실패로 인해 사용할 수없는 목록: {notificationNames}", "GrabId": "ID 잡아", - "RemoveQueueItemConfirmation": "대기열에서 {0} 항목 {1}을 제거하시겠습니까?", - "ReleaseProfilesLoadError": "지연 프로필을로드 할 수 없습니다.", - "QualitiesLoadError": "품질을로드 할 수 없습니다.", + "RemoveQueueItemConfirmation": "정말로 대기열에서 '{sourceTitle}'을(를) 제거하시겠습니까?", + "ReleaseProfilesLoadError": "지연 프로필을 로드할 수 없음", + "QualitiesLoadError": "품질을 로드 할 수 없음", "TablePageSize": "페이지 크기", - "AddAutoTagError": "새 자동 태그을 추가 할 수 없습니다. 다시 시도해주세요.", - "AddRootFolderError": "루트 폴더를로드 할 수 없습니다.", - "ApplyTagsHelpTextHowToApplyImportLists": "선택한 동영상에 태그를 적용하는 방법", - "MustNotContainHelpText": "하나 이상의 용어가 포함 된 경우 릴리스가 거부됩니다 (대소 문자 구분 안 함).", - "MustContainHelpText": "릴리스에는 다음 용어 중 하나 이상이 포함되어야합니다 (대소 문자 구분 안 함).", - "SelectDropdown": "'선택...", - "CustomFilter": "사용자 지정 필터", - "DeleteAutoTagHelpText": "품질 프로필 {0}을 (를) 삭제 하시겠습니까?", - "DownloadClientsLoadError": "다운로드 클라이언트를로드 할 수 없습니다.", + "AddAutoTagError": "새 자동 태그을 추가 할 수 없음 재시도해주세요.", + "AddRootFolderError": "루트 폴더를 추가할 수 없음", + "ApplyTagsHelpTextHowToApplyImportLists": "선택한 가져오기 목록에 태그를 적용하는 방법", + "MustNotContainHelpText": "하나 이상의 용어가 포함 된 경우 출시가 거부됩니다 (대소 문자 구분 안 함).", + "MustContainHelpText": "출시에는 다음 용어 중 하나 이상이 포함되어야합니다 (대소 문자 구분 안 함).", + "SelectDropdown": "선택...", + "CustomFilter": "사용자 정의 필터", + "DeleteAutoTagHelpText": "정말로 자동 태그 '{name}'을(를) 삭제하시겠습니까?", + "DownloadClientsLoadError": "다운로드 클라이언트를로드 할 수 없음", "Lists": "기울기", "No": "아니", "RemoveSelectedBlocklistMessageText": "블랙리스트에서 선택한 항목을 제거 하시겠습니까?", "Yes": "예", - "ApplyTagsHelpTextHowToApplyMovies": "선택한 동영상에 태그를 적용하는 방법", - "DeletedReasonMovieMissingFromDisk": "{appName}가 디스크에서 파일을 찾을 수 없어 제거되었습니다.", - "ShowUnknownMovieItemsHelpText": "대기열에 영화가없는 항목을 표시합니다. 여기에는 제거 된 영화 또는 {appName} 카테고리의 다른 항목이 포함될 수 있습니다.", - "DeleteSelectedMovieFilesHelpText": "선택한 동영상 파일을 삭제 하시겠습니까?", + "ApplyTagsHelpTextHowToApplyMovies": "선택한 영화에 태그를 적용하는 방법", + "DeletedReasonMovieMissingFromDisk": "{appName}이(가) 디스크에서 파일을 찾을 수 없어 제거되었습니다.", + "ShowUnknownMovieItemsHelpText": "대기열에 영화가 없는 항목을 표시합니다. 여기에는 제거 된 영화 또는 '{appName}' 카테고리의 다른 항목이 포함될 수 있습니다", + "DeleteSelectedMovieFilesHelpText": "정말로 선택한 영화 파일을 삭제하시겠습니까?", "DownloadClientSettingsRecentPriority": "클라이언트 우선 순위", - "MovieSearchResultsLoadError": "이 영화 검색 결과를 불러올 수 없습니다. 나중에 다시 시도", + "MovieSearchResultsLoadError": "이 영화 검색 결과를 로드할 수 없음 나중에 재시도", "NotificationsSimplepushSettingsEvent": "이벤트", "SearchOnAddCollectionHelpText": "{appName}에 추가되면이 목록에서 영화 검색", - "AddDelayProfileError": "새 지연 프로필을 추가할 수 없습니다. 다시 시도해주세요.", + "AddDelayProfileError": "새 지연 프로필을 추가할 수 없음 재시도해주세요.", "DeleteMovieFolders": "영화 폴더 삭제", - "DeleteMovieFoldersHelpText": "동영상 폴더 및 내용 삭제", - "DeleteSelectedMovies": "선택한 동영상 파일 삭제", - "DeleteSelectedImportListExclusionsMessageText": "이 가져오기 목록 제외를 삭제하시겠습니까?", - "DeleteSelectedCustomFormats": "사용자 지정 형식 삭제", + "DeleteMovieFoldersHelpText": "영화 폴더 및 콘텐츠 삭제", + "DeleteSelectedMovies": "선택한 영화 삭제", + "DeleteSelectedImportListExclusionsMessageText": "정말로 이 가져오기 목록 제외를 삭제하시겠습니까?", + "DeleteSelectedCustomFormats": "사용자 정의 형식 삭제", "ReleaseDate": "출시일", "MovieFileDeleted": "영화 파일 삭제", "MovieFileDeletedTooltip": "영화 파일 삭제", "Clone": "닫기", "EditReleaseProfile": "지연 프로필 편집", - "AllTitles": "모든 파일", + "AllTitles": "모든 제목", "AppUpdated": "{appName} 업데이트", "AddIndexerImplementation": "인덱서 추가 - {implementationName}", "Any": "모두", "AddConnection": "연결 추가", "AddConnectionImplementation": "연결 추가 - {implementationName}", "AddDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", - "ApiKeyValidationHealthCheckMessage": "API 키를 {length}자 이상으로 업데이트하세요. 설정 또는 구성 파일을 통해 이 작업을 수행할 수 있습니다.", - "AppUpdatedVersion": "{appName}이 버전 `{version}`으로 업데이트되었습니다. 최신 변경 사항을 받으려면 {appName}을 다시 로드해야 합니다", + "ApiKeyValidationHealthCheckMessage": "API 키를 {length}자 이상으로 업데이트하세요. 설정 또는 구성 파일을 통해 이 작업을 수행할 수 있습니다", + "AppUpdatedVersion": "{appName}이 버전 `{version}`으로 업데이트되었습니다. 최신 변경 사항을 받으려면 {appName}을 재로드해야 합니다", "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "해시에 의해 토렌트가 차단된 경우 일부 인덱서의 RSS/검색 중에 토렌트가 제대로 거부되지 않을 수 있습니다. 이 기능을 활성화하면 토렌트를 가져온 후 클라이언트로 전송하기 전에 토렌트를 거부할 수 있습니다.", "EditIndexerImplementation": "인덱서 추가 - {implementationName}", "AddReleaseProfile": "지연 프로필 편집", "IndexerSettingsRejectBlocklistedTorrentHashes": "동기화 중 차단 목록에 있는 토렌트 해시 거부", - "DownloadClientUnavailable": "다운로드 클라이언트를 사용할 수 없습니다.", + "DownloadClientUnavailable": "다운로드 클라이언트를 사용할 수 없음", "EditConditionImplementation": "연결 추가 - {implementationName}", "EditConnectionImplementation": "애플리케이션 추가 - {implementationName}", "EditDownloadClientImplementation": "다운로드 클라이언트 추가 - {implementationName}", @@ -1079,7 +1079,7 @@ "TraktRating": "Trakt 평점", "AddAutoTag": "자동 태그 추가", "AddCondition": "조건 추가", - "TotalMovies": "총 영화", + "TotalMovies": "총 영화 개수", "UseSsl": "SSL 사용", "UsenetBlackhole": "유즈넷 블랙홀", "TypeOfList": "{typeOfList} 목록", @@ -1099,5 +1099,798 @@ "AutoTaggingSpecificationStatus": "상태", "CustomFormatsSpecificationLanguage": "언어", "CustomFormatsSpecificationMaximumSize": "최대 크기", - "CustomFormatsSpecificationSource": "출처" + "CustomFormatsSpecificationSource": "원본", + "AuthenticationMethod": "인증 방식", + "Category": "카테고리", + "ResetTitles": "제목 초기화", + "UpdateFiltered": "업데이트에 필터 적용됨", + "ReleasePush": "출시 푸시", + "ReleaseSource": "출시 원본", + "ReleasedMovieAvailabilityDescription": "영화는 블루레이 또는 스트리밍 버전이 출시되자마자 이용 가능한 것으로 간주됩니다.", + "RemotePathMappingCheckBadDockerPath": "Docker를 사용하고 있습니다. 다운로드 클라이언트 {downloadClientName}는 {path}에 다운로드를 배치하지만 이는 유효한 {osName} 경로가 아닙니다. 원격 경로 매핑과 다운로드 클라이언트 설정을 검토하세요.", + "RemotePathMappingCheckDownloadPermissions": "{appName}은(는) 다운로드한 영화 {path}을(를) 볼 수는 있지만 액세스할 수 없음 권한 오류일 가능성이 높습니다.", + "RemotePathMappingCheckFileRemoved": "파일 {path}이(가) 처리 도중에 제거되었습니다.", + "RemotePathMappingCheckFilesBadDockerPath": "Docker를 사용하고 있습니다. 클라이언트 {downloadClientName}에서 보고된 파일을 {path}에서 다운로드했지만 이는 유효한 {osName} 경로가 아닙니다. 원격 경로 매핑을 검토하고 클라이언트 설정을 다운로드하세요.", + "RemotePathMappingsInfo": "원격 경로 매핑은 거의 필요하지 않습니다. {appName}와(과) 다운로드 클라이언트가 동일한 시스템에 있는 경우 경로를 일치시키는 것이 좋습니다. 상세 내용은 [위키]({wikiLink})를 참조하세요.", + "RemoveQueueItem": "제거 - {sourceTitle}", + "RemoveMultipleFromDownloadClientHint": "다운로드 클라이언트에서 다운로드 및 파일을 제거합니다", + "RemoveQueueItemRemovalMethod": "제거 방식", + "RemoveTagsAutomatically": "태그 자동 제거", + "RemoveSelectedItem": "선택한 항목 제거", + "RemoveSelectedItems": "선택한 항목 제거", + "Repack": "repack", + "ResetDefinitionTitlesHelpText": "정의 제목과 값을 초기화하세요", + "ResetDefinitions": "정의 초기화", + "ScrollMovies": "영화 스크롤", + "SearchForAllMissingMovies": "모든 누락된 영화 검색", + "SearchForAllMissingMoviesConfirmationCount": "{totalRecords}개의 누락된 영화를 모두 검색하시겠습니까?", + "SearchForCutoffUnmetMovies": "모든 조건 미충족 영화 검색", + "SecretToken": "비밀 토큰", + "SetReleaseGroupModalTitle": "{modalTitle} - 출시 그룹 설정", + "ShowOverview": "개요 보기", + "ShowPhysicalRelease": "실제 출시일 표시", + "ShowPhysicalReleaseHelpText": "포스터 아래에 실제 출시일 표시", + "ShowTagsHelpText": "포스터 아래에 태그 표시", + "ShowTmdbRating": "TMDb 평점 보기", + "ShowTmdbRatingHelpText": "포스터 아래에 TMDb 평점 표시", + "ShowTraktRating": "Trakt 평점 보기", + "ShowTraktRatingPosterHelpText": "포스터 아래에 Trakt 등급 표시", + "Started": "시작됨", + "TodayAt": "오늘 {time}", + "ToggleMonitoredToUnmonitored": "모니터링 설정, 모니터링을 해제하려면 클릭하세요", + "Umask": "U마스크", + "UnableToImportAutomatically": "자동으로 가져올 수 없습니다", + "UnableToLoadCollections": "컬렉션을 로드할 수 없습니다", + "Underscore": "밑줄", + "Unknown": "알 수 없음", + "UnknownDownloadState": "알 수 없는 다운로드 상태: {state}", + "WantMoreControlAddACustomFormat": "어떤 다운로드를 선호하는지에 대한 더 많은 제어를 원하십니까? [사용자 정의 형식](/settings/customformats)을 추가하세요.", + "NotificationsPushBulletSettingsAccessToken": "액세스 토큰", + "DownloadClientDelugeSettingsDirectory": "다운로드 디렉토리", + "Complete": "완료", + "Completed": "완료됨", + "AutoRedownloadFailedFromInteractiveSearch": "상호작용 검색에서 재다운로드를 실패함", + "CutoffNotMet": "조건 미충족", + "MatchedToMovie": "영화와 매치됨", + "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "새 비밀번호 확인", + "AuthenticationRequiredUsernameHelpTextWarning": "새 사용자이름을 입력하세요", + "DownloadClientDownloadStationValidationFolderMissing": "폴더가 존재하지 않습니다", + "NotificationsKodiSettingsUpdateLibraryHelpText": "가져오기 및 이름 바꾸기에서 라이브러리를 업데이트하시겠습니까?", + "DownloadClientRTorrentSettingsAddStoppedHelpText": "활성화하면 rTorrent에 정지된 상태에서 토런트와 마그넷이 추가됩니다. 마그넷 파일이 손상될 수 있습니다.", + "DownloadClientSabnzbdValidationCheckBeforeDownloadDetail": "'다운로드 전 확인'을 사용하면 {appName}의 새로운 다운로드 추적 기능에 영향을 미칩니다. 또한 Sabnzbd는 '완료할 수 없는 작업 중단'을 대신 권장하는데, 이는 더 효과적이기 때문입니다.", + "DownloadClientSabnzbdValidationDevelopVersion": "Sabnzbd는 버전 3.0.0 이상을 가정하고 개발 버전을 개발했습니다.", + "DownloadClientSabnzbdValidationEnableDisableMovieSorting": "영화 정렬 비활성화", + "DownloadClientSabnzbdValidationEnableJobFoldersDetail": "{appName}은 각 다운로드에 별도의 폴더가 있는 것을 선호합니다. 폴더/경로에 *를 추가하면 Sabnzbd는 이러한 작업 폴더를 생성하지 않습니다. Sabnzbd로 이동하여 수정하세요.", + "FormatAgeDay": "일", + "MovieGrabbedTooltip": "{indexer}에서 영화를 가져와 {downloadClient}로 보냈습니다.", + "MovieImportedTooltip": "영화가 성공적으로 다운로드되어 다운로드 클라이언트에서 선택되었습니다.", + "NotificationsJoinSettingsNotificationPriority": "알림 우선순위", + "NotificationsJoinValidationInvalidDeviceId": "장치 ID가 유효하지 않습니다.", + "NotificationsSendGridSettingsApiKeyHelpText": "SendGrid에서 생성된 API 키", + "ShowDigitalRelease": "디지털 출시일 표시", + "AnnouncedMovieDescription": "영화가 발표되었습니다", + "AuthenticationRequired": "인증 필수", + "AuthenticationRequiredPasswordHelpTextWarning": "새 비밀번호를 입력하세요", + "AutoTaggingLoadError": "자동 태그 지정을 로드할 수 없음", + "BlackholeWatchFolder": "감시 폴더", + "DeleteMovieFolderMovieCount": "{movieFileCount}개의 영화 파일 총 크기 {size}", + "Destination": "대상", + "DownloadClientQbittorrentTorrentStateStalled": "다운로드가 연결되지 않아 중단되었습니다.", + "DownloadClientRTorrentSettingsDirectoryHelpText": "다운로드를 넣을 선택 위치, 기본 rTorrent 위치를 사용하려면 비워두세요.", + "DownloadIgnored": "다운로드 무시됨", + "EditCollection": "컬렉션 편집", + "EditImportListImplementation": "가져오기 목록 편집 - {implementationName}", + "NoHistoryFound": "기록이 발견되지 않았습니다", + "NotificationsPushoverSettingsRetryHelpText": "비상 경보 재시도 간격, 최소 30초", + "Recommendation": "권장사항", + "IncludePopular": "인기 있는 것을 포함하세요", + "IncludePopularMoviesHelpText": "TMDb에서 인기 영화를 포함하세요", + "NotificationsSettingsUpdateLibrary": "라이브러리 업데이트", + "NotificationsSignalSettingsGroupIdPhoneNumber": "그룹 ID / 전화 번호", + "Recommended": "추천", + "WhySearchesCouldBeFailing": "검색이 실패하는 이유를 알아보려면 여기를 클릭하세요", + "BlackholeFolderHelpText": "{appName}이(가) {extension} 파일을 저장할 폴더", + "AutoTaggingRequiredHelpText": "이 {implementationName} 조건은 자동 태그 지정 규칙이 적용되도록 일치해야 합니다. 그렇지 않으면 단일 {implementationName} 일치로 충분합니다.", + "ChangeCategoryMultipleHint": "다운로드 클라이언트에서 다운로드를 '가져오기 이후 카테고리'로 변경", + "BlackholeWatchFolderHelpText": "{appName}이(가) 완료된 다운로드를 가져와야 하는 폴더", + "RefreshCollections": "컬렉션 새로고침", + "BlocklistOnlyHint": "대체 항목을 검색하지 않고 차단 목록에 추가", + "ChangeCategory": "카테고리 변경", + "CountCollectionsSelected": "{count}개의 컬렉션을 선택함", + "CountVotes": "{votes}표", + "CustomFormatsSpecificationExceptLanguage": "언어 제외", + "CustomFormatsSpecificationRegularExpression": "일반 표현", + "CustomFormatsSpecificationResolution": "해상도", + "Database": "데이터베이스", + "Default": "기본값", + "DeleteSelected": "선택된 것을 삭제", + "Directory": "디렉토리", + "Donate": "기부하기", + "DownloadClientDelugeValidationLabelPluginInactiveDetail": "카테고리를 사용하려면 {clientName}에서 라벨 플러그인을 활성화해야 합니다.", + "DownloadClientDownloadStationSettingsDirectoryHelpText": "다운로드를 넣을 공유 폴더(선택 사항). 기본 다운로드 스테이션 위치를 사용하려면 비워두세요.", + "DownloadClientDownloadStationValidationApiVersion": "다운로드 스테이션 API 버전이 지원되지 않습니다. 최소한 {requiredVersion} 이상이어야 합니다. {minVersion}에서 {maxVersion}까지 지원합니다.", + "DownloadClientDownloadStationValidationFolderMissingDetail": "'{downloadDir}' 폴더가 존재하지 않습니다. 공유 폴더 '{sharedFolder}' 내에 수동으로 만들어야 합니다.", + "DownloadClientDownloadStationValidationNoDefaultDestinationDetail": "{username} 사용자로 Diskstation에 로그인한 후 BT/HTTP/FTP/NZB -> 위치에서 DownloadStation 설정에서 수동으로 설정해야 합니다.", + "DownloadClientDownloadStationValidationSharedFolderMissing": "공유 폴더가 존재하지 않습니다", + "DownloadClientFloodSettingsAdditionalTagsHelpText": "미디어의 속성을 태그로 추가합니다. 힌트는 예시입니다.", + "DownloadClientFloodSettingsPostImportTags": "수입 후 태그", + "DownloadClientFloodSettingsAddPaused": "일시 중지 추가", + "DownloadClientFloodSettingsAdditionalTags": "추가 태그", + "DownloadClientFloodSettingsPostImportTagsHelpText": "다운로드를 가져온 후에 태그를 추가합니다.", + "DownloadClientFloodSettingsRemovalInfo": "{appName}은 설정 -> 인덱서의 현재 시드 기준에 따라 토런트를 자동으로 제거합니다.", + "DownloadClientFloodSettingsStartOnAdd": "추가에서 시작", + "DownloadClientFreeboxApiError": "Freebox API가 오류를 반환했습니다: {errorDescription}", + "DownloadClientFreeboxAuthenticationError": "Freebox API에 대한 인증이 실패했습니다. 이유: {errorDescription}", + "DownloadClientFloodSettingsTagsHelpText": "다운로드의 초기 태그. 인식되려면 다운로드에 모든 초기 태그가 있어야 합니다. 이렇게 하면 관련 없는 다운로드와의 충돌을 피할 수 있습니다.", + "DownloadClientFloodSettingsUrlBaseHelpText": "{url}와 같은 Flood API에 접두사를 추가합니다.", + "DownloadClientFreeboxNotLoggedIn": "사용자가 로그인했습니다", + "DownloadClientFreeboxSettingsApiUrl": "API 주소", + "DownloadClientFreeboxSettingsApiUrlHelpText": "API 버전을 사용하여 Freebox API 기본 URL을 정의합니다(예: '{url}', 기본값은 '{defaultApiUrl}').", + "DownloadClientFreeboxSettingsAppId": "앱 ID", + "DownloadClientFreeboxSettingsAppToken": "App 토큰", + "DownloadClientFreeboxSettingsAppIdHelpText": "Freebox API에 대한 액세스를 생성할 때 제공된 앱 ID(예: 'app_id')", + "DownloadClientFreeboxSettingsPortHelpText": "Freebox 인터페이스에 액세스하는 데 사용되는 포트, 기본값은 '{port}'입니다.", + "DownloadClientFreeboxSettingsAppTokenHelpText": "Freebox API에 대한 액세스를 생성할 때 앱 토큰이 검색됨(예: 'app_token')", + "DownloadClientFreeboxSettingsHostHelpText": "Freebox의 호스트 이름 또는 호스트 IP 주소, 기본값은 '{url}'입니다(동일한 네트워크에 있는 경우에만 작동함)", + "DownloadClientMovieTagHelpText": "이 다운로드 클라이언트는 적어도 하나의 일치하는 태그가 있는 영화에만 사용하세요. 모든 영화에 사용하려면 비워두세요.", + "DownloadClientNzbgetSettingsAddPausedHelpText": "이 옵션을 사용하려면 최소한 NzbGet 버전 16.0이 필요합니다.", + "DownloadClientNzbVortexMultipleFilesMessage": "다운로드에 여러 파일이 포함되어 있으며 작업 폴더에 없습니다: {outputPath}", + "DownloadClientNzbgetValidationKeepHistoryOverMaxDetail": "NzbGet 설정 KeepHistory가 너무 높게 설정되었습니다.", + "DownloadClientNzbgetValidationKeepHistoryZero": "NzbGet 설정 KeepHistory는 0보다 커야 합니다.", + "DownloadClientPneumaticSettingsNzbFolderHelpText": "이 폴더는 XBMC에서 접근할 수 있어야 합니다.", + "DownloadClientPneumaticSettingsStrmFolder": "Strm 폴더", + "DownloadClientPneumaticSettingsStrmFolderHelpText": "이 폴더의 .strm 파일은 드론으로 가져옵니다.", + "DownloadClientPriorityHelpText": "클라이언트 우선 순위를 1(가장 높음)에서 50(가장 낮음)까지 다운로드합니다. 기본값: 1. 라운드 로빈은 동일한 우선 순위를 가진 클라이언트에 사용됩니다.", + "DownloadClientQbittorrentSettingsContentLayout": "콘텐츠 레이아웃", + "DownloadClientQbittorrentSettingsFirstAndLastFirst": "이름과 성 이름", + "DownloadClientQbittorrentSettingsContentLayoutHelpText": "qBittorrent의 구성된 콘텐츠 레이아웃을 사용할지, 토런트의 원래 레이아웃을 사용할지, 항상 하위 폴더를 생성할지(qBittorrent 4.3.2+)", + "DownloadClientQbittorrentSettingsFirstAndLastFirstHelpText": "첫 번째와 마지막 부분을 먼저 다운로드하세요(qBittorrent 4.1.0+)", + "DownloadClientQbittorrentSettingsInitialStateHelpText": "qBittorrent에 추가된 토렌트의 초기 상태입니다. 강제 토렌트는 시드 제한을 따르지 않는다는 점에 유의하세요.", + "DownloadClientQbittorrentSettingsSequentialOrderHelpText": "순차적으로 다운로드 (qBittorrent 4.1.0+)", + "DownloadClientQbittorrentSettingsUseSslHelpText": "보안 연결을 사용하세요. qBittorrent에서 옵션 -> 웹 UI -> 'HTTP 대신 HTTPS 사용'을 참조하세요.", + "DownloadClientQbittorrentTorrentStateMetadata": "qBittorrent가 메타데이터를 다운로드하고 있습니다", + "DownloadClientQbittorrentTorrentStateError": "qBittorrent에서 오류가 보고되었습니다", + "DownloadClientQbittorrentTorrentStateMissingFiles": "qBittorrent에서 누락된 파일을 보고합니다.", + "DownloadClientQbittorrentTorrentStateUnknown": "알 수 없는 다운로드 상태: {state}", + "DownloadClientQbittorrentValidationCategoryAddFailure": "카테고리 구성에 실패했습니다", + "DownloadClientQbittorrentValidationCategoryRecommendedDetail": "{appName}은 카테고리 없이 완료된 다운로드를 가져오려고 시도하지 않습니다.", + "DownloadClientQbittorrentValidationCategoryUnsupported": "카테고리가 지원되지 않습니다.", + "DownloadClientQbittorrentValidationQueueingNotEnabled": "대기열이 활성화되지 않음", + "DownloadClientQbittorrentValidationRemovesAtRatioLimit": "qBittorrent는 토런트가 공유 비율 한도에 도달하면 토런트를 제거하도록 구성되어 있습니다.", + "DownloadClientQbittorrentValidationQueueingNotEnabledDetail": "토런트 큐잉이 qBittorrent 설정에서 활성화되어 있지 않습니다. qBittorrent에서 활성화하거나 우선순위로 '마지막'을 선택하세요.", + "DownloadClientRTorrentProviderMessage": "rTorrent는 시드 기준을 충족할 때 토런트를 일시 중지하지 않습니다. {appName}은 Remove Completed가 활성화된 경우에만 설정->인덱서에서 현재 시드 기준에 따라 토런트를 자동으로 제거합니다. 가져온 후에는 {importedView}을 rTorrent 뷰로 설정하여 rTorrent 스크립트에서 동작을 사용자 정의하는 데 사용할 수 있습니다.", + "DownloadClientRTorrentSettingsAddStopped": "중지됨 추가", + "DownloadClientRTorrentSettingsUrlPath": "URL 경로", + "DownloadClientRTorrentSettingsUrlPathHelpText": "XMLRPC 엔드포인트 경로, {url} 참조. ruTorrent를 사용할 때 이는 일반적으로 RPC2 또는 [ruTorrent 경로]{url2}입니다.", + "DownloadClientSabnzbdValidationCheckBeforeDownload": "Sabnbzd에서 '다운로드 전 확인' 옵션 비활성화", + "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "다운로드 클라이언트 {downloadClientName}이 완료된 다운로드를 제거하도록 설정되어 있습니다. 이로 인해 {appName}이 가져오기 전에 클라이언트에서 다운로드가 제거될 수 있습니다.", + "DownloadClientSabnzbdValidationDevelopVersionDetail": "{appName}은 개발 버전을 실행할 때 SABnzbd에 추가된 새로운 기능을 지원하지 못할 수 있습니다.", + "DownloadClientSabnzbdValidationEnableDisableDateSorting": "날짜 정렬 비활성화", + "DownloadClientSabnzbdValidationEnableDisableDateSortingDetail": "가져오기 문제를 방지하려면 카테고리 {appName}에 대한 날짜 정렬을 비활성화해야 합니다. 수정하려면 Sabnzbd로 이동하세요.", + "DownloadClientSabnzbdValidationEnableDisableMovieSortingDetail": "가져오기 문제를 방지하려면 카테고리 {appName}에 대한 영화 정렬을 비활성화해야 합니다. 수정하려면 Sabnzbd로 이동하세요.", + "DownloadClientSabnzbdValidationEnableDisableTvSorting": "TV 정렬 비활성화", + "DownloadClientSabnzbdValidationEnableDisableTvSortingDetail": "가져오기 문제를 방지하려면 카테고리 {appName}에 대한 TV 정렬을 비활성화해야 합니다. 수정하려면 Sabnzbd로 이동하세요.", + "DownloadClientSabnzbdValidationEnableJobFolders": "작업 폴더 활성화", + "DownloadClientSabnzbdValidationUnknownVersion": "알 수 없는 버전: {rawVersion}", + "DownloadClientSettingsAddPaused": "일시 중지 추가", + "DownloadClientSettingsCategorySubFolderHelpText": "{appName}에 대한 특정 카테고리를 추가하면 관련 없는 비{appName} 다운로드와의 충돌을 피할 수 있습니다. 카테고리 사용은 선택 사항이지만 강력히 권장됩니다. 출력 디렉토리에 [카테고리] 하위 디렉토리를 만듭니다.", + "DownloadClientSettingsCategoryHelpText": "{appName}에 대한 특정 카테고리를 추가하면 관련 없는 비{appName} 다운로드와의 충돌을 피할 수 있습니다. 카테고리 사용은 선택 사항이지만 강력히 권장됩니다.", + "DownloadClientSettingsDestinationHelpText": "다운로드 대상을 수동으로 지정하고 기본값을 사용하려면 비워두세요.", + "DownloadClientSettingsInitialState": "초기 상태", + "DownloadClientSettingsInitialStateHelpText": "{clientName}에 추가된 토런트의 초기 상태", + "DownloadClientSettingsOlderPriority": "이전 우선 순위", + "DownloadClientSettingsOlderPriorityMovieHelpText": "21일 이상 방영된 영화를 잡을 때 우선적으로 사용 가능", + "DownloadClientSettingsPostImportCategoryHelpText": "다운로드를 가져온 후 {appName}에 대한 카테고리를 설정합니다. {appName}은 시딩이 완료되었더라도 해당 카테고리의 토런트를 제거하지 않습니다. 같은 카테고리를 유지하려면 비워두세요.", + "DownloadClientSettingsRecentPriorityMovieHelpText": "최근 21일 이내 방영된 영화를 잡을 때 우선적으로 사용 가능", + "DownloadClientTransmissionSettingsDirectoryHelpText": "다운로드를 넣을 선택 위치입니다. 기본 전송 위치를 사용하려면 비워두세요.", + "DownloadClientSettingsUrlBaseHelpText": "{clientName} url에 {url}과 같은 접두사를 추가합니다.", + "DownloadClientValidationApiKeyRequired": "API 키가 필요합니다", + "DownloadClientValidationAuthenticationFailure": "인증 실패", + "DownloadClientValidationAuthenticationFailureDetail": "사용자 이름과 비밀번호를 확인하세요. 또한 {appName}을 실행하는 호스트가 {clientName} 구성의 WhiteList 제한으로 {clientName}에 액세스하는 것이 차단되지 않았는지 확인하세요.", + "DownloadClientTransmissionSettingsUrlBaseHelpText": "{clientName} rpc URL에 접두사를 추가합니다(예: {url}, 기본값은 '{defaultUrl}').", + "DownloadClientUTorrentTorrentStateError": "uTorrent에서 오류가 보고되었습니다", + "DownloadClientValidationApiKeyIncorrect": "API 키가 올바르지 않습니다", + "DownloadClientValidationCategoryMissing": "카테고리가 존재하지 않습니다", + "DownloadClientValidationCategoryMissingDetail": "입력하신 카테고리는 {clientName}에 존재하지 않습니다. 먼저 {clientName}에 만드세요.", + "DownloadClientValidationErrorVersion": "{clientName} 버전은 최소한 {requiredVersion}이어야 합니다. 보고된 버전은 {reportedVersion}입니다.", + "DownloadClientValidationGroupMissing": "그룹이 존재하지 않습니다", + "DownloadClientValidationGroupMissingDetail": "입력한 그룹은 {clientName}에 존재하지 않습니다. 먼저 {clientName}에 만드세요.", + "DownloadClientValidationSslConnectFailure": "SSL을 통해 연결할 수 없습니다", + "DownloadClientValidationTestNzbs": "NZB 목록을 가져오지 못했습니다: {exceptionMessage}", + "DownloadClientValidationTestTorrents": "토런트 목록을 가져오지 못했습니다: {exceptionMessage}", + "DownloadClientValidationUnableToConnectDetail": "호스트 이름과 포트를 확인해 주세요.", + "DownloadClientValidationUnknownException": "알 수 없는 예외: {exception}", + "DownloadClientValidationVerifySsl": "SSL 설정 확인", + "DownloadClientValidationVerifySslDetail": "{clientName} 및 {appName} 모두에서 SSL 구성을 확인해 주세요.", + "DownloadFailedMovieTooltip": "영화 다운로드 실패", + "DownloadIgnoredMovieTooltip": "영화 다운로드 무시됨", + "DownloadClientVuzeValidationErrorVersion": "프로토콜 버전이 지원되지 않습니다. Vuze Web Remote 플러그인과 함께 Vuze 5.0.0.0 이상을 사용하세요.", + "DownloadStationStatusExtracting": "추출 중: {progress}%", + "Duration": "기간", + "EditAutoTag": "자동 태그 편집", + "EditMetadata": "{metadataType} 메타데이터 편집", + "EditSelectedCustomFormats": "선택한 사용자 정의 형식 편집", + "EditSelectedDownloadClients": "선택한 다운로드 클라이언트 편집", + "EditSelectedImportLists": "선택한 가져오기 목록 편집", + "EditionFootNote": "선택적으로 줄임표(`...`)를 포함한 최대 바이트 수까지 잘라내기를 제어합니다. 끝에서 잘라내기(예: `{Edition Tags:30}`) 또는 시작에서 잘라내기(예: `{Edition Tags:-30}`)가 모두 지원됩니다.", + "EditSelectedIndexers": "선택한 인덱서 편집", + "EnableProfile": "프로필 활성화", + "Example": "예제", + "ExistsInLibrary": "도서관에 존재함", + "External": "외부", + "FailedToUpdateSettings": "설정 업데이트에 실패했습니다", + "Fallback": "폴백", + "False": "거짓", + "FavoriteFolderAdd": "즐겨찾는 폴더 추가", + "FavoriteFolderRemove": "즐겨찾는 폴더 제거", + "FavoriteFolders": "즐겨찾는 폴더", + "FileBrowser": "파일 브라우저", + "FolderNameTokens": "폴더 이름 토큰", + "FormatAgeDays": "일", + "FormatAgeHour": "시간", + "FormatAgeHours": "시간", + "FormatAgeMinutes": "분", + "FormatDateTime": "{formattedDate} {formattedTime}", + "FormatDateTimeRelative": "{relativeDay}, {formattedDate} {formattedTime}", + "FormatRuntimeHours": "{hours}시간", + "FormatRuntimeMinutes": "{minutes}분", + "FormatShortTimeSpanHours": "{hours}시간", + "FormatTimeSpanDays": "{days}d {time}", + "FormatShortTimeSpanMinutes": "{minutes}분", + "FormatShortTimeSpanSeconds": "{seconds}초", + "From": "부터", + "FullColorEvents": "풀 컬러 이벤트", + "FullColorEventsHelpText": "왼쪽 가장자리만 아니라 전체 이벤트를 상태 색상으로 색칠하도록 스타일을 변경했습니다. 일정에는 적용되지 않습니다.", + "OnMovieAdded": "영화 추가됨", + "IMDbId": "IMDb 아이디", + "HourShorthand": "h", + "IgnoreDownload": "다운로드 무시", + "IgnoreDownloadHint": "{appName}이 이 다운로드를 더 이상 처리하지 못하도록 합니다.", + "IgnoreDownloads": "다운로드 무시", + "IgnoreDownloadsHint": "{appName}이(가) 이러한 다운로드를 더 이상 처리하지 않도록 중지합니다.", + "ImdbRating": "IMDb 평점", + "Implementation": "구현", + "ImportListMissingRoot": "가져오기 목록에 대한 루트 폴더가 없습니다: {rootFolderInfo}", + "ImportListMultipleMissingRoots": "가져오기 목록에 여러 개의 루트 폴더가 없습니다: {rootFoldersInfo}", + "ImportScriptPathHelpText": "가져오기에 사용할 스크립트의 경로", + "ImportUsingScript": "스크립트를 사용하여 가져오기", + "ImportUsingScriptHelpText": "스크립트를 사용하여 가져오기 위한 파일 복사(예: 트랜스코딩용)", + "InCinemasMovieAvailabilityDescription": "영화는 극장에 개봉되자마자 바로 볼 수 있는 것으로 간주됩니다.", + "IncludeTrending": "트렌드 포함", + "IncludeTrendingMoviesHelpText": "TMDb에서 인기 있는 영화를 포함합니다", + "IndexerDownloadClientHealthCheckMessage": "잘못된 다운로드 클라이언트가 있는 인덱서: {indexerNames}.", + "IndexerDownloadClientHelpText": "이 인덱서에서 가져온 것을 가져오는 데 사용되는 다운로드 클라이언트를 지정합니다.", + "IndexerSettingsMultiLanguageRelease": "다국어", + "IndexerSettingsSeedRatio": "종자 비율", + "IndexerJackettAll": "지원되지 않는 Jackett 'all' 엔드포인트를 사용하는 인덱서: {indexerNames}", + "IndexerSettingsMultiLanguageReleaseHelpText": "이 인덱서에서는 일반적으로 여러 출시에 어떤 언어가 포함됩니까?", + "IndexerSettingsSeedRatioHelpText": "토런트가 멈추기 전에 도달해야 하는 비율, 비어 있으면 다운로드 클라이언트의 기본값을 사용합니다. 비율은 최소 1.0이어야 하며 인덱서 규칙을 따라야 합니다.", + "IndexerSettingsSeedTime": "파종 시간", + "IndexerTagMovieHelpText": "일치하는 태그가 하나 이상 있는 영화에만 이 인덱서를 사용하세요. 모든 영화에 사용하려면 비워두세요.", + "IndexerSettingsSeedTimeHelpText": "토런트가 중지되기 전에 시드되어야 하는 시간, 비어 있으면 다운로드 클라이언트의 기본값을 사용합니다.", + "InfoUrl": "정보 URL", + "Install": "설치", + "InstallMajorVersionUpdate": "업데이트 설치", + "InstanceName": "인스턴스 이름", + "InstallMajorVersionUpdateMessage": "이 업데이트는 새로운 주요 버전을 설치하며 시스템과 호환되지 않을 수 있습니다. 이 업데이트를 설치하시겠습니까?", + "InstanceNameHelpText": "탭의 인스턴스 이름과 Syslog 앱 이름", + "InteractiveImportLoadError": "수동 가져오기 항목을 로드할 수 없습니다", + "InteractiveImportNoImportMode": "가져오기 모드를 선택해야 합니다.", + "InteractiveImportNoLanguage": "선택한 각 파일에 대해 언어를 선택해야 합니다.", + "InteractiveImportNoMovie": "선택한 각 파일에 대해 영화를 선택해야 합니다.", + "InteractiveImportNoQuality": "선택한 각 파일에 대해 품질을 선택해야 합니다.", + "InvalidMovieInfoLanguageLanguage": "영화 정보 언어가 잘못된 값으로 설정되어 있습니다. 이를 수정하고 설정을 저장하세요.", + "InteractiveSearchModalHeaderTitle": "대화형 검색 - {title}", + "InvalidUILanguage": "UI가 잘못된 언어로 설정되어 있습니다. 이를 수정하고 설정을 저장하세요.", + "Label": "라벨", + "LastSearched": "마지막 검색", + "Letterboxd": "레터박스d", + "LabelIsRequired": "라벨이 필요합니다", + "LanguagesLoadError": "언어를 로드할 수 없습니다", + "ListQualityProfileHelpText": "품질 프로필 목록 항목이 추가됩니다.", + "ListRefreshInterval": "목록 새로고침 간격", + "ListRootFolderHelpText": "루트 폴더 목록 항목이 추가됩니다.", + "ListWillRefreshEveryInterval": "목록은 {refreshInterval}마다 새로 고쳐집니다.", + "Loading": "로딩중", + "LogFilesLocation": "로그 파일은 다음 위치에 있습니다: {location}", + "LogSizeLimit": "로그 크기 제한", + "LogSizeLimitHelpText": "보관 전 최대 로그 파일 크기(MB). 기본값은 1MB입니다.", + "ManageDownloadClients": "다운로드 클라이언트 관리", + "ManageCustomFormats": "사용자 정의 형식 관리", + "ManageFormats": "형식 관리", + "ManageLists": "목록 관리", + "ManageImportLists": "가져오기 목록 관리", + "ManageIndexers": "인덱서 관리", + "MassSearchCancelWarning": "{appName}을 재시작하거나 모든 인덱서를 비활성화하지 않고는 이 작업을 취소할 수 없음", + "Menu": "메뉴", + "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages는 파일 이름에 포함된 언어를 필터링할 수 있는 `:EN+DE` 접미사를 지원합니다. 특정 언어를 제외하려면 `-DE`를 사용합니다. `+`를 추가하면(예: `:EN+`) 제외된 언어에 따라 `[EN]`/`[EN+--]`/`[--]`가 출력됩니다. 예를 들어 `{MediaInfo Full:EN+DE}`.", + "MetadataKometaDeprecated": "Kometa 파일은 더 이상 생성되지 않으며 v6에서는 지원이 완전히 제거됩니다.", + "MetadataKometaDeprecatedSetting": "폐기된", + "MetadataSettingsMovieImages": "영화 이미지", + "MetadataSettingsMovieMetadata": "영화 메타데이터", + "MetadataSettingsMovieMetadataCollectionName": "영화 컬렉션 이름", + "MetadataSettingsMovieMetadataLanguage": "영화 메타데이터 언어", + "MetadataSettingsMovieMetadataUrl": "영화 메타데이터 URL", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": ".nfo에 컬렉션 이름을 포함합니다.", + "MetadataSettingsMovieMetadataNfo": "movie.nfo를 사용하세요", + "MetadataXmbcSettingsMovieMetadataHelpText": "전체 영화 메타데이터가 포함된 .nfo", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": ".nfo에 있는 경우 선택한 언어를 포함합니다.", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "기본 메타데이터 대신 movie.nfo에 메타데이터를 쓰세요 .nfo", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": ".nfo에 TMDb 및 IMDb 영화 URL을 포함합니다.", + "MinimumCustomFormatScoreIncrement": "최소 사용자 정의 형식 점수 증가", + "MissingLoadError": "누락된 항목을 로드하는 중 오류가 발생했습니다.", + "MissingNoItems": "누락된 항목 없음", + "MonitorSelected": "선택된 모니터", + "MonitoredCollectionHelpText": "이 컬렉션의 영화가 자동으로 라이브러리에 추가되도록 모니터링합니다.", + "MovieAndCollection": "영화 및 컬렉션", + "MovieCollectionFolderMultipleMissingRootsHealthCheckMessage": "영화 컬렉션에 대한 여러 루트 폴더가 없습니다: {rootFoldersInfo}", + "MovieFileRenamed": "영화 파일 이름이 변경되었습니다", + "MovieCollectionRootFolderMissingRootHealthCheckMessage": "영화 컬렉션에 대한 루트 폴더가 없습니다: {rootFolderInfo}", + "MovieDownloaded": "영화 다운로드됨", + "MovieFileMissingTooltip": "영화 파일이 없습니다", + "MovieFileRenamedTooltip": "영화 파일 이름이 변경되었습니다", + "MovieFolderFormatHelpText": "새로운 영화를 추가하거나 영화 편집기를 통해 영화를 이동할 때 사용됩니다.", + "MovieFolderImportedTooltip": "영화 폴더에서 가져온 영화", + "MovieFootNote": "선택적으로 줄임표(`...`)를 포함한 최대 바이트 수까지 잘라내기를 제어합니다. 끝에서 잘라내기(예: `{영화 제목:30}`) 또는 시작에서 잘라내기(예: `{영화 제목:-30}`)가 모두 지원됩니다.", + "MovieImported": "영화 수입", + "MovieIsNotAvailable": "영화를 볼 수 없습니다", + "MovieIsNotMonitored": "영화가 모니터링되지 않습니다", + "MovieIsPopular": "이 영화는 TMDb에서 인기가 많습니다", + "MovieIsTrending": "영화가 TMDb에서 트렌드 중입니다", + "MovieMatchType": "영화 매치 유형", + "MovieMissingFromDisk": "디스크에서 영화가 누락되었습니다", + "MovieOnly": "영화만", + "Never": "절대", + "NewNonExcluded": "새로운 제외되지 않음", + "NoBlocklistItems": "차단 목록 항목 없음", + "NoDelay": "유즈넷 지연: {usenetDelay}", + "NoImportListsFound": "수입 목록을 찾을 수 없습니다", + "NoIndexersFound": "인덱서를 찾을 수 없습니다", + "NotificationsAppriseSettingsConfigurationKey": "Apprise 구성 키", + "NotificationsAppriseSettingsConfigurationKeyHelpText": "영구 저장소 솔루션의 구성 키. Stateless URL을 사용하는 경우 비워두세요.", + "NotificationsAppriseSettingsNotificationType": "사전 알림 유형", + "NotificationsAppriseSettingsPasswordHelpText": "HTTP 기본 인증 비밀번호", + "NotificationsAppriseSettingsServerUrl": "Apprise 서버 URL", + "NotificationsAppriseSettingsServerUrlHelpText": "필요한 경우 http(s):// 및 포트를 포함한 Apprise 서버 URL", + "NotificationsAppriseSettingsStatelessUrls": "Apprise Stateless URL", + "NotificationsAppriseSettingsStatelessUrlsHelpText": "알림을 보낼 위치를 식별하는 쉼표로 구분된 하나 이상의 URL. 영구 저장소를 사용하는 경우 비워 둡니다.", + "NotificationsAppriseSettingsTags": "태그 알림", + "NotificationsAppriseSettingsTagsHelpText": "선택적으로 태그가 지정된 사람에게만 알립니다.", + "NotificationsAppriseSettingsUsernameHelpText": "HTTP 기본 인증 사용자 이름", + "NotificationsCustomScriptSettingsArgumentsHelpText": "스크립트에 전달할 인수", + "NotificationsCustomScriptSettingsName": "사용자 정의 스크립트", + "NotificationsCustomScriptValidationFileDoesNotExist": "파일이 존재하지 않습니다", + "NotificationsDiscordSettingsAuthor": "저작자", + "NotificationsDiscordSettingsAuthorHelpText": "이 알림에 표시되는 임베드 작성자를 재정의합니다. 빈칸은 인스턴스 이름입니다.", + "NotificationsDiscordSettingsAvatar": "아바타", + "NotificationsDiscordSettingsAvatarHelpText": "이 통합에서 메시지에 사용되는 아바타를 변경합니다.", + "NotificationsDiscordSettingsOnGrabFields": "그랩 필드에서", + "NotificationsDiscordSettingsOnImportFields": "가져오기 필드에서", + "NotificationsDiscordSettingsOnImportFieldsHelpText": "이 '가져오기 시' 알림에 전달되는 필드를 변경합니다.", + "NotificationsDiscordSettingsOnGrabFieldsHelpText": "이 '잡기' 알림에 전달된 필드를 변경하세요", + "NotificationsDiscordSettingsOnManualInteractionFields": "수동 상호작용 필드에서", + "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "이 '수동 상호작용 시' 알림에 전달되는 필드를 변경합니다.", + "NotificationsDiscordSettingsUsernameHelpText": "게시할 사용자 이름은 기본적으로 Discord 웹훅 기본값으로 설정됩니다.", + "NotificationsDiscordSettingsWebhookUrlHelpText": "Discord 채널 웹훅 url", + "NotificationsEmailSettingsBccAddress": "BCC 주소", + "NotificationsEmailSettingsCcAddress": "CC 주소", + "NotificationsEmailSettingsBccAddressHelpText": "이메일 숨은참조 수신자의 쉼표로 구분된 목록", + "NotificationsEmailSettingsCcAddressHelpText": "이메일 참조 수신자의 쉼표로 구분된 목록", + "NotificationsEmailSettingsFromAddress": "발신주소", + "NotificationsEmailSettingsName": "이메일", + "NotificationsEmailSettingsRecipientAddress": "수신자 주소", + "NotificationsEmailSettingsRecipientAddressHelpText": "이메일 수신자의 쉼표로 구분된 목록", + "NotificationsEmailSettingsServer": "서버", + "NotificationsEmailSettingsServerHelpText": "이메일 서버의 호스트 이름 또는 IP", + "NotificationsEmailSettingsUseEncryption": "암호화 사용", + "NotificationsEmailSettingsUseEncryptionHelpText": "서버에 구성된 경우 암호화를 사용할지, 항상 SSL(포트 465만 해당) 또는 StartTLS(다른 포트)를 통해 암호화를 사용할지, 아니면 암호화를 전혀 사용하지 않을지", + "NotificationsEmbySettingsSendNotifications": "알림 보내기", + "NotificationsEmbySettingsSendNotificationsHelpText": "Emby가 구성된 공급자에게 알림을 보내도록 합니다. Jellyfin에서는 지원되지 않습니다.", + "NotificationsEmbySettingsUpdateLibraryHelpText": "가져오기, 이름 바꾸기 또는 삭제 시 라이브러리 업데이트", + "NotificationsGotifySettingsAppToken": "App 토큰", + "NotificationsGotifySettingIncludeMoviePoster": "영화 포스터 포함", + "NotificationsGotifySettingsAppTokenHelpText": "Gotify에서 생성된 애플리케이션 토큰", + "NotificationsGotifySettingsPreferredMetadataLink": "선호하는 메타데이터 링크", + "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "단일 링크만 지원하는 클라이언트에 대한 메타데이터 링크", + "NotificationsGotifySettingsPriorityHelpText": "알림의 우선순위", + "NotificationsGotifySettingsServer": "고티파이 서버", + "NotificationsJoinSettingsApiKeyHelpText": "가입 계정 설정의 API 키(가입 API 버튼 클릭)", + "NotificationsJoinSettingsDeviceIdsHelpText": "더 이상 사용되지 않음, 대신 장치 이름을 사용하세요. 알림을 보내고 싶은 장치 ID의 쉼표로 구분된 목록입니다. 설정하지 않으면 모든 장치가 알림을 받습니다.", + "NotificationsJoinSettingsDeviceNamesHelpText": "알림을 보내고 싶은 전체 또는 부분 장치 이름의 쉼표로 구분된 목록입니다. 설정하지 않으면 모든 장치가 알림을 받습니다.", + "NotificationsKodiSettingAlwaysUpdate": "항상 업데이트하세요", + "NotificationsKodiSettingAlwaysUpdateHelpText": "동영상이 재생되는 중에도 라이브러리를 업데이트하시겠습니까?", + "NotificationsKodiSettingsCleanLibrary": "깨끗한 도서관", + "NotificationsKodiSettingsCleanLibraryHelpText": "업데이트 후 라이브러리 정리", + "NotificationsKodiSettingsDisplayTimeHelpText": "알림이 표시되는 시간(초)", + "NotificationsMailgunSettingsApiKeyHelpText": "MailGun에서 생성된 API 키", + "NotificationsKodiSettingsGuiNotification": "GUI 알림", + "NotificationsMailgunSettingsSenderDomain": "발신자 도메인", + "NotificationsMailgunSettingsUseEuEndpoint": "EU 엔드포인트 사용", + "NotificationsMailgunSettingsUseEuEndpointHelpText": "EU MailGun 엔드포인트 사용 활성화", + "NotificationsNotifiarrSettingsApiKeyHelpText": "프로필의 API 키", + "NotificationsNtfySettingsAccessToken": "액세스 토큰", + "NotificationsNtfySettingsClickUrl": "URL을 클릭하세요", + "NotificationsNtfySettingsAccessTokenHelpText": "선택적인 토큰 기반 인증. 사용자 이름/암호보다 우선합니다.", + "NotificationsNtfySettingsClickUrlHelpText": "사용자가 알림을 클릭할 때의 선택 링크", + "NotificationsNtfySettingsPasswordHelpText": "선택 비밀번호", + "NotificationsNtfySettingsServerUrl": "서버 URL", + "NotificationsNtfySettingsServerUrlHelpText": "공개 서버({url})를 사용하려면 비워두세요.", + "NotificationsNtfySettingsTagsEmojis": "Ntfy 태그 및 이모티콘", + "NotificationsNtfySettingsTagsEmojisHelpText": "사용할 태그 또는 이모티콘의 선택 목록", + "NotificationsNtfySettingsTopics": "주제", + "NotificationsNtfySettingsTopicsHelpText": "알림을 보낼 주제 목록", + "NotificationsNtfySettingsUsernameHelpText": "선택 사용자 이름", + "NotificationsNtfyValidationAuthorizationRequired": "승인이 필요합니다", + "NotificationsPlexSettingsAuthToken": "인증 토큰", + "NotificationsPlexSettingsAuthenticateWithPlexTv": "Plex.tv로 인증하세요", + "NotificationsPlexSettingsServer": "서버", + "NotificationsPlexSettingsServerHelpText": "인증 후 plex.tv 계정에서 서버를 선택하세요", + "NotificationsPlexValidationNoMovieLibraryFound": "최소한 하나의 영화 라이브러리가 필요합니다", + "NotificationsPushBulletSettingSenderId": "발신자 ID", + "NotificationsPushBulletSettingSenderIdHelpText": "알림을 보낼 장치 ID는 pushbullet.com의 장치 URL에 device_iden을 사용합니다(자신에게서 보내려면 비워두세요)", + "NotificationsPushBulletSettingsChannelTags": "채널 태그", + "NotificationsPushBulletSettingsChannelTagsHelpText": "알림을 보낼 채널 태그 목록", + "NotificationsPushBulletSettingsDeviceIds": "장치 ID", + "NotificationsPushBulletSettingsDeviceIdsHelpText": "장치 ID 목록(모든 장치로 보내려면 비워두세요)", + "NotificationsPushcutSettingsApiKeyHelpText": "API 키는 Pushcut 앱의 계정 보기에서 관리할 수 있습니다.", + "NotificationsPushcutSettingsNotificationName": "알림 이름", + "NotificationsPushcutSettingsNotificationNameHelpText": "Pushcut 앱의 알림 탭에서 알림 이름", + "NotificationsPushcutSettingsTimeSensitive": "시간에 민감한", + "NotificationsPushcutSettingsTimeSensitiveHelpText": "알림을 \"시간 제한\"으로 표시하도록 설정", + "NotificationsPushoverSettingsDevices": "장치", + "NotificationsPushoverSettingsDevicesHelpText": "장치 이름 목록 (모든 장치로 보내려면 비워두세요)", + "NotificationsPushoverSettingsExpire": "만료", + "NotificationsPushoverSettingsSound": "소리", + "NotificationsPushoverSettingsExpireHelpText": "비상 경보 재시도 최대 시간, 최대 86400초\"", + "NotificationsPushoverSettingsRetry": "재시도", + "NotificationsPushoverSettingsSoundHelpText": "알림음, 기본값을 사용하려면 비워두세요.", + "NotificationsPushoverSettingsUserKey": "SecretKey", + "NotificationsSettingsUpdateMapPathsFrom": "지도 경로", + "NotificationsSettingsUpdateMapPathsTo": "지도 경로", + "NotificationsSettingsUseSslHelpText": "HTTP 대신 HTTPS를 통해 {serviceName}에 연결", + "NotificationsSettingsWebhookHeaders": "헤더", + "NotificationsSettingsWebhookMethod": "방법", + "NotificationsSettingsWebhookMethodHelpText": "웹 서비스에 제출할 때 사용할 HTTP 메서드는 무엇입니까?", + "NotificationsSettingsWebhookUrl": "Webhook URL", + "NotificationsSignalSettingsGroupIdPhoneNumberHelpText": "수신자의 그룹 ID / 전화번호", + "NotificationsSignalSettingsPasswordHelpText": "signal-api에 대한 요청을 인증하는 데 사용되는 비밀번호", + "NotificationsSignalSettingsSenderNumberHelpText": "signal-api에 등록된 발신자 전화번호", + "NotificationsSignalSettingsUsernameHelpText": "signal-api에 대한 요청을 인증하는 데 사용되는 사용자 이름", + "NotificationsSignalValidationSslRequired": "SSL이 필요한 것 같습니다", + "NotificationsSimplepushSettingsKey": "키", + "NotificationsSlackSettingsChannel": "채널", + "NotificationsSlackSettingsChannelHelpText": "수신 웹훅에 대한 기본 채널을 재정의합니다(#other-channel)", + "NotificationsSlackSettingsIcon": "아이콘", + "NotificationsSlackSettingsIconHelpText": "Slack에 게시된 메시지에 사용되는 아이콘(이모티콘 또는 URL)을 변경합니다.", + "NotificationsSlackSettingsUsernameHelpText": "Slack에 게시할 사용자 이름", + "NotificationsSlackSettingsWebhookUrlHelpText": "Slack 채널 웹훅 URL", + "NotificationsSynologySettingsUpdateLibraryHelpText": "로컬호스트에서 synoindex를 호출하여 라이브러리 파일을 업데이트합니다.", + "NotificationsSynologyValidationInvalidOs": "Synology이어야 합니다", + "NotificationsTagsMovieHelpText": "최소한 하나의 일치하는 태그가 있는 영화에 대해서만 알림을 보내세요.", + "NotificationsTelegramSettingsBotToken": "봇 토큰", + "NotificationsTelegramSettingsChatId": "채팅 ID", + "NotificationsTelegramSettingsChatIdHelpText": "메시지를 받으려면 봇과 대화를 시작하거나 봇을 그룹에 추가해야 합니다.", + "NotificationsTelegramSettingsIncludeAppName": "제목에 {appName}을 포함하세요", + "NotificationsTelegramSettingsIncludeAppNameHelpText": "선택적으로 다른 애플리케이션의 알림을 구분하기 위해 메시지 제목 앞에 {appName}을 접두사로 사용합니다.", + "NotificationsTelegramSettingsIncludeInstanceName": "제목에 인스턴스 이름 포함", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "선택적으로 알림에 인스턴스 이름을 포함합니다.", + "NotificationsTelegramSettingsMetadataLinks": "메타데이터 링크", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "알림을 보낼 때 영화 메타데이터에 대한 링크를 추가합니다.", + "NotificationsTelegramSettingsSendSilently": "조용히 보내기", + "NotificationsTelegramSettingsSendSilentlyHelpText": "메시지를 소리 없이 보냅니다. 사용자는 소리 없이 알림을 받게 됩니다.", + "NotificationsTelegramSettingsTopicId": "주제 ID", + "NotificationsTelegramSettingsTopicIdHelpText": "해당 주제로 알림을 보내려면 주제 ID를 지정하세요. 일반 주제를 사용하려면 비워두세요(슈퍼그룹 전용)", + "NotificationsTraktSettingsAccessToken": "액세스 토큰", + "NotificationsTraktSettingsAuthenticateWithTrakt": "Trakt로 인증하기", + "NotificationsTraktSettingsAuthUser": "인증 사용자", + "NotificationsTraktSettingsExpires": "만료", + "NotificationsTraktSettingsRefreshToken": "토큰 새로고침", + "NotificationsTwitterSettingsAccessToken": "액세스 토큰", + "NotificationsTwitterSettingsAccessTokenSecret": "액세스 토큰 비밀", + "NotificationsTwitterSettingsConnectToTwitter": "트위터에 연결 / X", + "NotificationsTwitterSettingsConsumerKey": "고객 키", + "NotificationsTwitterSettingsConsumerKeyHelpText": "Twitter 애플리케이션의 소비자 키", + "NotificationsTwitterSettingsConsumerSecret": "소비자 비밀", + "NotificationsTwitterSettingsConsumerSecretHelpText": "Twitter 애플리케이션의 소비자 비밀", + "NotificationsTwitterSettingsDirectMessage": "다이렉트 메시지", + "NotificationsTwitterSettingsDirectMessageHelpText": "공개 메시지 대신 직접 메시지를 보내세요", + "NotificationsTwitterSettingsMention": "멘션(언급)", + "NotificationsValidationInvalidAccessToken": "액세스 토큰이 잘못되었습니다", + "NotificationsValidationInvalidApiKey": "API 키가 잘못되었습니다", + "NotificationsValidationInvalidApiKeyExceptionMessage": "API 키가 잘못되었습니다: {exceptionMessage}", + "NotificationsValidationInvalidAuthenticationToken": "인증 토큰이 잘못되었습니다.", + "NotificationsValidationInvalidHttpCredentials": "HTTP 인증 자격 증명이 잘못되었습니다: {exceptionMessage}", + "NotificationsValidationInvalidUsernamePassword": "유효하지 않은 사용자 이름 또는 암호입니다", + "NotificationsValidationUnableToConnect": "연결할 수 없습니다: {exceptionMessage}", + "NotificationsValidationUnableToSendTestMessage": "테스트 메시지를 보낼 수 없습니다: {exceptionMessage}", + "NzbgetHistoryItemMessage": "PAR 상태: {parStatus} - 압축 해제 상태: {unpackStatus} - 이동 상태: {moveStatus} - 스크립트 상태: {scriptStatus} - 삭제 상태: {deleteStatus} - 표시 상태: {markStatus}", + "OnFileImport": "파일 가져오기", + "OnApplicationUpdate": "신청 업데이트", + "OnExcludedList": "제외 목록에", + "OnFileUpgrade": "파일 업그레이드", + "OnHealthRestored": "건강 회복에 관하여", + "OnManualInteractionRequired": "수동 상호 작용이 필요합니다", + "OnManualInteractionRequiredHelpText": "수동 상호 작용이 필요합니다", + "OptionalName": "선택 이름", + "Or": "또는", + "OrganizeModalHeader": "정리 및 이름 변경", + "OrganizeNamingPattern": "명명 패턴: `{standardMovieFormat}`", + "OrganizeRelativePaths": "모든 경로는 `{path}`를 기준으로 합니다.", + "OriginalTitle": "원제목", + "OriginalLanguage": "원어", + "OverrideAndAddToDownloadQueue": "재정의하고 다운로드 대기열에 추가", + "OverrideGrabModalTitle": "오버라이드 및 그랩 - {title}", + "OverrideGrabNoLanguage": "최소한 하나의 언어를 선택해야 합니다.", + "OverrideGrabNoMovie": "영화를 선택해야 합니다", + "OverrideGrabNoQuality": "품질을 선택해야 합니다", + "PackageVersionInfo": "{packageVersion} by {packageAuthor}", + "Parse": "파스하다", + "PasswordConfirmation": "비밀번호 확인", + "Popular": "인기", + "Period": "기간", + "Popularity": "인기", + "PopularityIndex": "현재 인기 지수", + "PostImportCategory": "수입 후 카테고리", + "PreferProtocol": "{preferredProtocol}을 선호합니다", + "PreferredProtocol": "선호 프로토콜", + "PreviouslyInstalled": "이전에 설치됨", + "QualityCutoffNotMet": "품질 기준이 충족되지 않았습니다.", + "RefreshMonitoredIntervalHelpText": "다운로드 클라이언트에서 모니터링된 다운로드를 새로 고칠 빈도(최소 1분)", + "RegularExpressionsTutorialLink": "정규 표현식에 대한 상세 내용은 [여기]({url})에서 확인할 수 있습니다.", + "Release": "출시", + "ReleaseGroupFootNote": "선택적으로 줄임표(`...`)를 포함한 최대 바이트 수까지 잘라내기를 제어합니다. 끝(예: `{Release Group:30}`) 또는 시작(예: `{Release Group:-30}`)에서 잘라내기가 모두 지원됩니다.", + "ReleaseHash": "출시 해시", + "ResetQualityDefinitions": "품질 정의 초기화", + "ResetQualityDefinitionsMessageText": "품질 정의를 초기화하시겠습니까?", + "RestartRequiredToApplyChanges": "{appName}의 변경 사항을 적용하려면 재시작이 필요합니다. 지금 재시작하시겠습니까?", + "RestartRequiredWindowsService": "{appName} 서비스를 실행하는 사용자에 따라 서비스가 자동으로 시작되기 전에 {appName}을 관리자 권한으로 한 번 재시작해야 할 수도 있습니다.", + "RootFolderPath": "루트 폴더 경로", + "RottenTomatoesRating": "Tomato 평점", + "SearchForCutoffUnmetMoviesConfirmationCount": "{totalRecords}개의 조건 미충족 영화를 모두 검색하시겠습니까?", + "SearchMoviesConfirmationMessageText": "정말로 {count}개의 영화에 대한 검색을 실행하시겠습니까?", + "SearchMoviesOnAdd": "추가 시 영화 검색", + "SelectDownloadClientModalTitle": "{modalTitle} - 다운로드 클라이언트 선택", + "SelectFolderModalTitle": "{modalTitle} - 폴더 선택", + "SelectIndexerFlags": "인덱서 플래그 선택", + "SelectLanguageModalTitle": "{modalTitle} - 언어 선택", + "SelectReleaseGroup": "출시 그룹 선택", + "SetIndexerFlags": "인덱서 플래그 설정", + "SetIndexerFlagsModalTitle": "{modalTitle} - 인덱서 플래그 설정", + "SetReleaseGroup": "출시 그룹 설정", + "ShowCinemaReleaseHelpText": "포스터 아래에 영화 개봉일 표시", + "ShowDigitalReleaseHelpText": "포스터 아래에 디지털 출시일 표시", + "ShowCollectionDetails": "컬렉션 상태 표시", + "ShowImdbRating": "IMDb 평점 표시", + "ShowImdbRatingHelpText": "포스터 아래에 IMDb 평점 표시", + "ShowPosters": "포스터 표시", + "ShowRottenTomatoesRating": "Tomato 평점 보기", + "ShowRottenTomatoesRatingHelpText": "포스터 아래에 Tomato 평점 표시", + "ShowTags": "태그 표시", + "SizeLimit": "크기 제한", + "SkipRedownload": "재다운로드 건너뛰기", + "SmartReplace": "지능형 바꾸기", + "SmartReplaceHint": "이름에 따라 대시 또는 띄어쓰고 대시", + "SubtitleLanguages": "자막 언어", + "SupportedAutoTaggingProperties": "{appName}은(는) 자동 태그 지정 규칙에 대한 다음 속성을 지원합니다", + "TableOptionsButton": "표 옵션 버튼", + "TablePageSizeMaximum": "페이지 크기는 {maximumValue}을(를) 초과할 수 없습니다", + "TablePageSizeMinimum": "페이지 크기는 최소 {minimumValue} 이상이어야 합니다", + "TaskUserAgentTooltip": "API를 호출한 앱에서 제공하는 사용자 에이전트", + "TestParsing": "테스트 파싱", + "ThereWasAnErrorLoadingThisItem": "이 항목을 로드하는 중에 오류가 발생했습니다", + "Theme": "테마", + "ThemeHelpText": "애플리케이션 UI 테마 변경, '자동' 테마는 OS 테마를 사용하여 라이트 또는 다크 모드를 설정합니다. Theme.Park에서 영감을 받음", + "ThereWasAnErrorLoadingThisPage": "이 페이지를 로드하는 중ㅇ 오류가 발생했습니다", + "TorrentBlackhole": "Torrent Blackhole", + "TmdbRating": "TMDb 평점", + "TmdbVotes": "TMDb 투표", + "ToggleUnmonitoredToMonitored": "모니터링 해제, 모니터링을 설정하려면 클릭하세요", + "TomorrowAt": "내일 {time}에", + "TorrentBlackholeSaveMagnetFiles": "마그넷 파일 저장", + "TorrentBlackholeSaveMagnetFilesExtension": "마그넷 파일 확장자 저장", + "TorrentBlackholeSaveMagnetFilesExtensionHelpText": "마그넷 링크에 사용할 확장자, 기본값은 '.magnet'입니다", + "TorrentBlackholeSaveMagnetFilesHelpText": ".torrent 파일을 사용할 수 없는 경우 마그넷 링크를 저장합니다 (다운로드 클라이언트가 파일에 저장된 마그넷을 지원하는 경우에만 유용함)", + "TorrentBlackholeSaveMagnetFilesReadOnly": "읽기 전용", + "TorrentBlackholeSaveMagnetFilesReadOnlyHelpText": "파일을 이동하는 대신 {appName}에 복사 또는 하드링크(설정/시스템 구성에 따라 다름)를 지시합니다", + "TraktVotes": "Trakt 투표", + "Trending": "트렌딩", + "True": "참", + "UnmonitorSelected": "선택 항목 모니터링 해제", + "UserInvokedSearch": "사용자 호출 검색", + "BlocklistReleaseHelpText": "{appName}에서 RSS 또는 자동 검색을 통해 이 출시를 다운로드하는 것을 차단합니다", + "BypassDelayIfAboveCustomFormatScoreHelpText": "구성된 최소 사용자 정의 형식 점수보다 출시 점수가 높을 경우 무시를 활성화합니다", + "BypassDelayIfHighestQualityHelpText": "선호 프로토콜이 있는 품질 프로필에서 출시가 가장 높은 활성화 품질을 가질 때 지연을 무시합니다", + "ClearBlocklist": "차단 목록 지우기", + "ClearBlocklistMessageText": "정말로 모든 항목을 차단 목록에서 지우시겠습니까?", + "ClickToChangeIndexerFlags": "인덱서 플래그를 변경하려면 클릭", + "ClickToChangeReleaseGroup": "출시 그룹을 변경하려면 클릭", + "CloneCondition": "조건 복제", + "CollectionOptions": "컬렉션옵션", + "CollectionShowDetailsHelpText": "컬렉션 상태 및 속성 표시", + "CollectionShowOverviewsHelpText": "컬렉션 개요 표시", + "CollectionShowPostersHelpText": "컬렉션 아이템 포스터 표시", + "ConditionUsingRegularExpressions": "이 조건은 정규 표현식을 사용하여 일치합니다. 문자 `\\^$.|?*+()[{`은(는) 특별한 의미가 있으며 `\\`으로 끝나야 합니다.", + "ConnectionSettingsUrlBaseHelpText": "{connectionName} url에 {url}와(과) 같은 접두사를 추가합니다", + "CountCustomFormatsSelected": "{count}개의 사용자 정의 형식을 선택함", + "CountDownloadClientsSelected": "{count}개의 다운로드 클라이언트를 선택함", + "CountImportListsSelected": "{count}개의 가져오기 목록을 선택함", + "CountIndexersSelected": "{count}개의 인덱서를 선택함", + "CustomFormatJson": "사용자 정의 형식 JSON", + "CustomFormatsSpecificationExceptLanguageHelpText": "선택한 언어 외의 다른 언어가 존재하는 경우 일치합니다", + "CustomFormatsSpecificationMaximumSizeHelpText": "출시는 이 크기보다 작거나 같아야 합니다", + "CustomFormatsSettingsTriggerInfo": "사용자 정의 형식은 선택한 다양한 조건 유형 중 하나 이상과 일치할 경우 출시 또는 파일에 적용됩니다.", + "CustomFormatsSpecificationMinimumSizeHelpText": "출시는 이 크기보다 커야 합니다", + "CustomFormatsSpecificationMaximumYear": "최대 연도", + "CustomFormatsSpecificationMinimumSize": "최소 크기", + "CustomFormatsSpecificationMinimumYear": "최소 연도", + "CustomFormatsSpecificationQualityModifier": "품질 수정 도구", + "CustomFormatsSpecificationRegularExpressionHelpText": "사용자 정의 형식 정규표현식은 대소문자를 구분하지 않습니다", + "CutoffUnmetLoadError": "조건 미충족 항목을 로드하는 중 오류가 발생함", + "CutoffUnmetNoItems": "조건 미충족 항목 없음", + "DefaultNameCopiedProfile": "{name} - 복사", + "DefaultNameCopiedSpecification": "{name} - 복사", + "DefaultNotFoundMessage": "길을 잃은 모양입니다. 여기는 볼 것이 없습니다.", + "DelayMinutes": "{delay}분", + "DelayProfileProtocol": "프로토콜: {preferredProtocol}", + "DeleteAutoTag": "자동 태그 삭제", + "DeleteCondition": "조건 삭제", + "DeleteImportList": "가져오기 목록 삭제", + "DeleteMovieFolderCountConfirmation": "정말로 {count}개의 선택한 영화를 삭제하시겠습니까?", + "DeleteMovieFolderCountWithFilesConfirmation": "정말로 {count}개의 선택한 영화와 모든 콘텐츠를 삭제하시겠습니까?", + "DeleteRootFolder": "루트 폴더 삭제", + "DeleteRemotePathMappingMessageText": "정말로 이 원격 경로 매핑을 삭제하시겠습니까?", + "DeleteRootFolderMessageText": "정말로 루트 폴더 '{path}'을(를) 삭제하시겠습니까?", + "DeleteSelectedCustomFormatsMessageText": "정말로 {count}개의 선택한 사용자 정의 형식을 삭제하시겠습니까?", + "DeleteSelectedDownloadClientsMessageText": "정말로 {count}개의 선택한 다운로드 클라이언트를 삭제하시겠습니까?", + "DeleteSelectedIndexersMessageText": "정말로 {count}개의 선택한 인덱서를 삭제하시겠습니까?", + "DeletedReasonManual": "{appName}을 사용하여 파일이 삭제되었습니다. 수동으로 또는 API를 통한 다른 도구를 사용하여 삭제되었습니다", + "DiscordUrlInSlackNotification": "Slack 알림으로 설정된 Discord 알림이 있습니다. 더 나은 기능을 위해 Discord 알림으로 설정하세요. 영향을 받는 알림은 다음과 같습니다: {0}", + "Disposition": "처분", + "DoNotBlocklistHint": "차단 목록에 추가하지 않고 제거", + "DownloadClientAriaSettingsDirectoryHelpText": "다운로드를 이동할 선택적 위치입니다. 기본 Aria2 위치를 사용하려면 비워두세요", + "DownloadClientDelugeSettingsDirectoryCompleted": "완료 후 이동할 디렉토리", + "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "완료된 다운로드를 이동할 선택적 위치. 기본 Deluge 위치를 사용하려면 비워두세요", + "DownloadClientDelugeSettingsDirectoryHelpText": "다운로드를 이동할 선택적 위치. 기본 Deluge 위치를 사용하려면 비워두세요", + "DownloadClientDelugeSettingsUrlBaseHelpText": "deluge json url에 접두사를 추가합니다. {url}을(를) 참조하세요", + "DownloadClientDelugeValidationLabelPluginFailure": "라벨 구성에 실패함", + "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName}이(가) {clientName}에 라벨을 추가하지 못함", + "DownloadClientDelugeValidationLabelPluginInactive": "라벨 플러그인이 활성화되지 않음", + "DownloadClientDownloadStationProviderMessage": "DSM 계정에서 2단계 인증이 활성화된 경우 {appName}이 Download Station에 연결할 수 없음", + "DownloadClientDownloadStationValidationNoDefaultDestination": "기본 대상 없음", + "DownloadClientFreeboxUnableToReachFreebox": "Freebox API에 도달할 수 없음 '호스트', '포트' 또는 'SSL 사용' 설정을 확인하세요. (오류: {exceptionMessage})", + "DownloadClientDownloadStationValidationSharedFolderMissingDetail": "Diskstation에 '{sharedFolder}'이라는 이름의 공유 폴더가 없음 올바르게 지정했습니까?", + "DownloadClientFreeboxUnableToReachFreeboxApi": "Freebox API에 도달할 수 없음 기본 URL 및 버전에 대한 'API URL' 설정을 확인하세요.", + "DownloadClientNzbgetValidationKeepHistoryZeroDetail": "NzbGet 설정 KeepHistory가 0으로 설정되어 있습니다. 이렇게 하면 {appName}이 완료된 다운로드를 볼 수 없음", + "DownloadClientQbittorrentTorrentStateDhtDisabled": "qBittorrent는 DHT가 비활성화된 상태에서 마그넷 링크를 확인할 수 없음", + "DownloadClientQbittorrentTorrentStatePathError": "가져올 수 없음 경로가 클라이언트 기반 다운로드 디렉토리와 일치합니다. 이 토런트에 대해 '최상위 폴더 유지'가 비활성화되었거나 '토런트 콘텐츠 레이아웃'이 '원본' 또는 '하위 폴더 만들기'로 설정되지 않았을 수 있습니다.", + "DownloadClientQbittorrentValidationCategoryAddFailureDetail": "{appName}이 qBittorrent에 라벨을 추가하지 못함", + "DownloadClientQbittorrentValidationRemovesAtRatioLimitDetail": "{appName}은 구성된 대로 완료된 다운로드 처리를 수행할 수 없음 qBittorrent에서 이를 수정할 수 있습니다(메뉴의 '도구 -> 옵션...'). '옵션 -> BitTorrent -> 공유 비율 제한'을 '제거'에서 '일시 중지'로 변경합니다.", + "DownloadClientQbittorrentValidationCategoryUnsupportedDetail": "qBittorrent 버전 3.3.0까지는 카테고리가 지원되지 않습니다. 업그레이드하거나 빈 카테고리로 재시도하세요.", + "DownloadClientValidationSslConnectFailureDetail": "{appName}은 SSL을 사용하여 {clientName}에 연결할 수 없음 이 문제는 컴퓨터와 관련이 있을 수 있습니다. {appName}와(과) {clientName} 둘 다 SSL을 사용하지 않도록 구성해 보세요.", + "DownloadClientValidationUnableToConnect": "{clientName}에 연결할 수 없음", + "EnableProfileHelpText": "출시 프로필을 활성화하려면 체크하세요", + "EnableRssHelpText": "{appName}이(가) RSS 동기화를 통해 주기적으로 출시를 찾을 때 사용됩니다.", + "FailedToFetchUpdates": "업데이트를 가져오지 못함", + "HealthMessagesInfoBox": "행 끝에 있는 위키 링크(책 아이콘)를 클릭하거나 [로그]({link})를 확인하면 이러한 상태 점검 메시지의 원인에 대한 상세 정보를 찾을 수 있습니다. 이러한 메시지를 해석하는 데 어려움이 있는 경우 아래 링크에서 지원팀에 문의할 수 있습니다.", + "InstallMajorVersionUpdateMessageLink": "상세 내용은 [{domain}]({url})을 확인하세요.", + "InteractiveImportNoFilesFound": "선택한 폴더에서 비디오 파일을 찾을 수 없음", + "InteractiveSearchResultsFailedErrorMessage": "{message}이기 때문에 검색에 실패했습니다. 영화 정보를 새로 고치고 재검색하기 전에 필요한 정보가 있는지 확인하세요.", + "MinimumCustomFormatScoreIncrementHelpText": "{appName}이 업그레이드로 간주하기 전에 기존 출시와 새 출시 간의 사용자 정의 형식 점수의 최소 요구 개선", + "NoCustomFormatsFound": "사용자 정의 형식을 찾을 수 없음", + "NoDownloadClientsFound": "다운로드 클라이언트를 찾을 수 없음", + "NoExtraFilesToManage": "추가로 관리할 파일이 없음", + "NoMovieFilesToManage": "관리할 영화 파일이 없음", + "NotificationsCustomScriptSettingsProviderMessage": "테스트는 EventType을 {eventTypeTest}으로 설정하여 스크립트를 실행하므로 스크립트가 이를 올바르게 처리하는지 확인하세요.", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} 경로는 {serviceName}이 라이브러리 경로 위치를 {appName}와(과) 다르게 볼 때 영화 경로를 수정하는 데 사용됩니다(라이브러리 업데이트 필요)", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName} 경로는 {serviceName}이 라이브러리 경로 위치를 {appName}와(과) 다르게 볼 때 영화 경로를 수정하는 데 사용됩니다(라이브러리 업데이트 필요)", + "NotificationsSynologyValidationTestFailed": "Synology 또는 synoindex를 사용할 수 없음", + "NotificationsValidationUnableToConnectToApi": "{service} API에 연결할 수 없음 서버 연결에 실패했습니다: ({responseCode}) {exceptionMessage}", + "NotificationsValidationUnableToConnectToService": "{serviceName}에 연결할 수 없음", + "NotificationsValidationUnableToSendTestMessageApiResponse": "테스트 메시지를 보낼 수 없음 API 응답: {error}", + "OrganizeRenamingDisabled": "이름 바꾸기가 비활성화되어 있습니다. 이름을 바꿀 것이 없음", + "ParseModalErrorParsing": "구문분석 중 오류가 발생했습니다. 재시도하세요.", + "ParseModalHelpText": "위의 입력란에 출시 제목을 입력하세요.", + "ParseModalHelpTextDetails": "{appName}은 제목을 구문 분석하고 해당 제목에 대한 세부 사항를 표시하려고 시도합니다.", + "ParseModalUnableToParse": "제공된 제목을 구문 분석할 수 없음 재시도하세요.", + "PendingDownloadClientUnavailable": "보류 중 - 다운로드 클라이언트를 사용할 수 없음", + "QueueFilterHasNoItems": "선택된 대기열 필터에 항목이 없음", + "RecycleBinUnableToWriteHealthCheck": "구성된 휴지통 폴더에 쓸 수 없습니다: {path}. 이 경로가 존재하고 {appName}을 실행하는 사용자가 쓸 수 있는지 확인하세요.", + "Rejections": "거부", + "ReleaseProfileIndexerHelpText": "프로필이 적용되는 인덱서를 지정하세요", + "ReleaseProfileIndexerHelpTextWarning": "출시 프로필에 특정 인덱서를 설정하면 이 프로필은 해당 인덱서의 출시에만 적용됩니다.", + "ReleaseProfileTagMovieHelpText": "출시 프로필은 일치하는 태그가 하나 이상 있는 영화에 적용됩니다. 모든 영화에 적용하려면 비워두세요", + "RemotePathMappingCheckDockerFolderMissing": "Docker를 사용하고 있습니다. 다운로드 클라이언트 {downloadClientName}는 {path}에 다운로드를 배치하지만 이 디렉토리는 컨테이너 내부에 존재하지 않는 것으로 보입니다. 원격 경로 매핑과 컨테이너 볼륨 설정을 검토하세요.", + "RemotePathMappingCheckFilesGenericPermissions": "클라이언트 {downloadClientName}이(가) {path}에서 보고한 파일을 다운로드했지만 {appName}은(는) 이 디렉토리를 볼 수 없음 폴더의 권한을 조정해야 할 수도 있습니다.", + "RemotePathMappingCheckFilesLocalWrongOSPath": "로컬 다운로드 클라이언트 {downloadClientName}이(가) {path}에서 파일을 보고했지만 이는 유효한 {osName} 경로가 아닙니다. 다운로드 클라이언트 설정을 검토하세요.", + "RemotePathMappingCheckFilesWrongOSPath": "원격 다운로드 클라이언트 {downloadClientName}이(가) {path}에서 파일을 보고했지만 이는 유효한 {osName} 경로가 아닙니다. 원격 경로 매핑과 다운로드 클라이언트 설정을 검토하세요.", + "RemotePathMappingCheckGenericPermissions": "다운로드 클라이언트 {downloadClientName}은(는) {path}에 다운로드를 배치하지만 {appName}은(는) 이 디렉토리를 볼 수 없음 폴더의 권한을 조정해야 할 수도 있습니다.", + "RemotePathMappingCheckFolderPermissions": "{appName}은(는) 다운로드 디렉토리 {path}을(를) 볼 수는 있지만 액세스할 수 없음 권한 오류일 가능성이 높습니다.", + "RemotePathMappingCheckImportFailed": "{appName}이(가) 영화를 가져오지 못함 상세 내용은 로그를 확인하세요.", + "RemotePathMappingCheckLocalFolderMissing": "원격 다운로드 클라이언트 {downloadClientName}이(가) {path}에 다운로드를 배치하지만 이 디렉토리는 존재하지 않는 것 같습니다. 원격 경로 매핑이 누락되었거나 잘못되었을 가능성이 있습니다.", + "RemotePathMappingCheckLocalWrongOSPath": "로컬 다운로드 클라이언트 {downloadClientName}이(가) {path}에 다운로드를 배치하지만 이는 유효한 {osName} 경로가 아닙니다. 다운로드 클라이언트 설정을 검토하세요.", + "RemotePathMappingCheckRemoteDownloadClient": "원격 다운로드 클라이언트 {downloadClientName}이(가) {path}에 파일을 보고했지만 이 디렉토리는 존재하지 않는 것으로 보입니다. 원격 경로 매핑이 누락되었을 가능성이 높습니다.", + "RemotePathMappingCheckWrongOSPath": "원격 다운로드 클라이언트 {downloadClientName}이(가) {path}에 다운로드를 배치하지만 이는 유효한 {osName} 경로가 아닙니다. 원격 경로 매핑과 다운로드 클라이언트 설정을 검토하세요.", + "RemoveCompleted": "제거 완료", + "RemoveDownloadsAlert": "제거 설정은 위 표의 개별 다운로드 클라이언트 설정으로 이동되었습니다.", + "RemoveFailed": "제거 실패", + "RemoveFailedDownloads": "실패한 다운로드 제거", + "RemoveFromDownloadClientHint": "다운로드 클라이언트에서 다운로드 및 파일을 제거합니다", + "RemoveQueueItemRemovalMethodHelpTextWarning": "'다운로드 클라이언트에서 제거'를 선택하면 다운로드 및 파일이 다운로드 클라이언트에서 제거됩니다.", + "RemoveQueueItemsRemovalMethodHelpTextWarning": "'다운로드 클라이언트에서 제거'를 선택하면 다운로드 및 파일이 다운로드 클라이언트에서 제거됩니다.", + "SkipRedownloadHelpText": "{appName}이(가) 이 항목에 대한 대체 출시를 다운로드하려는 것을 방지합니다", + "ChownGroup": "chown 그룹", + "DownloadClientQbittorrentValidationCategoryRecommended": "카테고리를 추천합니다", + "DownloadClientSettingsUseSslHelpText": "{clientName}에 연결할 때 보안 연결을 사용하세요.", + "NoMovieReleaseDatesAvailable": "[TMDb]({url})에는 이 영화의 출시 날짜가 없음", + "NotificationsGotifySettingIncludeMoviePosterHelpText": "메시지에 영화 포스터 포함", + "DownloadClientSortingCheckMessage": "다운로드 클라이언트 {downloadClientName}에서 {appName}의 카테고리에 대해 {sortingMode} 정렬이 활성화되었습니다. 가져오기 문제를 방지하려면 다운로드 클라이언트에서 정렬을 비활성화해야 합니다.", + "ImdbVotes": "IMDb 투표", + "NotificationTriggersHelpText": "이 알림을 트리거할 이벤트를 선택하세요", + "BlocklistAndSearchHint": "차단 목록에 추가한 후 대체 항목 검색 시작", + "CloneAutoTag": "자동 태그 복제", + "DoNotBlocklist": "차단 목록에 추가하지 않음", + "MonitorCollection": "모니터 컬렉션", + "NotificationsCustomScriptSettingsArguments": "독립변수", + "NotificationsJoinSettingsDeviceIds": "장치 ID", + "AnnouncedMovieAvailabilityDescription": "{appName}에 추가된 직후 영화는 사용 가능한 것으로 간주됩니다.", + "ApplicationURL": "애플리케이션 URL", + "ApplicationUrlHelpText": "이 애플리케이션의 외부 URL - http(s)://, port 및 URL 기반 포함", + "ApplyChanges": "변경 사항 적용", + "AuthenticationMethodHelpTextWarning": "인증 방식을 선택해주세요", + "Auto": "자동", + "AuthenticationRequiredWarning": "인증 없이 원격 액세스를 방지하기 위해 {appName}은(는) 이제 인증을 활성화해야 합니다. 선택적으로 로컬 주소에서 인증을 비활성화할 수 있습니다.", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "대화형 검색에서 실패한 출시가 잡혔을 때 다른 출시를 자동으로 검색하여 다운로드 시도", + "AutoTagging": "자동 태그 지정", + "FormatAgeMinute": "분", + "Dash": "대시", + "DeleteSelectedImportLists": "가져오기 목록 삭제", + "DownloadClientDelugeTorrentStateError": "Deluge에서 오류를 보고합니다", + "ManualImportSetReleaseGroup": "수동 가져오기 - 출시 그룹 설정", + "ManualGrab": "수동 그랩", + "Space": "간격", + "NotificationsGotifySettingsServerHelpText": "필요한 경우 http(s):// 및 포트를 포함하여 Gotify 서버 URL을 확인하세요.", + "AuthenticationRequiredHelpText": "필수 인증을 요청하는 변경 사항. 위험을 이해하지 못한다면 변경하지 마세요.", + "AudioLanguages": "오디오 언어", + "NotificationsSimplepushSettingsEventHelpText": "푸시 알림의 동작 사용자 정의", + "NotificationsKodiSettingsDisplayTime": "시간 표시", + "OneMinute": "1분", + "ProgressBarProgress": "진행률 표시줄이 {progress}%에 있음", + "DayOfWeekAt": "{day} {time}", + "DeleteSelectedImportListsMessageText": "정말로 {count}개의 선택한 가져오기 목록을 삭제하시겠습니까?", + "SkipFreeSpaceCheckHelpText": "{appName}이(가) 루트 폴더의 여유 공간을 감지할 수 없는 경우 사용하세요", + "UpdaterLogFiles": "업데이트 도구 로그 파일", + "NotificationsGotifySettingsMetadataLinks": "메타데이터 링크", + "NotificationsGotifySettingsMetadataLinksMovieHelpText": "알림을 보낼 때 영화 메타데이터에 대한 링크를 추가합니다.", + "NotificationsJoinSettingsDeviceNames": "장치 이름", + "NotificationsSignalSettingsSenderNumber": "발신자 번호", + "AutoTaggingSpecificationGenre": "장르", + "AutoTaggingSpecificationMaximumRuntime": "최대 상영시간", + "AutoTaggingSpecificationMaximumYear": "최대 연도", + "AutoTaggingSpecificationMinimumRuntime": "최소 상영시간", + "AutoTaggingSpecificationMinimumYear": "최소 연도", + "AutoTaggingSpecificationTag": "태그", + "AutomaticAdd": "자동 추가", + "AutomaticUpdatesDisabledDocker": "Docker 업데이트 메커니즘을 사용할 때는 자동 업데이트가 직접 지원되지 않습니다. {appName} 외부에서 컨테이너 이미지를 업데이트하거나 스크립트를 사용해야 합니다", + "BlocklistMultipleOnlyHint": "대체 항목을 검색하지 않고 차단 목록에 추가", + "BlocklistAndSearch": "차단 목록 및 검색", + "BlocklistAndSearchMultipleHint": "차단 목록에 추가한 후 대체 항목 검색 시작", + "BlocklistFilterHasNoItems": "선택된 차단 목록 필터에 항목이 없음", + "BlocklistOnly": "차단 목록만", + "BypassDelayIfAboveCustomFormatScore": "사용자 정의 형식 점수보다 높으면 무시", + "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "선호하는 프로토콜의 지연을 우회하는 데 필요한 최소 사용자 정의 형식 점수", + "BypassDelayIfHighestQuality": "최고 품질일 경우 무시", + "ChangeCategoryHint": "다운로드 클라이언트에서 다운로드를 '가져오기 이후 카테고리'로 변경", + "ChooseImportMode": "가져오기 모드 선택", + "CustomFormatsSpecificationFlag": "국기", + "Delay": "지연", + "DownloadClientNzbgetValidationKeepHistoryOverMax": "NzbGet 설정 KeepHistory는 25000보다 작아야 합니다.", + "ImportScriptPath": "스크립트 경로 가져오기", + "Logout": "로그아웃", + "ManageClients": "클라이언트 관리", + "ManageFiles": "파일 관리", + "NotificationsTwitterSettingsMentionHelpText": "보낸 트윗에 이 사용자를 언급하세요", + "ReleaseProfiles": "출시 프로필", + "RemoveCompletedDownloads": "완료된 다운로드 제거", + "RemoveTagsAutomaticallyHelpText": "조건이 충족되지 않으면 태그를 자동으로 제거", + "DownloadClientQbittorrentSettingsSequentialOrder": "순차적 순서" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index 3fe8d17a72..a0653c59c6 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -325,5 +325,12 @@ "AutoTaggingSpecificationRootFolder": "Rotmappe", "CustomFormatsSpecificationResolution": "Oppløsning", "AutoTaggingSpecificationOriginalLanguage": "språk", - "CustomFormatsSpecificationLanguage": "språk" + "CustomFormatsSpecificationLanguage": "språk", + "AddRemotePathMappingError": "Kunne ikke legge til ny ekstern stimapping, vennligst prøv igjen.", + "AddRootFolderError": "Kunne ikke legge til rotmappe", + "FailedLoadingSearchResults": "Kunne ikke laste søkeresultat, vennligst prøv igjen.", + "AddImportList": "Ny Importliste", + "AddNewRestriction": "Legg til ny begrensning", + "AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}", + "AddImportListImplementation": "Legg til importliste - {implementationName}" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 636945d17c..51c10f5f9e 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -134,7 +134,7 @@ "ErrorLoadingContents": "Erro ao carregar o conteúdo", "Error": "Erro", "Ended": "Terminou", - "EnableSslHelpText": " Requer a reinicialização com a execução como administrador para fazer efeito", + "EnableSslHelpText": " Requer reinicialização e execução como administrador para entrar em vigor", "EnableSsl": "Habilitar SSL", "EnableRss": "Habilitar RSS", "AnalyseVideoFilesHelpText": "Extraia informações do vídeo, como resolução, duração e informações do codec de arquivos. Isso requer que o {appName} leia partes do arquivo que podem causar alta atividade no disco ou na rede durante as verificações.", @@ -309,7 +309,7 @@ "CalendarOptions": "Opções do calendário", "Calendar": "Calendário", "BypassProxyForLocalAddresses": "Ignorar proxy para endereços locais", - "BuiltIn": "Embutido", + "BuiltIn": "Integrado", "BranchUpdateMechanism": "Ramificação usada pelo mecanismo externo de atualização", "BranchUpdate": "Ramificação para atualizar o {appName}", "Branch": "Ramificação", @@ -369,7 +369,7 @@ "MinimumAgeHelpText": "Somente Usenet: idade mínima, em minutos, dos NZBs antes de serem obtidos. Use esta opção para dar aos novos lançamentos tempo para propagarem para seu provedor de Usenet.", "MinimumAge": "Idade mínima", "MinimumAvailability": "Disponibilidade mínima", - "MinimumCustomFormatScoreHelpText": "Pontuação mínima de formato personalizado permitida para download", + "MinimumCustomFormatScoreHelpText": "Pontuação mínima do formato personalizado permitida para download", "MinAvailability": "Disponibilidade mínima", "MetadataSettingsMovieSummary": "Criar arquivos de metadados ao importar ou atualizar filmes", "Metadata": "Metadados", @@ -743,7 +743,7 @@ "ReleaseStatus": "Status da versão", "Released": "Lançado", "ReleaseRejected": "Lançamento Rejeitado", - "ReleaseGroup": "Grupo de lançamento", + "ReleaseGroup": "Grupo do lançamento", "ReleasedMovieDescription": "Filme lançado", "ReleaseDates": "Datas de lançamento", "RelativePath": "Caminho relativo", @@ -864,7 +864,7 @@ "OAuthPopupMessage": "Os pop-ups estão bloqueados em seu navegador", "NoUpdatesAreAvailable": "Não há atualizações disponíveis", "NotMonitored": "Não monitorado", - "NotificationTriggers": "Gatilhos de Notificação", + "NotificationTriggers": "Acionadores de notificação", "NotAvailable": "Indisponível", "NoTagsHaveBeenAddedYet": "Nenhuma tag foi adicionada ainda", "NoResultsFound": "Nenhum resultado encontrado", @@ -1057,7 +1057,7 @@ "ResetTitles": "Redefinir títulos", "Theme": "Tema", "EnableRssHelpText": "Será usado quando o {appName} procurar periodicamente por lançamentos via RSS Sync", - "DownloadClientSortingCheckMessage": "O cliente de download {downloadClientName} tem a classificação {sortingMode} habilitada para a categoria do {appName}. Você deve desativar essa classificação em seu cliente de download para evitar problemas de importação.", + "DownloadClientSortingCheckMessage": "O cliente de download {downloadClientName} tem classificação {sortingMode} habilitada para a categoria do {appName}. Você deve desabilitar essa classificação em seu cliente de download para evitar problemas de importação.", "File": "Arquivo", "StopSelecting": "Parar Seleção", "UpdateFiltered": "Atualização Filtrada", @@ -1436,7 +1436,7 @@ "NotificationsTraktSettingsAccessToken": "Token de Acesso", "NotificationsTraktSettingsAuthenticateWithTrakt": "Autenticar com Trakt", "NotificationsTraktSettingsExpires": "Expira", - "NotificationsTraktSettingsRefreshToken": "Atualizar Token", + "NotificationsTraktSettingsRefreshToken": "Atualizar token", "NotificationsTwitterSettingsAccessToken": "Token de Acesso", "NotificationsTwitterSettingsAccessTokenSecret": "Segredo do Token de Acesso", "NotificationsTwitterSettingsConnectToTwitter": "Conecte-se ao Twitter / X", @@ -1447,7 +1447,7 @@ "NotificationsTelegramSettingsBotToken": "Token do Bot", "NotificationsSynologyValidationInvalidOs": "Deve ser uma Synology", "NotificationsTelegramSettingsChatId": "ID do Bate-papo", - "NotificationsTraktSettingsAuthUser": "Autenticação de Usuário", + "NotificationsTraktSettingsAuthUser": "Autenticação de usuário", "NotificationsTwitterSettingsConsumerKey": "Chave do Consumidor", "NotificationsTwitterSettingsMention": "Mencionar", "NotificationsTwitterSettingsMentionHelpText": "Mencione este usuário nos tweets enviados", @@ -1881,13 +1881,16 @@ "CustomFormatsSpecificationLanguage": "Idioma", "CustomFormatsSpecificationMaximumSize": "Tamanho máximo", "CustomFormatsSpecificationMaximumSizeHelpText": "O lançamento deve ser menor ou igual a este tamanho", - "CustomFormatsSpecificationMaximumYear": "Ano Máximo", + "CustomFormatsSpecificationMaximumYear": "Ano máximo", "CustomFormatsSpecificationMinimumSize": "Tamanho Mínimo", "CustomFormatsSpecificationMinimumSizeHelpText": "O lançamento deve ser maior que esse tamanho", - "CustomFormatsSpecificationMinimumYear": "Ano Mínimo", + "CustomFormatsSpecificationMinimumYear": "Ano mínimo", "CustomFormatsSpecificationResolution": "Resolução", "CustomFormatsSpecificationSource": "Origem", "AutoTaggingSpecificationMaximumRuntime": "Tempo Máximo de Duração", "AutoTaggingSpecificationMinimumRuntime": "Tempo Mínimo de Duração", - "CustomFormatsSpecificationQualityModifier": "Modificador de Qualidade" + "CustomFormatsSpecificationQualityModifier": "Modificador de Qualidade", + "ReleasePush": "Impulsionar Lançamento", + "ReleaseSource": "Fonte do Lançamento", + "UserInvokedSearch": "Pesquisa Invocada pelo Usuário" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 071bd6d0b9..e9486fdcbf 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -118,7 +118,7 @@ "Options": "Seçenekler", "NoChanges": "Değişiklikler yok", "NoChange": "Değişiklik yok", - "MovieTitle": "Film başlığı", + "MovieTitle": "Film Başlığı", "Movies": "Film", "MovieNaming": "Film Adlandırma", "MovieEditor": "Film Editörü", @@ -183,7 +183,7 @@ "Released": "Yayınlandı", "ReleasedMovieDescription": "Film yayınlandı", "ReleaseRejected": "Reddedildi", - "ReplaceWithDash": "Dash ile değiştir", + "ReplaceWithDash": "'Kısa Çizgi' ile değiştir", "Reset": "Sıfırla", "New": "Yeni", "LocalPath": "Yerel Yol", @@ -225,7 +225,7 @@ "EnableAutomaticSearchHelpText": "Kullanıcı arayüzü veya {appName} tarafından otomatik aramalar yapıldığında kullanılacaktır", "EnableColorImpairedModeHelpText": "Renk engelli kullanıcıların renkleri daha iyi ayırt edebilmelerini sağlamak için değiştirilmiş stil", "EnableInteractiveSearch": "Etkileşimli Aramayı Etkinleştir", - "ExtraFileExtensionsHelpTextsExamples": "Örnekler: \".sub, .nfo\" veya \"sub, nfo\"", + "ExtraFileExtensionsHelpTextsExamples": "Örneğin: \".sub, .nfo\" veya \"sub, nfo\"", "FocusSearchBox": "Arama Kutusuna Odaklan", "Folders": "Klasörler", "FollowPerson": "Kişiyi Takip Et", @@ -242,7 +242,7 @@ "RemoveFromDownloadClient": "İndirme İstemcisinden Kaldır", "Reorder": "Yeniden sırala", "Replace": "Değiştir", - "ReplaceWithSpaceDashSpace": "Space Dash Space ile değiştirin", + "ReplaceWithSpaceDashSpace": "'Boşluk' 'Kısa Çizgi' 'Boşluk' ile değiştir", "RestartNow": "Şimdi yeniden başlat", "RestartReloadNote": "Not: {appName}, geri yükleme işlemi sırasında kullanıcı arayüzünü otomatik olarak yeniden başlatacak ve yeniden yükleyecektir.", "RetentionHelpText": "Yalnızca Usenet: Sınırsız saklamaya ayarlamak için sıfıra ayarlayın", @@ -554,7 +554,7 @@ "DeleteBackupMessageText": "'{name}' yedeğini silmek istediğinizden emin misiniz?", "Edition": "Versiyon", "EnableCompletedDownloadHandlingHelpText": "Tamamlanan indirmeleri indirme istemcisinden otomatik olarak içe aktarın", - "ListEnabledHelpText": "Bu listeyi {appName}'da kullanmak üzere etkinleştirin", + "ListEnabledHelpText": "Bu listeyi {appName}'da kullanmak üzere etkinleştir", "Ended": "Biten", "Events": "Olaylar", "IncludeCustomFormatWhenRenamingHelpText": "Özel formatları yeniden adlandırma formatına dahil et", @@ -640,8 +640,8 @@ "CloneIndexer": "Klon İndeksleyici", "CloneProfile": "Klon Profili", "CloseCurrentModal": "Geçerli Modeli Kapat", - "ColonReplacement": "Kolon Değiştirme", - "ColonReplacementFormatHelpText": "{appName}'ın kolon değişimini nasıl işlediğini değiştirin", + "ColonReplacement": "\":\" İşaretini Değiştir", + "ColonReplacementFormatHelpText": "{appName} uygulamasının iki nokta üst üste değiştirmeyi işleme biçimi ayarı", "Conditions": "Koşullar", "Connection": "Bağlantılar", "ConnectionLost": "Bağlantı koptu", @@ -701,7 +701,7 @@ "DownloadPropersAndRepacks": "Uygunluj ve Yeniden Paketlemeler", "DownloadPropersAndRepacksHelpText": "Propers / Repacks'e otomatik olarak yükseltme yapılıp yapılmayacağı", "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks'e otomatik yükseltmeler için özel formatlar kullanın", - "DownloadWarning": "Uyarıyı indir: {warningMessage}", + "DownloadWarning": "İndirme Uyası: {warningMessage}", "EditImportListExclusion": "Hariç Tutulanlar Listesini Düzenle", "EditMovie": "Filmi Düzenle", "EditMovieFile": "Film Dosyasını Düzenle", @@ -746,7 +746,7 @@ "GeneralSettings": "Genel Ayarlar", "Genres": "Türler", "Global": "Küresel", - "GoToInterp": "{0} adresine gidin", + "GoToInterp": "{0}'a git", "Grabbed": "Alındı", "GrabRelease": "Yayın Alma", "Group": "Grup", @@ -876,7 +876,7 @@ "RenameMoviesHelpText": "Yeniden adlandırma devre dışı bırakılırsa, {appName} mevcut dosya adını kullanacaktır", "ReplaceIllegalCharacters": "Geçersiz Karakterleri Değiştirin", "ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse bunun yerine {appName} bunları kaldıracak", - "ReplaceWithSpaceDash": "Space Dash ile değiştirin", + "ReplaceWithSpaceDash": "'Boşluk' ve 'Kısa Çizgi' ile değiştir", "Required": "Gerekli", "RequiredRestrictionHelpText": "Yayın, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarlı değildir)", "RescanAfterRefreshMovieHelpText": "Filmi yeniledikten sonra film klasörünü yeniden tarayın", @@ -1332,7 +1332,7 @@ "EnableProfile": "Profili Etkinleştir", "IndexerDownloadClientHelpText": "Bu indeksleyiciden almak için hangi indirme istemcisinin kullanılacağını belirtin", "InstanceNameHelpText": "Sekmedeki örnek adı ve Syslog uygulaması adı için", - "InstanceName": "Örnek isim", + "InstanceName": "Örnek Adı", "InteractiveImportNoFilesFound": "Seçilen klasörde video dosyası bulunamadı", "InteractiveImportNoQuality": "Seçilen her dosya için kalite seçilmelidir", "InvalidUILanguage": "Kullanıcı arayüzünüz geçersiz bir dile ayarlanmış, düzeltin ve ayarlarınızı kaydedin", @@ -1471,7 +1471,7 @@ "LabelIsRequired": "Etiket gerekli", "Lists": "Listeler", "Letterboxd": "Letterboxd", - "MediaInfoFootNote": "Full/AudioLanguages/SubtitleLanguages, dosya adında yer alan dilleri filtrelemenize olanak tanıyan bir `:EN+DE` son ekini destekler. Belirli dilleri hariç tutmak için '-DE'yi kullanın. `+` (örneğin `:EN+`) eklenmesi, hariç tutulan dillere bağlı olarak `[EN]`/`[EN+--]`/`[--]` sonucunu verecektir. Örneğin `{MediaInfo Full:EN+DE}`.", + "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages, dosya adında bulunan dilleri filtrelemenize olanak tanıyan `:EN+DE` ekini destekler. Belirli dilleri hariç tutmak için `-DE` kullanın. `+` eklemek (örneğin `:EN+`) hariç tutulan dillere bağlı olarak `[EN]`/`[EN+--]`/`[--]` çıktısı verecektir. Örneğin `{MediaInfo Full:EN+DE}`.", "NoIndexersFound": "İndeksleyici bulunamadı", "NotificationsDiscordSettingsOnGrabFieldsHelpText": "Bu 'alındı' bildirimi için iletilen alanları değiştirin", "NotificationsDiscordSettingsOnManualInteractionFieldsHelpText": "'Manuel Etkileşimlerde' bildirimi için iletilen alanları değiştirin", @@ -1837,7 +1837,7 @@ "ReleasedMovieAvailabilityDescription": "Filmler Blu-Ray veya streaming versiyonu yayınlanır yayınlanmaz yayınlanabilir kabul edilir.", "AnnouncedMovieAvailabilityDescription": "Filmler {appName} uygulamasına eklendiği anda kullanılabilir olarak kabul edilir.", "SmartReplace": "Akıllı Değiştir", - "SmartReplaceHint": "İsme bağlı olarak Dash veya Space Dash", + "SmartReplaceHint": "İsme bağlı olarak 'Kısa Çizgi' veya 'Boşluk' 'Kısa Çizgi'", "DefaultNotFoundMessage": "Kaybolmuş olmalısın, burada görülecek bir şey yok.", "ShowTraktRating": "Trakt Puanını Göster", "OnFileImport": "Dosya İçe Aktarımı", @@ -1889,5 +1889,8 @@ "CustomFormatsSpecificationSource": "Kaynak", "AutoTaggingSpecificationMaximumRuntime": "Maksimum Çalışma Süresi", "AutoTaggingSpecificationMinimumRuntime": "Minimum Çalışma Süresi", - "CustomFormatsSpecificationQualityModifier": "Kalite Değiştirici" + "CustomFormatsSpecificationQualityModifier": "Kalite Değiştirici", + "ReleaseSource": "Yayın Kaynağı", + "UserInvokedSearch": "Kullanıcı Tarafından Çağrılan Arama", + "ReleasePush": "Yayın İtimi" } From f1f19215177c59d3d3b153165039eba91ade35fc Mon Sep 17 00:00:00 2001 From: Luke Anderson Date: Mon, 20 Jan 2025 01:35:55 +1030 Subject: [PATCH 179/579] Update Trakt ratings logo (#10822) Co-authored-by: Bogdan --- frontend/src/Components/TraktRating.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/Components/TraktRating.tsx b/frontend/src/Components/TraktRating.tsx index ad0c94b8c3..83ca1e0edd 100644 --- a/frontend/src/Components/TraktRating.tsx +++ b/frontend/src/Components/TraktRating.tsx @@ -15,7 +15,7 @@ function TraktRating(props: TraktRatingProps) { const { ratings, iconSize = 14, hideIcon = false } = props; const traktImage = - 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTguMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiAgICAgdmlld0JveD0iMCAwIDE0NC44IDE0NC44IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxNDQuOCAxNDQuOCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+ICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik0yOS41LDExMS44YzEwLjYsMTEuNiwyNS45LDE4LjgsNDIuOSwxOC44YzguNywwLDE2LjktMS45LDI0LjMtNS4zTDU2LjMsODVMMjkuNSwxMTEuOHoiLz4gICAgPHBhdGggZmlsbD0iI0VEMjIyNCIgZD0iTTU2LjEsNjAuNkwyNS41LDkxLjFMMjEuNCw4N2wzMi4yLTMyLjJoMGwzNy42LTM3LjZjLTUuOS0yLTEyLjItMy4xLTE4LjgtMy4xYy0zMi4yLDAtNTguMywyNi4xLTU4LjMsNTguMyAgICAgICBjMCwxMy4xLDQuMywyNS4yLDExLjcsMzVsMzAuNS0zMC41bDIuMSwybDQzLjcsNDMuN2MwLjktMC41LDEuNy0xLDIuNS0xLjZMNTYuMyw3Mi43TDI3LDEwMmwtNC4xLTQuMWwzMy40LTMzLjRsMi4xLDJsNTEsNTAuOSAgICAgICBjMC44LTAuNiwxLjUtMS4zLDIuMi0xLjlsLTU1LTU1TDU2LjEsNjAuNnoiLz4gICAgPHBhdGggZmlsbD0iI0VEMUMyNCIgZD0iTTExNS43LDExMS40YzkuMy0xMC4zLDE1LTI0LDE1LTM5YzAtMjMuNC0xMy44LTQzLjUtMzMuNi01Mi44TDYwLjQsNTYuMkwxMTUuNywxMTEuNHogTTc0LjUsNjYuOGwtNC4xLTQuMSAgICAgICBsMjguOS0yOC45bDQuMSw0LjFMNzQuNSw2Ni44eiBNMTAxLjksMjcuMUw2OC42LDYwLjRsLTQuMS00LjFMOTcuOCwyM0wxMDEuOSwyNy4xeiIvPiAgICA8Zz4gICAgICAgPGc+ICAgICAgICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik03Mi40LDE0NC44QzMyLjUsMTQ0LjgsMCwxMTIuMywwLDcyLjRDMCwzMi41LDMyLjUsMCw3Mi40LDBzNzIuNCwzMi41LDcyLjQsNzIuNCAgICAgICAgICAgICBDMTQ0LjgsMTEyLjMsMTEyLjMsMTQ0LjgsNzIuNCwxNDQuOHogTTcyLjQsNy4zQzM2LjUsNy4zLDcuMywzNi41LDcuMyw3Mi40czI5LjIsNjUuMSw2NS4xLDY1LjFzNjUuMS0yOS4yLDY1LjEtNjUuMSAgICAgICAgICAgICBTMTA4LjMsNy4zLDcyLjQsNy4zeiIvPiAgICAgICA8L2c+ICAgIDwvZz48L2c+PC9zdmc+'; + 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6ICM5ZjQyYzY7CiAgICAgIH0KCiAgICAgIC5jbHMtMiB7CiAgICAgICAgZmlsbDogI2ZmZjsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM+CiAgPGcgaWQ9Il94MkRfLXByb2R1Y3Rpb24iPgogICAgPGcgaWQ9ImxvZ29tYXJrLmNpcmNsZS5jb2xvciI+CiAgICAgIDxwYXRoIGlkPSJiYWNrZ3JvdW5kIiBjbGFzcz0iY2xzLTEiIGQ9Ik00OCwyNGMwLDYuNjItMi42OSwxMi42Mi03LjAzLDE2Ljk3LTQuMzQsNC4zNC0xMC4zNCw3LjAzLTE2Ljk3LDcuMDNDMTAuNzUsNDgsMCwzNy4yNSwwLDI0YzAtNi42MywyLjY5LTEyLjYzLDcuMDMtMTYuOTdDMTEuMzcsMi42OCwxNy4zNywwLDI0LDBzMTIuNjMsMi42OCwxNi45Nyw3LjAzYy4xNC4xNC4yNy4yOC40LjQyLjQ4LjUuOTQsMS4wMiwxLjM3LDEuNTYuMjEuMjYuNDEuNTIuNi43OS40My41Ny44MiwxLjE2LDEuMTgsMS43Ni4xOC4yOS4zNS41OC41MS44Ny4zNS42NC42OCwxLjI5Ljk2LDEuOTcsMS4zLDIuOTQsMi4wMSw2LjE4LDIuMDEsOS42WiIvPgogICAgICA8ZyBpZD0iY2hlY2tib3giPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTEyLjkzLDE4LjY3bC0xLjQ3LDEuNDYsMTQuNCwxNC40LDEuNDctMS40Ny00LjMyLTQuMzEsMTkuNzMtMTkuNzRjLS40My0uNTQtLjg5LTEuMDYtMS4zNy0xLjU2bC0xOS44MywxOS44My04LjYxLTguNjFaTTI4LjAyLDMyLjM3bDEuNDYtMS40Ni0yLjE1LTIuMTYsMTcuMTktMTcuMTljLS4zNi0uNi0uNzUtMS4xOS0xLjE4LTEuNzZsLTE4Ljk0LDE4Ljk1LDMuNjIsMy42MlpNMzAuMTgsMzAuMjFsMTUuODEtMTUuODFjLS4yOC0uNjgtLjYxLTEuMzMtLjk2LTEuOTdsLTE2LjMyLDE2LjMyLDEuNDcsMS40NlpNMTMuNjIsMTcuOTdsNy45Miw3LjkyLDEuNDctMS40Ny03LjkyLTcuOTItMS40NywxLjQ3Wk0yNS4xNywyMi4yN2wtNy45Mi03LjkyLTEuNDcsMS40Nyw3LjkyLDcuOTIsMS40Ny0xLjQ3Wk0yNCw0MS4zMmMtOS41NSwwLTE3LjMyLTcuNzctMTcuMzItMTcuMzJTMTQuNDUsNi42NywyNCw2LjY3YzIuNiwwLDUuMTEuNTYsNy40NCwxLjY4bC44OS0xLjg3Yy0yLjYxLTEuMjUtNS40Mi0xLjg4LTguMzMtMS44OEMxMy4zMSw0LjYsNC42MSwxMy4zLDQuNjEsMjRzOC43LDE5LjQsMTkuNCwxOS40YzcuNjQsMCwxNC41OS00LjUxLDE3LjcxLTExLjQ4bC0xLjg5LS44NWMtMi43OSw2LjIzLTksMTAuMjYtMTUuODIsMTAuMjZaIi8+CiAgICAgIDwvZz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPg=='; const { value = 0, votes = 0 } = ratings.trakt; From 3ceda1bcdafd81971ee33f034d955cd4b92de97c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 20 Jan 2025 03:59:38 +0200 Subject: [PATCH 180/579] New: Parse releases with JPN as Japanese and KOR as Korean --- .../ParserTests/LanguageParserFixture.cs | 4 ++++ src/NzbDrone.Core/Parser/LanguageParser.cs | 14 +++++++++++++- src/NzbDrone.Core/Parser/Parser.cs | 2 +- 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index ecbdfef12f..ec3c2ce890 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -120,6 +120,8 @@ public void should_parse_language_dutch(string postTitle) } [TestCase("Movie.Title.1994.Japanese.1080p.XviD-LOL")] + [TestCase("Movie.Title (1988) 2160p HDR 5.1 Eng - Jpn x265 10bit")] + [TestCase("Movie Title (1985) (1080p.AC3 ITA-ENG-JPN)")] public void should_parse_language_japanese(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); @@ -291,6 +293,8 @@ public void should_parse_language_greek(string postTitle) } [TestCase("Movie.Title.1994.Korean.1080p.XviD-LOL")] + [TestCase("Movie Title [2006] BDRip 720p [Kor Rus] GROUP")] + [TestCase("Movie.Title.2019.KOR.1080p.HDRip.H264.AAC-GROUP")] public void should_parse_language_korean(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index 60cbda36db..f710e9b15a 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -34,7 +34,9 @@ public static class LanguageParser (?\b(?:catalan?|catalán|català)\b)| (?\b(?:lat|lav|lv)\b)| (?\btel\b)| - (?\bVIE\b)", + (?\bVIE\b)| + (?\bJPN\b)| + (?\bKOR\b)", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.IgnorePatternWhitespace); private static readonly Regex CaseSensitiveLanguageRegex = new Regex(@"(?:(?i)(?\bLT\b)| @@ -393,6 +395,16 @@ public static List ParseLanguages(string title) { languages.Add(Language.Vietnamese); } + + if (match.Groups["japanese"].Success) + { + languages.Add(Language.Japanese); + } + + if (match.Groups["korean"].Success) + { + languages.Add(Language.Korean); + } } if (!languages.Any()) diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 76011eab71..e943feb6bb 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -142,7 +142,7 @@ public static class Parser private static readonly Regex CleanQualityBracketsRegex = new Regex(@"\[[a-z0-9 ._-]+\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", + private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex InvalidReleaseGroupRegex = new Regex(@"^([se]\d+|[0-9a-f]{8})$", RegexOptions.IgnoreCase | RegexOptions.Compiled); From 6b81f92137a3a5c70aea293df023eae85a443f80 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 21 Jan 2025 16:11:22 +0200 Subject: [PATCH 181/579] Fixed: Import Movies page crashing on `console.error` with non-string values --- .../ImportMovie/Import/ImportMovieRow.js | 1 - .../SelectMovie/ImportMovieSelectMovie.js | 4 +-- .../src/Store/Actions/importMovieActions.js | 28 +++++++++++++++---- frontend/src/index.ts | 9 +++--- src/NzbDrone.Core/Localization/Core/en.json | 1 + 5 files changed, 31 insertions(+), 12 deletions(-) diff --git a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieRow.js b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieRow.js index 7858b6633d..a419eb40e1 100644 --- a/frontend/src/AddMovie/ImportMovie/Import/ImportMovieRow.js +++ b/frontend/src/AddMovie/ImportMovie/Import/ImportMovieRow.js @@ -81,7 +81,6 @@ ImportMovieRow.propTypes = { selectedMovie: PropTypes.object, isExistingMovie: PropTypes.bool.isRequired, items: PropTypes.arrayOf(PropTypes.object).isRequired, - queued: PropTypes.bool.isRequired, isSelected: PropTypes.bool, onSelectedChange: PropTypes.func.isRequired, onInputChange: PropTypes.func.isRequired diff --git a/frontend/src/AddMovie/ImportMovie/Import/SelectMovie/ImportMovieSelectMovie.js b/frontend/src/AddMovie/ImportMovie/Import/SelectMovie/ImportMovieSelectMovie.js index 6ec718b034..eca2eda874 100644 --- a/frontend/src/AddMovie/ImportMovie/Import/SelectMovie/ImportMovieSelectMovie.js +++ b/frontend/src/AddMovie/ImportMovie/Import/SelectMovie/ImportMovieSelectMovie.js @@ -131,7 +131,7 @@ class ImportMovieSelectMovie extends Component { id={this._buttonId} > { return ( { + const selectedMovie = queued.selectedMovie || data[0]; + dispatch(updateItem({ section, id: queued.id, @@ -158,8 +160,8 @@ export const actionHandlers = handleThunks({ isPopulated: true, error: null, items: data, - queued: false, - selectedMovie: queued.selectedMovie || data[0], + isQueued: false, + selectedMovie, updateOnly: true })); }); @@ -171,7 +173,7 @@ export const actionHandlers = handleThunks({ isFetching: false, isPopulated: false, error: xhr, - queued: false, + isQueued: false, updateOnly: true })); }); @@ -278,7 +280,23 @@ export const actionHandlers = handleThunks({ export const reducers = createHandleActions({ [CANCEL_LOOKUP_MOVIE]: function(state) { - return Object.assign({}, state, { isLookingUpMovie: false }); + queue.splice(0, queue.length); + + const items = state.items.map((item) => { + if (item.isQueued) { + return { + ...item, + isQueued: false + }; + } + + return item; + }); + + return Object.assign({}, state, { + isLookingUpMovie: false, + items + }); }, [CLEAR_IMPORT_MOVIE]: function(state) { diff --git a/frontend/src/index.ts b/frontend/src/index.ts index b9cb9ad848..3ea4ad28ca 100644 --- a/frontend/src/index.ts +++ b/frontend/src/index.ts @@ -23,12 +23,13 @@ const error = console.error; function logError(...parameters: any[]) { const filter = parameters.find((parameter) => { return ( - parameter.includes( + typeof parameter === 'string' && + (parameter.includes( 'Support for defaultProps will be removed from function components in a future major release' ) || - parameter.includes( - 'findDOMNode is deprecated and will be removed in the next major release' - ) + parameter.includes( + 'findDOMNode is deprecated and will be removed in the next major release' + )) ); }); diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index d41c025b02..70cb30ee38 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -975,6 +975,7 @@ "MissingMonitoredAndConsideredAvailable": "Missing (Monitored)", "MissingNoItems": "No missing items", "MissingNotMonitored": "Missing (Unmonitored)", + "Mixed": "Mixed", "Mode": "Mode", "Monday": "Monday", "Monitor": "Monitor", From 55b9477a017b9a5eb72112eeb04653ef065535b7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 22 Jan 2025 00:06:08 +0200 Subject: [PATCH 182/579] Fixed: Cleanup duplicated movie translations --- .../CleanupDuplicateMovieTranslations.cs | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMovieTranslations.cs diff --git a/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMovieTranslations.cs b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMovieTranslations.cs new file mode 100644 index 0000000000..3e9d6ff913 --- /dev/null +++ b/src/NzbDrone.Core/Housekeeping/Housekeepers/CleanupDuplicateMovieTranslations.cs @@ -0,0 +1,27 @@ +using Dapper; +using NzbDrone.Core.Datastore; + +namespace NzbDrone.Core.Housekeeping.Housekeepers +{ + public class CleanupDuplicateMovieTranslations : IHousekeepingTask + { + private readonly IMainDatabase _database; + + public CleanupDuplicateMovieTranslations(IMainDatabase database) + { + _database = database; + } + + public void Clean() + { + using var mapper = _database.OpenConnection(); + + mapper.Execute(@"DELETE FROM ""MovieTranslations"" + WHERE ""Id"" IN ( + SELECT MAX(""Id"") FROM ""MovieTranslations"" + GROUP BY ""MovieMetadataId"", ""Language"" + HAVING COUNT(""Id"") > 1 + )"); + } + } +} From 69a9c7228666ff8f394b27309ec438f0ed3b98f5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 22 Jan 2025 00:14:53 +0200 Subject: [PATCH 183/579] Fixed: Loading movies with duplicated translations --- .../Extensions/IEnumerableExtensions.cs | 13 +++++-------- .../Collections/CollectionController.cs | 2 +- src/Radarr.Api.V3/Movies/MovieController.cs | 2 +- src/Radarr.Api.V3/Movies/MovieEditorController.cs | 2 +- 4 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs index 6eb544c1da..76752f21ef 100644 --- a/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs +++ b/src/NzbDrone.Common/Extensions/IEnumerableExtensions.cs @@ -54,10 +54,8 @@ public static Dictionary ToDictionaryIgnoreDuplicates( foreach (var item in src) { var key = keySelector(item); - if (!result.ContainsKey(key)) - { - result[key] = item; - } + + result.TryAdd(key, item); } return result; @@ -69,10 +67,9 @@ public static Dictionary ToDictionaryIgnoreDuplicates MapToResource(List coll .ToDictionary(x => x.Key, x => (IEnumerable)x); var translations = _movieTranslationService.GetAllTranslationsForLanguage(configLanguage); - var tdict = translations.ToDictionary(x => x.MovieMetadataId); + var tdict = translations.ToDictionaryIgnoreDuplicates(x => x.MovieMetadataId); foreach (var collection in collections) { diff --git a/src/Radarr.Api.V3/Movies/MovieController.cs b/src/Radarr.Api.V3/Movies/MovieController.cs index 33c35988f7..4f48fe66d4 100644 --- a/src/Radarr.Api.V3/Movies/MovieController.cs +++ b/src/Radarr.Api.V3/Movies/MovieController.cs @@ -150,7 +150,7 @@ public List AllMovie(int? tmdbId, bool excludeLocalCovers = false var translations = _movieTranslationService .GetAllTranslationsForLanguage(translationLanguage); - var tdict = translations.ToDictionary(x => x.MovieMetadataId); + var tdict = translations.ToDictionaryIgnoreDuplicates(x => x.MovieMetadataId); var sdict = movieStats.ToDictionary(x => x.MovieId); if (!excludeLocalCovers) diff --git a/src/Radarr.Api.V3/Movies/MovieEditorController.cs b/src/Radarr.Api.V3/Movies/MovieEditorController.cs index d10e5b2d9e..902c224519 100644 --- a/src/Radarr.Api.V3/Movies/MovieEditorController.cs +++ b/src/Radarr.Api.V3/Movies/MovieEditorController.cs @@ -116,7 +116,7 @@ public IActionResult SaveAll([FromBody] MovieEditorResource resource) var availabilityDelay = _configService.AvailabilityDelay; var translations = _movieTranslationService.GetAllTranslationsForLanguage(configLanguage); - var tdict = translations.ToDictionary(x => x.MovieMetadataId); + var tdict = translations.ToDictionaryIgnoreDuplicates(x => x.MovieMetadataId); var updatedMovies = _movieService.UpdateMovie(moviesToUpdate, !resource.MoveFiles); From d923406f0850214d1ee11f8db05e220ce849a74b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 26 Jan 2025 14:48:34 +0200 Subject: [PATCH 184/579] Bump version to 5.18.3 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5653118cb4..c15e32fe60 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.18.2' + majorVersion: '5.18.3' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 10094b4e6613331af4bcb2b129338b27b741426f Mon Sep 17 00:00:00 2001 From: Weblate Date: Sun, 26 Jan 2025 10:33:23 +0000 Subject: [PATCH 185/579] Multiple Translations updated by Weblate MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ignore-downstream Co-authored-by: Craze Co-authored-by: Dimitar \"Topper\" Maznekov Co-authored-by: GkhnGRBZ Co-authored-by: Lizandra Candido da Silva Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: ηg Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fa/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 3 +- src/NzbDrone.Core/Localization/Core/bg.json | 12 ++- src/NzbDrone.Core/Localization/Core/ca.json | 6 +- src/NzbDrone.Core/Localization/Core/cs.json | 33 +++++++- src/NzbDrone.Core/Localization/Core/da.json | 3 +- src/NzbDrone.Core/Localization/Core/de.json | 21 ++++- src/NzbDrone.Core/Localization/Core/el.json | 3 +- src/NzbDrone.Core/Localization/Core/es.json | 3 +- src/NzbDrone.Core/Localization/Core/fa.json | 22 ++++- src/NzbDrone.Core/Localization/Core/fi.json | 33 ++++---- src/NzbDrone.Core/Localization/Core/fr.json | 3 +- src/NzbDrone.Core/Localization/Core/he.json | 3 +- src/NzbDrone.Core/Localization/Core/hi.json | 3 +- src/NzbDrone.Core/Localization/Core/hu.json | 3 +- src/NzbDrone.Core/Localization/Core/is.json | 3 +- src/NzbDrone.Core/Localization/Core/it.json | 3 +- src/NzbDrone.Core/Localization/Core/ja.json | 3 +- src/NzbDrone.Core/Localization/Core/ko.json | 3 +- src/NzbDrone.Core/Localization/Core/nl.json | 3 +- src/NzbDrone.Core/Localization/Core/pl.json | 3 +- src/NzbDrone.Core/Localization/Core/pt.json | 3 +- .../Localization/Core/pt_BR.json | 43 +++++----- src/NzbDrone.Core/Localization/Core/ro.json | 3 +- src/NzbDrone.Core/Localization/Core/ru.json | 4 +- src/NzbDrone.Core/Localization/Core/sv.json | 3 +- src/NzbDrone.Core/Localization/Core/th.json | 3 +- src/NzbDrone.Core/Localization/Core/tr.json | 81 ++++++++++--------- src/NzbDrone.Core/Localization/Core/uk.json | 3 +- src/NzbDrone.Core/Localization/Core/vi.json | 3 +- .../Localization/Core/zh_CN.json | 3 +- 30 files changed, 208 insertions(+), 110 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index a26ea92261..4bb0030108 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1083,5 +1083,6 @@ "AutoTaggingSpecificationStatus": "الحالة", "CustomFormatsSpecificationLanguage": "لغة", "CustomFormatsSpecificationMaximumSize": "أكبر مقاس", - "CustomFormatsSpecificationSource": "مصدر" + "CustomFormatsSpecificationSource": "مصدر", + "Mixed": "ثابت" } diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 851f33ec2f..a0723827a4 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1,6 +1,6 @@ { - "AuthenticationMethodHelpText": "Изисквайте потребителско име и парола за достъп до {appName}", - "AuthForm": "Формуляри (Страница за вход)", + "AuthenticationMethodHelpText": "Изисква потребителско име и парола за достъп до {appName}", + "AuthForm": "Форма (Страница за вход)", "MovieNaming": "Именуване на филми", "OpenBrowserOnStart": "Отворете браузъра при стартиране", "OnHealthIssue": "По здравен въпрос", @@ -730,7 +730,7 @@ "ChmodFolderHelpText": "Осмично, приложено по време на импортиране / преименуване към медийни папки и файлове (без битове за изпълнение)", "ChmodFolderHelpTextWarning": "Това работи само ако потребителят, работещ с {appName}, е собственик на файла. По-добре е да се уверите, че клиентът за изтегляне правилно задава разрешенията.", "ChownGroupHelpText": "Име на група или gid. Използвайте gid за отдалечени файлови системи.", - "AuthBasic": "Основно (изскачащ прозорец на браузъра)", + "AuthBasic": "Базово (изскачащ прозорец на браузъра)", "Authentication": "Удостоверяване", "Announced": "Обявен", "ApplyTags": "Прилагане на тагове", @@ -1191,5 +1191,9 @@ "DownloadClientFloodSettingsRemovalInfo": "{appName} ще се справи с автоматичното премахване на торенти въз основа на текущите критерии за сийд в Настройки -> Индексатори", "DownloadClientAriaSettingsDirectoryHelpText": "Незадължително локация за изтеглянията, оставете празно, за да използвате локацията по подразбиране на Aria2", "BlocklistReleaseHelpText": "Блокира изтеглянето на тази версия от {appName} чрез RSS или автоматично търсене", - "Disposition": "Разпореждане" + "Disposition": "Разпореждане", + "Delay": "Забавяне", + "Label": "Етикет", + "DownloadClientSettingsAddPaused": "Добави на пауза", + "Theme": "Тема" } diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 703e51eb2e..58aec56a69 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1400,5 +1400,9 @@ "CustomFormatsSpecificationMaximumYear": "Any màxim", "CustomFormatsSpecificationMinimumYear": "Any mínim", "CustomFormatsSpecificationResolution": "Resolució", - "CustomFormatsSpecificationSource": "Font" + "CustomFormatsSpecificationSource": "Font", + "Mixed": "Combinat", + "CountCustomFormatsSelected": "{count} format(s) personalitzat(s) seleccionat(s)", + "BlocklistFilterHasNoItems": "El filtre de la llista de bloqueig seleccionat no conté elements", + "CountVotes": "{votes} vots" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index d70d079921..45e5db304e 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1263,5 +1263,36 @@ "UsenetBlackholeNzbFolder": "Složka Nzb", "DownloadClientFloodSettingsAdditionalTags": "Další štítky", "ManualImportSetReleaseGroup": "Ruční import - nastavte skupinu vydání", - "NotificationTriggersHelpText": "Vyber, které události mají vyvolat toto upozornění" + "NotificationTriggersHelpText": "Vyber, které události mají vyvolat toto upozornění", + "CustomFormatsSpecificationMinimumSizeHelpText": "Vydání musí být větší než tato velikost", + "BlocklistAndSearchHint": "Začne hledat náhradu po blokaci", + "CustomFormatsSpecificationExceptLanguage": "Vyjma jazyka", + "CustomFormatsSpecificationExceptLanguageHelpText": "Odpovídá, pokud je přítomen jiný jazyk než vybraný", + "DoNotBlocklist": "Nepřidávat do Seznamu blokování", + "DownloadClientDelugeValidationLabelPluginFailureDetail": "{appName} nemohl(a) přidat etiketu k {clientName}.", + "Mixed": "Pevný", + "BlocklistOnly": "Pouze seznam blokování", + "BlocklistFilterHasNoItems": "Vybraný filtr blokování neobsahuje žádné položky", + "CountCustomFormatsSelected": "{count} vybraný vlastní formát(y)", + "BlocklistAndSearchMultipleHint": "Začne vyhledávat náhrady po blokaci", + "DayOfWeekAt": "{day} v {time}", + "ChangeCategoryMultipleHint": "Změní stahování do kategorie „Post-Import“ z aplikace Download Client", + "DoNotBlocklistHint": "Odstraň bez přidání do seznamu blokování", + "CutoffUnmetLoadError": "Chybné načítání nesplněných položek", + "CutoffUnmetNoItems": "Žádné neodpovídající nesplněné položky", + "ClickToChangeIndexerFlags": "Kliknutím změníte značky indexeru", + "RecycleBinUnableToWriteHealthCheck": "Nelze zapisovat do nakonfigurované složky koše: {path}. Ujistěte se, že tato cesta existuje a že do ní může zapisovat uživatel se spuštěnou {appName}", + "AutoTaggingSpecificationMaximumYear": "Maximální Rok", + "AutoTaggingSpecificationMinimumYear": "Minimální Rok", + "ChangeCategoryHint": "Změní stahování do kategorie „Post-Import“ z aplikace Download Client", + "CustomFormatsSpecificationMaximumSizeHelpText": "Vydání musí odpovídat nebo být menší než tato velikost", + "CustomFormatsSpecificationMaximumYear": "Maximální Rok", + "CustomFormatsSpecificationMinimumYear": "Minimální Rok", + "CustomFormatsSpecificationMinimumSize": "Minimální velikost", + "DownloadClientDelugeSettingsDirectory": "Adresář stahování", + "DownloadClientDelugeValidationLabelPluginFailure": "Konfigurace etikety selhala", + "CountVotes": "{votes} hlasy", + "CustomFormatsSpecificationRegularExpression": "Běžný výraz", + "AutoTaggingSpecificationGenre": "Žánr(y)", + "DeleteSelected": "Smazat vybrané" } diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 39d6595903..0c440d9cd1 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1105,5 +1105,6 @@ "CustomFormatsSpecificationLanguage": "Sprog", "CustomFormatsSpecificationMaximumSize": "Maksimal størrelse", "CustomFormatsSpecificationResolution": "Opløsning", - "CustomFormatsSpecificationSource": "Kilde" + "CustomFormatsSpecificationSource": "Kilde", + "Mixed": "Fast" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 4961ee57ac..7f6d809b83 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -147,7 +147,7 @@ "Week": "Woche", "ICalLink": "iCal Link", "Language": "Sprache", - "MediaManagementSettingsSummary": "Einstellungen für Bennenung und Dateiverwaltung", + "MediaManagementSettingsSummary": "Einstellungen für Benennung und Dateiverwaltung", "Year": "Jahr", "Wanted": "Gesucht", "UpdateSelected": "Auswahl aktualisieren", @@ -457,7 +457,7 @@ "RemoveFilter": "Filter entfernen", "RemoveFromQueue": "Aus der Warteschlange entfernen", "RenameMovies": "Filme umbenennen", - "RenameMoviesHelpText": "Wenn das umbennen deaktiviert ist, wird der vorhandene Dateiname benutzt", + "RenameMoviesHelpText": "Wenn das Umbenennen deaktiviert ist, wird {appName} den vorhandenen Dateiname verwenden.", "Reorder": "Neu anordnen", "ReplaceIllegalCharacters": "Illegale Zeichen ersetzen", "ReplaceIllegalCharactersHelpText": "Ersetze illegale Zeichen. Wenn nicht ausgewählt, werden sie stattdessen von {appName} entfernt", @@ -876,7 +876,7 @@ "HttpHttps": "HTTP(S)", "Hours": "Stunden", "HomePage": "Hauptseite", - "FolderMoveRenameWarning": "Dies wird auch den Filmordner nach dem Filmordnerformat aus den Einstellungen umbennen.", + "FolderMoveRenameWarning": "Dies wird auch den Filmordner nach dem Filmordnerformat aus den Einstellungen umbenennen.", "FeatureRequests": "Feature Anfragen", "FailedToLoadMovieFromAPI": "Film konnte nicht über die API geladen werden", "ExternalUpdater": "{appName} ist so konfiguriert, dass es einen externen Aktualisierungsmechanismus verwendet", @@ -1805,5 +1805,18 @@ "CustomFormatsSpecificationMaximumSizeHelpText": "Das Release muss kleiner oder gleich Groß sein", "CustomFormatsSpecificationMaximumYear": "Höchstjahr", "CustomFormatsSpecificationMinimumSize": "Mindestgröße", - "CustomFormatsSpecificationMinimumSizeHelpText": "Das Release muss größer als diese Größe sein" + "CustomFormatsSpecificationMinimumSizeHelpText": "Das Release muss größer als diese Größe sein", + "AnnouncedMovieAvailabilityDescription": "Filme werden als verfügbar erachtet sobald Sie zu {appName} hinzugefügt werden.", + "AutoTaggingSpecificationMaximumRuntime": "Maximale Laufzeit", + "AutoTaggingSpecificationMinimumRuntime": "Minimale Laufzeit", + "DeleteMovieFolderMovieCount": "{movieFileCount} Film Dateien, total {size}", + "DownloadFailedMovieTooltip": "Der Film Download ist fehlgeschlagen", + "DownloadIgnoredMovieTooltip": "Film Download wurde ignoriert", + "MetadataKometaDeprecatedSetting": "Veraltet", + "NotificationsTelegramSettingsIncludeInstanceName": "Instanzname im Titel einfügen", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Optional den Instanznamen in die Benachrichtigung einfügen", + "Mixed": "Gemischt", + "ReleasePush": "Veröffentlichung-Push", + "ReleaseSource": "Veröffentlichungsquelle", + "UserInvokedSearch": "Benutzerinitiierte Suche" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 78786dfb9f..60ea0eb0d3 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1241,5 +1241,6 @@ "AutoTaggingSpecificationStatus": "Κατάσταση", "CustomFormatsSpecificationLanguage": "Γλώσσα", "CustomFormatsSpecificationMaximumSize": "Μέγιστο μέγεθος", - "CustomFormatsSpecificationSource": "Πηγή" + "CustomFormatsSpecificationSource": "Πηγή", + "Mixed": "Σταθερός" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 10fb59fe75..00244d558c 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1889,5 +1889,6 @@ "CustomFormatsSpecificationMaximumYear": "Año máximo", "AutoTaggingSpecificationMaximumRuntime": "Tiempo de ejecución máximo", "AutoTaggingSpecificationMinimumRuntime": "Tiempo de ejecución mínimo", - "CustomFormatsSpecificationQualityModifier": "Modificador de calidad" + "CustomFormatsSpecificationQualityModifier": "Modificador de calidad", + "Mixed": "Mezclado" } diff --git a/src/NzbDrone.Core/Localization/Core/fa.json b/src/NzbDrone.Core/Localization/Core/fa.json index 0d96703016..2dd35178ee 100644 --- a/src/NzbDrone.Core/Localization/Core/fa.json +++ b/src/NzbDrone.Core/Localization/Core/fa.json @@ -1,3 +1,23 @@ { - "About": "درباره" + "About": "درباره", + "DotNetVersion": ".NET", + "Add": "افزودن", + "AddAutoTag": "افزودن برچسب خودکار", + "AddCondition": "افزودن شرط", + "AddConnectionImplementation": "افزودن پیوند - {implementationName}", + "AddDownloadClientImplementation": "افزودن کلاینت دانلود - {implementationName}", + "AddImportList": "افزودن لیست واردات", + "Docker": "Docker", + "Usenet": "Usenet", + "AddConditionError": "افزودن شرط جدید ناموفق بود، لطفا مجددا تلاش کنید.", + "AddAutoTagError": "افزودن برچسب خودکار جدید ناموفق بود، لطفا مجددا تلاش کنید.", + "AddDelayProfile": "افزودن نمایه تاخیر", + "AddDelayProfileError": "افزودن نمایه تاخیر جدید ناموفق بود، لطفا مجددا تلاش کنید.", + "AddImportListExclusion": "افزودن لیست واردات مستثنی", + "ApiKey": "کلید API", + "Torrents": "تورنت ها", + "AddConditionImplementation": "افزودن شرط - {implementationName}", + "AddConnection": "افزودن پیوند", + "Actions": "اقدامات", + "Activity": "فعالیت" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 63e8e78997..dd2f782d31 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -258,7 +258,7 @@ "Failed": "Epäonnistui", "InCinemas": "Teatterijulkaisu", "IncludeCustomFormatWhenRenaming": "Sisällytä mukautetut muodot uudelleennimettäessä", - "IndexerFlags": "Tietolähteen liput", + "IndexerFlags": "Hakupalvelun liput", "IndexerLongTermStatusCheckSingleClientMessage": "Hakupalvelut eivät ole käytettävissä yli kuusi tuntia kestäneiden virheiden vuoksi: {indexerNames}.", "IndexerStatusCheckAllClientMessage": "Hakupalvelut eivät ole virheiden vuoksi käytettävissä.", "Level": "Taso", @@ -294,7 +294,7 @@ "LastExecution": "Edellinen suoritus", "ListSyncLevelHelpTextWarning": "Elokuvatiedostot poistetaan pysyvästi, mikä voi johtaa kirjaston pyyhkimiseen, jos luettelosi ovat tyhjät", "ImportListExclusions": "Listojen poikkeussäännöt", - "Indexer": "Tietolähde", + "Indexer": "Hakupalvelu", "MovieIsMonitored": "Elokuvaa valvotaan", "Updates": "Päivitykset", "AddImportListExclusion": "Lisää tuontilistapoikkeus", @@ -473,8 +473,8 @@ "DeleteMovieFiles": "Poista {movieFileCount} elokuvatiedostoa", "DeleteHeader": "Poistetaan – {0}", "DeleteImportListExclusion": "Poista tuontilistapoikkeus", - "DeleteIndexer": "Poista tietolähde", - "DeleteIndexerMessageText": "Haluatko varmasti poistaa tietolähteen '{name}'?", + "DeleteIndexer": "Poista hakupalvelu", + "DeleteIndexerMessageText": "Haluatko varmasti poistaa hakupalvelun \"{name}\"?", "DeleteMovieFolderHelpText": "Poista elokuvakansio ja sen sisältö", "DeleteNotification": "Poista ilmoituspalvelu", "DeleteNotificationMessageText": "Haluatko varmasti poistaa ilmoituspalvelun \"{name}\"?", @@ -593,14 +593,14 @@ "IncludeRadarrRecommendations": "Sisällytä {appName}-suositukset", "IncludeRecommendationsHelpText": "Sisällytä {appName}in suosittelemat elokuvat etsintänäkymään", "ImportMovies": "Tuo elokuvia", - "IndexerPriority": "Tietolähteiden painotus", + "IndexerPriority": "Hakupalveluiden painotus", "IndexerPriorityHelpText": "Hakupalvelun painotus, 1– 50 (korkein-alin). Oletusarvo on 25. Käytetään muutoin tasaveroisten julkaisujen kaappauspäätökseen. {appName} käyttää edelleen kaikkia käytössä olevia hakupalveluita RSS-synkronointiin ja hakuun.", - "IndexerRssHealthCheckNoAvailableIndexers": "RSS-syötteitä tukevat tietolähteet eivät ole hiljattaisten tietolähdevirheiden vuoksi tilapaisesti käytettävissä.", + "IndexerRssHealthCheckNoAvailableIndexers": "RSS-syötteitä tukevat hakupalvelut eivät ole tilapäisesti käytettävissä hiljattaisten palveluvirheiden vuoksi.", "IndexerRssHealthCheckNoIndexers": "RSS-synkronoinnille ei ole määritetty hakupalveluita, eikä {appName} tämän vuoksi kaappaa uusia julkaisuja automaattisesti.", - "Indexers": "Tietolähteet", + "Indexers": "Hakupalvelut", "IndexerSearchCheckNoAutomaticMessage": "Automaattihaulle ei ole määritetty hakupalveluita, eikä {appName}in automaattihaku tämän vuoksi löydä tuloksia.", "IndexerSearchCheckNoAvailableIndexersMessage": "Hakua tukevat hakupalvelut eivät ole hiljattaisten hakupalveluvirheiden vuoksi tilapäisesti käytettävissä.", - "IndexerSettings": "Tietolähdeasetukset", + "IndexerSettings": "Hakupalveluasetukset", "IndexerStatusCheckSingleClientMessage": "Hakupalvelut eivät ole virheiden vuoksi käytettävissä: {indexerNames}.", "InstallLatest": "Asenna uusin", "InteractiveImport": "Manuaalinen tuonti", @@ -876,8 +876,8 @@ "Unlimited": "Rajoittamaton", "DownloadClientOptionsLoadError": "Latauspalveluasetusten lataus epäonnistui", "GeneralSettingsLoadError": "Virhe ladattaessa yleisasetuksia.", - "IndexerOptionsLoadError": "Tietolähdeasetusten lataus epäonnistui", - "IndexersLoadError": "Tietolähteiden lataus epäonnistui", + "IndexerOptionsLoadError": "Virhe ladattaessa hakupalveluasetuksia.", + "IndexersLoadError": "Virhe ladattaessa hakupalveluita.", "ImportListExclusionsLoadError": "Tuontilistapoikkeusten lataus epäonnistui", "ListOptionsLoadError": "Virhe ladattaessa lista-asetuksia.", "ImportListsLoadError": "Tuontilistojen lataus epäonnistui", @@ -993,7 +993,7 @@ "DiscordUrlInSlackNotification": "Olet määrittänyt Discordin Slack-ilmoituksena. Määritä se Discord-ilmoituksena parempaa toiminnallisuutta varten. Koskee seuraavia: {0}.", "ManualImportSetReleaseGroup": "Manuaalinen tuonti– Aseta julkaisuryhmä", "AnnouncedMovieDescription": "Elokuva on julkistettu", - "IndexerDownloadClientHelpText": "Määritä tämän tietolähteen kanssa käytettävä latauspalvelu.", + "IndexerDownloadClientHelpText": "Määritä tämän hakupalvelun kanssa käytettävä latauspalvelu.", "SelectLanguages": "Valitse kielet", "SelectReleaseGroup": "Aseta julkaisuryhmä", "SetReleaseGroup": "Aseta julkaisuryhmä", @@ -1128,7 +1128,7 @@ "ManageDownloadClients": "Palveluiden hallinta", "ManageIndexers": "Palveluiden hallinta", "MovieImportedTooltip": "Elokuva ladattiin ja poimittiin latauspalvelulta.", - "NoIndexersFound": "Tietolähteitä ei löytynyt", + "NoIndexersFound": "Hakupalveluita ei löytynyt", "NotificationStatusSingleClientHealthCheckMessage": "Ilmoituspalvelut eivät ole ongelmien vuoksi käytettävissä: {notificationNames}.", "OrganizeNothingToRename": "Valmis! Toiminto on suoritettu, eikä uudelleennimettäviä tiedostoja ole.", "PackageVersionInfo": "{packageVersion} julkaisijalta {packageAuthor}", @@ -1185,7 +1185,7 @@ "RemoveFailedDownloads": "Poista epäonnistuneet lataukset", "UpdaterLogFiles": "Päivittäjän lokitiedostot", "DownloadClientRemovesCompletedDownloadsHealthCheckMessage": "Latauspalvelu {downloadClientName} on määritetty poistamaan valmistuneet lataukset, jonka seuraksena ne saatetaan poistaa ennen kuin {appName} ehtii tuoda niitä.", - "DownloadClientsLoadError": "Latauspalveluiden lataus epäonnistui", + "DownloadClientsLoadError": "Virhe ladattaessa latauspalveluita.", "RemoveSelectedBlocklistMessageText": "Haluatko varmasti poistaa valitut kohteet estolistalta?", "TableOptionsButton": "Taulukon asetuspainike", "AuthenticationRequiredUsernameHelpTextWarning": "Syötä uusi käyttäjätunnus", @@ -1195,7 +1195,7 @@ "EditAutoTag": "Muokkaa automaattimerkintää", "EditConditionImplementation": "Muokataan ehtoa – {implementationName}", "EditImportListImplementation": "Muokataan tuontilistaa – {implementationName}", - "EditIndexerImplementation": "Muokataan tietolähdettä – {implementationName}", + "EditIndexerImplementation": "Muokataan hakupalvelua – {implementationName}", "PendingDownloadClientUnavailable": "Odottaa – Latauspalvelu ei ole käytettävissä", "ApplyChanges": "Toteuta muutokset", "AddRootFolderError": "Virhe lisättäessä juurikansiota.", @@ -1466,7 +1466,7 @@ "Rejections": "Hylkäykset", "CutoffNotMet": "Katkaisutasoa ei ole saavutettu", "IndexerSettingsRejectBlocklistedTorrentHashes": "Hylkää estetyt torrent-hajautusarvot kaapattaessa", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Jos torrent on estetty hajautusarvon perusteella sitä ei välttämättä hylätä oikein joidenkin tietolähteiden RSS-syötteestä tai hausta. Tämän käyttöönotto mahdollistaa tällaisten torrentien hylkäämisen kaappauksen jälkeen, kuitenkin ennen kuin niitä välitetään latauspalvelulle.", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Jos torrent on estetty hajautusarvon perusteella sitä ei välttämättä hylätä oikein joidenkin hakupalveluiden RSS-syötteestä tai hausta. Tämän käyttöönotto mahdollistaa tällaisten torrentien hylkäämisen kaappauksen jälkeen, kuitenkin ennen kuin niitä välitetään latauspalvelulle.", "MovieFileMissingTooltip": "Elokuvatiedosto puuttuu", "NotificationsAppriseSettingsServerUrlHelpText": "Apprise-palvelimen URL-osoite. SIsällytä myös http(s):// ja portti (tarvittaessa).", "NotificationsAppriseSettingsServerUrl": "Apprise-palvelimen URL", @@ -1892,5 +1892,6 @@ "CustomFormatsSpecificationQualityModifier": "Laatumuuttuja", "ReleaseSource": "Julkaisulähde", "UserInvokedSearch": "Käyttäjä herätti haun", - "ReleasePush": "Julkaisun työntö" + "ReleasePush": "Julkaisun työntö", + "Mixed": "Sekoitettu" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 3f8f4a1a77..2df6c96ae0 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1889,5 +1889,6 @@ "Warning": "Avertissement", "NotificationsGotifySettingsPreferredMetadataLink": "Lien de métadonnées préféré", "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Lien de métadonnées pour les clients qui ne prennent en charge qu'un seul lien", - "ManageFormats": "Gérer les formats" + "ManageFormats": "Gérer les formats", + "Mixed": "Mixte" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 149bf43704..0deca2cd23 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1126,5 +1126,6 @@ "CustomFormatsSpecificationMaximumSize": "גודל מקסימלי", "CustomFormatsSpecificationSource": "מָקוֹר", "AutoTaggingSpecificationRootFolder": "תיקיית שורש", - "AutoTaggingSpecificationStatus": "סטָטוּס" + "AutoTaggingSpecificationStatus": "סטָטוּס", + "Mixed": "תוקן" } diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 059112a34d..f6b080cc9b 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1078,5 +1078,6 @@ "AutoTaggingSpecificationStatus": "स्थिति", "CustomFormatsSpecificationLanguage": "भाषा: हिन्दी", "CustomFormatsSpecificationMaximumSize": "अधिकतम आकार", - "CustomFormatsSpecificationSource": "स्रोत" + "CustomFormatsSpecificationSource": "स्रोत", + "Mixed": "फिक्स्ड" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index d5fc922f0b..1bf62edf12 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1464,5 +1464,6 @@ "CustomFormatsSpecificationMinimumSizeHelpText": "A kibocsátásnak nagyobbnak kell lennie ennél a méretnél", "CustomFormatsSpecificationMinimumYear": "Minimum Év", "CustomFormatsSpecificationResolution": "Felbontás", - "CustomFormatsSpecificationSource": "Forrás" + "CustomFormatsSpecificationSource": "Forrás", + "Mixed": "Mixed" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index f97eaf3b50..e50082e567 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1080,5 +1080,6 @@ "CustomFormatsSpecificationLanguage": "Tungumál", "CustomFormatsSpecificationMaximumSize": "Hámarksstærð", "CustomFormatsSpecificationSource": "Heimild", - "AutoTaggingSpecificationQualityProfile": "Gæðaprófíll" + "AutoTaggingSpecificationQualityProfile": "Gæðaprófíll", + "Mixed": "Fastur" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 8cf9592664..c9a93a6b75 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1488,5 +1488,6 @@ "CustomFormatsSpecificationMinimumSizeHelpText": "La release deve essere maggiore di questa dimensione", "CustomFormatsSpecificationMinimumYear": "Anno Minimo", "CustomFormatsSpecificationResolution": "Risoluzione", - "CustomFormatsSpecificationSource": "Fonte" + "CustomFormatsSpecificationSource": "Fonte", + "Mixed": "Fissato" } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 84f5dbf377..17a15116ba 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1080,5 +1080,6 @@ "AutoTaggingSpecificationStatus": "状態", "CustomFormatsSpecificationMaximumSize": "最大サイズ", "CustomFormatsSpecificationSource": "ソース", - "CustomFormatsSpecificationLanguage": "言語" + "CustomFormatsSpecificationLanguage": "言語", + "Mixed": "修繕" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 08234a2be0..7affe795bf 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1892,5 +1892,6 @@ "ReleaseProfiles": "출시 프로필", "RemoveCompletedDownloads": "완료된 다운로드 제거", "RemoveTagsAutomaticallyHelpText": "조건이 충족되지 않으면 태그를 자동으로 제거", - "DownloadClientQbittorrentSettingsSequentialOrder": "순차적 순서" + "DownloadClientQbittorrentSettingsSequentialOrder": "순차적 순서", + "Mixed": "결정된" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index e405f6a186..c28683c81e 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1253,5 +1253,6 @@ "CustomFormatsSpecificationMinimumYear": "Minimum Jaar", "CustomFormatsSpecificationResolution": "Resolutie", "CustomFormatsSpecificationSource": "Bron", - "CustomFormatsSpecificationLanguage": "Taal" + "CustomFormatsSpecificationLanguage": "Taal", + "Mixed": "Opgelost" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index f13390e631..742a50c4e6 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1195,5 +1195,6 @@ "CustomFormatsSpecificationLanguage": "Język", "CustomFormatsSpecificationMaximumSize": "Największy rozmiar", "CustomFormatsSpecificationResolution": "Rozdzielczość", - "CustomFormatsSpecificationSource": "Źródło" + "CustomFormatsSpecificationSource": "Źródło", + "Mixed": "Naprawiony" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index a188001aaf..aba2d9fabd 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1274,5 +1274,6 @@ "CustomFormatsSpecificationLanguage": "Idioma", "CustomFormatsSpecificationMaximumSize": "Tamanho máximo", "CustomFormatsSpecificationResolution": "Resolução", - "CustomFormatsSpecificationSource": "Origem" + "CustomFormatsSpecificationSource": "Origem", + "Mixed": "Corrigido" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 51c10f5f9e..d9cfc9472d 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -16,13 +16,13 @@ "IndexerStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas", "IndexersSettingsSummary": "Indexadores e restrições de lançamento", "IndexerSettings": "Configurações do indexador", - "IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa Interativa habilitada, {appName} não fornecerá resultados para pesquisas interativas", + "IndexerSearchCheckNoInteractiveMessage": "Nenhum indexador disponível com a Pesquisa interativa habilitada, o {appName} não fornecerá resultados de pesquisa interativas", "IndexerSearchCheckNoAvailableIndexersMessage": "Todos os indexadores com capacidade de pesquisa estão temporariamente indisponíveis devido a erros recentes do indexador", "IndexerSearchCheckNoAutomaticMessage": "Nenhum indexador disponível com a Pesquisa automática habilitada, o {appName} não fornecerá nenhum resultado de pesquisa automática", "Indexers": "Indexadores", - "IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com a sincronização RSS habilitada, o {appName} não capturará novos lançamentos automaticamente", + "IndexerRssHealthCheckNoIndexers": "Nenhum indexador disponível com a sincronização RSS habilitada, o {appName} não obterá novos lançamentos automaticamente", "IndexerRssHealthCheckNoAvailableIndexers": "Todos os indexadores compatíveis com RSS estão temporariamente indisponíveis devido a erros recentes do indexador", - "IndexerPriorityHelpText": "Prioridade do indexador de 1 (mais alta) a 50 (mais baixa). Padrão: 25. Usado como um desempate ao capturar lançamentos, o {appName} ainda usará todos os indexadores habilitados para a sincronização RSS e pesquisa", + "IndexerPriorityHelpText": "Prioridade do indexador, de 1 (mais alta) a 50 (mais baixa). Padrão: 25. Usado como um desempate ao obter lançamentos, o {appName} ainda usará todos os indexadores habilitados para sincronização RSS e pesquisa", "IndexerPriority": "Prioridade do indexador", "IndexerLongTermStatusCheckSingleClientMessage": "Indexadores indisponíveis devido a falhas por mais de 6 horas: {indexerNames}", "IndexerLongTermStatusCheckAllClientMessage": "Todos os indexadores estão indisponíveis devido a falhas por mais de 6 horas", @@ -58,7 +58,7 @@ "Images": "Imagens", "IllRestartLater": "Reiniciarei mais tarde", "AddNewRestriction": "Adicionar nova restrição", - "IgnoredHelpText": "O lançamento será rejeitado se contiver um ou mais desses termos (não diferencia maiúsculas de minúsculas)", + "IgnoredHelpText": "O lançamento será rejeitado se contiver um ou mais destes termos (não diferencia maiúsculas e minúsculas)", "IgnoreDeletedMovies": "Não monitorar filmes excluídos", "IgnoredAddresses": "Endereços ignorados", "Ignored": "Ignorado", @@ -338,7 +338,7 @@ "ApplyTagsHelpTextHowToApplyMovies": "Como aplicar etiquetas aos filmes selecionados", "ApplyTags": "Aplicar etiquetas", "Apply": "Aplicar", - "AppDataLocationHealthCheckMessage": "A atualização não será possível para evitar a exclusão de AppData na Atualização", + "AppDataLocationHealthCheckMessage": "Não será possível atualizar para evitar a exclusão de AppData na atualização", "AppDataDirectory": "Diretório AppData", "ApiKey": "Chave da API", "Announced": "Anunciado", @@ -409,7 +409,7 @@ "LoadingMovieFilesFailed": "Falha ao carregar arquivos do filme", "LoadingMovieExtraFilesFailed": "Falha ao carregar arquivos adicionais do filme", "LoadingMovieCreditsFailed": "Falha ao carregar os créditos do filme", - "ListTagsHelpText": "Os itens na lista de etiquetas serão adicionados com", + "ListTagsHelpText": "Etiquetas com as quais os itens de lista serão adicionados", "ListSyncLevelHelpTextWarning": "Os arquivos de filme serão excluídos permanentemente, o que pode resultar na limpeza de sua biblioteca se suas listas estiverem vazias", "ListSyncLevelHelpText": "Os filmes na biblioteca serão tratados com base na sua seleção se saírem de sua(s) lista(s) ou não aparecerem nela(s)", "ImportListsSettingsSummary": "Importe de outra instância do {appName} ou listas do Trakt e gerencie exclusões de listas", @@ -457,7 +457,7 @@ "Add": "Adicionar", "Activity": "Atividade", "Actions": "Ações", - "AcceptConfirmationModal": "Aceitar o pop-up de confirmação", + "AcceptConfirmationModal": "Pop-up Aceitar confirmação", "About": "Sobre", "Analytics": "Análises", "Month": "Mês", @@ -524,7 +524,7 @@ "NoLimitForAnyRuntime": "Sem limite para qualquer duração", "NoLeaveIt": "Não, deixe", "NoHistory": "Não há histórico", - "NoEventsFound": "Não foram encontrados eventos", + "NoEventsFound": "Nenhum evento encontrado", "NoChanges": "Sem alterações", "NoChange": "Sem alteração", "NoBackupsAreAvailable": "Não há backups disponíveis", @@ -712,7 +712,7 @@ "RescanMovieFolderAfterRefresh": "Verificar novamente a pasta do filme após atualizar", "RescanAfterRefreshHelpTextWarning": "O {appName} não detectará automaticamente as alterações nos arquivos se não estiver definido como \"Sempre\"", "RescanAfterRefreshMovieHelpText": "Verificar novamente a pasta de filmes após atualizar o filme", - "RequiredRestrictionHelpText": "O lançamento deve conter pelo menos um desses termos (sem distinção entre maiúsculas e minúsculas)", + "RequiredRestrictionHelpText": "O lançamento deve conter pelo menos um destes termos (não diferencia maiúsculas e minúsculas)", "Required": "Necessário", "ReplaceIllegalCharactersHelpText": "Substituir caracteres ilegais. Se desmarcada, o {appName} irá removê-los", "ReplaceIllegalCharacters": "Substituir Caracteres Ilegais", @@ -1006,7 +1006,7 @@ "TmdbRating": "Avaliação no TMDb", "TmdbVotes": "Votos no TMDb", "ImdbVotes": "Votos no IMDb", - "IndexerJackettAll": "Indexadores que usam o ponto de extremidade \"all\" incompatível do Jackett: {indexerNames}", + "IndexerJackettAll": "Indexadores que usam o ponto de extremidade \"all\" (tudo) incompatível do Jackett: {indexerNames}", "Auto": "Automático", "Duration": "Duração", "ImportList": "Importar lista", @@ -1375,7 +1375,7 @@ "NotificationsMailgunSettingsSenderDomain": "Domínio do Remetente", "NotificationsMailgunSettingsUseEuEndpointHelpText": "Habilite para usar o endpoint EU MailGun", "NotificationsNotifiarrSettingsApiKeyHelpText": "Sua chave API do seu perfil", - "NotificationsNtfySettingsAccessToken": "Token de Acesso", + "NotificationsNtfySettingsAccessToken": "Token de acesso", "NotificationsNtfySettingsClickUrl": "Clique na URL", "NotificationsMailgunSettingsUseEuEndpoint": "Usar EU Endpoint", "NotificationsNtfySettingsPasswordHelpText": "Senha opcional", @@ -1392,9 +1392,9 @@ "NotificationsPlexSettingsAuthToken": "Token de Autenticação", "NotificationsPlexSettingsAuthenticateWithPlexTv": "Autenticar com Plex.tv", "NotificationsPushBulletSettingSenderId": "ID do Remetente", - "NotificationsPushBulletSettingsAccessToken": "Token de Acesso", + "NotificationsPushBulletSettingsAccessToken": "Token de acesso", "NotificationsPushBulletSettingsChannelTagsHelpText": "Lista de etiquetas do canal para enviar notificações", - "NotificationsPushBulletSettingsDeviceIds": "IDs de Dispositivos", + "NotificationsPushBulletSettingsDeviceIds": "IDs de dispositivos", "NotificationsPushBulletSettingsDeviceIdsHelpText": "Lista de IDs de dispositivos (deixe em branco para enviar a todos os dispositivos)", "NotificationsPushcutSettingsApiKeyHelpText": "As chaves de API podem ser gerenciadas na visualização da conta do aplicativo Pushcut", "NotificationsPushcutSettingsNotificationName": "Nome da Notificação", @@ -1433,11 +1433,11 @@ "NotificationsTelegramSettingsSendSilently": "Enviar Silenciosamente", "NotificationsTelegramSettingsSendSilentlyHelpText": "Envia a mensagem silenciosamente. Os usuários receberão uma notificação sem som", "NotificationsTelegramSettingsTopicId": "ID do Tópico", - "NotificationsTraktSettingsAccessToken": "Token de Acesso", + "NotificationsTraktSettingsAccessToken": "Token de acesso", "NotificationsTraktSettingsAuthenticateWithTrakt": "Autenticar com Trakt", "NotificationsTraktSettingsExpires": "Expira", "NotificationsTraktSettingsRefreshToken": "Atualizar token", - "NotificationsTwitterSettingsAccessToken": "Token de Acesso", + "NotificationsTwitterSettingsAccessToken": "Token de acesso", "NotificationsTwitterSettingsAccessTokenSecret": "Segredo do Token de Acesso", "NotificationsTwitterSettingsConnectToTwitter": "Conecte-se ao Twitter / X", "NotificationsTwitterSettingsConsumerKeyHelpText": "Chave do consumidor de um aplicativo do Twitter", @@ -1452,7 +1452,7 @@ "NotificationsTwitterSettingsMention": "Mencionar", "NotificationsTwitterSettingsMentionHelpText": "Mencione este usuário nos tweets enviados", "NotificationsValidationInvalidAccessToken": "O token de acesso é inválido", - "NotificationsValidationInvalidApiKey": "A chave de API é inválida", + "NotificationsValidationInvalidApiKey": "A chave da API é inválida", "NotificationsValidationInvalidAuthenticationToken": "O token de autenticação é inválido", "NotificationsValidationInvalidHttpCredentials": "As credenciais de autenticação HTTP são inválidas: {exceptionMessage}", "NotificationsValidationInvalidUsernamePassword": "Nome de usuário ou senha inválidos", @@ -1487,8 +1487,8 @@ "NotificationsValidationUnableToConnectToApi": "Não foi possível conectar-se à API {service}. Falha na conexão do servidor: ({responseCode}) {exceptionMessage}", "DownloadClientAriaSettingsDirectoryHelpText": "Local opcional para colocar downloads, deixe em branco para usar o local padrão do Aria2", "MovieFileMissingTooltip": "Arquivo de filme ausente", - "IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeitar hashes de torrent bloqueados durante a captura", - "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se um torrent for bloqueado por hash, pode não ser rejeitado corretamente durante o RSS/Pesquisa de alguns indexadores. Ativar isso permitirá que ele seja rejeitado após o torrent ser capturado, mas antes de ser enviado ao cliente.", + "IndexerSettingsRejectBlocklistedTorrentHashes": "Rejeitar hashes de torrents bloqueados durante a obtenção", + "IndexerSettingsRejectBlocklistedTorrentHashesHelpText": "Se um torrent for bloqueado por hash, pode não ser rejeitado corretamente durante a Sincronização RSS/Pesquisa em alguns indexadores. Ativar isso permitirá que ele seja rejeitado após obter o torrent, mas antes de enviar ao cliente.", "DownloadClientPriorityHelpText": "Prioridade do cliente de download de 1 (mais alta) a 50 (mais baixa). Padrão: 1. Usamos uma distribuição equilibrada para clientes com a mesma prioridade.", "ReleaseGroups": "Grupos do Lançamento", "CutoffNotMet": "Corte Não Alcançado", @@ -1745,7 +1745,7 @@ "NotificationsTelegramSettingsIncludeAppName": "Incluir {appName} no Título", "NotificationsTelegramSettingsIncludeAppNameHelpText": "Opcionalmente, prefixe o título da mensagem com {appName} para diferenciar notificações de diferentes aplicativos", "IndexerSettingsMultiLanguageReleaseHelpText": "Quais idiomas normalmente estão em um lançamento multi neste indexador?", - "IndexerSettingsMultiLanguageRelease": "Multi Idiomas", + "IndexerSettingsMultiLanguageRelease": "Vários idiomas", "EditionFootNote": "Opcionalmente, controle o truncamento para um número máximo de bytes, incluindo reticências (`...`). Truncar do final (por exemplo, `{Edition Tags:30}`) ou do início (por exemplo, `{Edition Tags:-30}`) é suportado.", "MovieFootNote": "Opcionalmente, controle o truncamento para um número máximo de bytes, incluindo reticências (`...`). Truncar do final (por exemplo, `{Movie Title:30}`) ou do início (por exemplo, `{Movie Title:-30}`) é suportado.", "ReleaseGroupFootNote": "Opcionalmente, controle o truncamento para um número máximo de bytes, incluindo reticências (`...`). Truncar do final (por exemplo, `{Release Group:30}`) ou do início (por exemplo, `{Release Group:-30}`) é suportado.`).", @@ -1866,7 +1866,7 @@ "DownloadClientUnavailable": "Cliente de download indisponível", "NotificationsSettingsWebhookHeaders": "Cabeçalhos", "MetadataKometaDeprecatedSetting": "Deprecado", - "MetadataKometaDeprecated": "Os arquivos Kometa não serão mais criados, o suporte será completamente removido na v6", + "MetadataKometaDeprecated": "Não criaremos mais arquivos Kometa, o suporte será completamente removido na v6", "NotificationsTelegramSettingsIncludeInstanceName": "Incluir nome da instância no título", "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Opcionalmente, inclua o nome da instância na notificação", "NotificationsTelegramSettingsMetadataLinks": "Links de metadados", @@ -1892,5 +1892,6 @@ "CustomFormatsSpecificationQualityModifier": "Modificador de Qualidade", "ReleasePush": "Impulsionar Lançamento", "ReleaseSource": "Fonte do Lançamento", - "UserInvokedSearch": "Pesquisa Invocada pelo Usuário" + "UserInvokedSearch": "Pesquisa Invocada pelo Usuário", + "Mixed": "Misturado" } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index a3433f66c4..a3ec0b1efd 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1159,5 +1159,6 @@ "CustomFormatsSpecificationLanguage": "Limbă", "CustomFormatsSpecificationMaximumSize": "Dimensiune maximă", "CustomFormatsSpecificationSource": "Sursă", - "AutoTaggingSpecificationOriginalLanguage": "Limbă" + "AutoTaggingSpecificationOriginalLanguage": "Limbă", + "Mixed": "Fix" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 71b3a4cd6c..67978b8684 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1807,5 +1807,7 @@ "CustomFormatsSpecificationMinimumSizeHelpText": "Релиз должен быть больше этого размера", "CustomFormatsSpecificationMinimumYear": "Минимальный год", "CustomFormatsSpecificationResolution": "Разрешение", - "CustomFormatsSpecificationSource": "Исходный код" + "CustomFormatsSpecificationSource": "Исходный код", + "CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного", + "Mixed": "Смешанный" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index ac0c1eab72..2c0a295bcf 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1107,5 +1107,6 @@ "CustomFormatsSpecificationLanguage": "Språk", "CustomFormatsSpecificationMaximumSize": "Maximal storlek", "CustomFormatsSpecificationSource": "Källa", - "AutoTaggingSpecificationOriginalLanguage": "Språk" + "AutoTaggingSpecificationOriginalLanguage": "Språk", + "Mixed": "Fast" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index d54cb37827..be8d234eef 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1078,5 +1078,6 @@ "AutoTaggingSpecificationStatus": "สถานะ", "CustomFormatsSpecificationLanguage": "ภาษา", "CustomFormatsSpecificationMaximumSize": "ขนาดสูงสุด", - "CustomFormatsSpecificationSource": "ที่มา" + "CustomFormatsSpecificationSource": "ที่มา", + "Mixed": "แก้ไขแล้ว" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index e9486fdcbf..70086b8049 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -134,7 +134,7 @@ "LastWriteTime": "Son Yazma Zamanı", "Languages": "Diller", "Language": "Dil", - "InCinemas": "Sinemada Yayınlanan", + "InCinemas": "Sinemalarda", "ImportMechanismHealthCheckMessage": "Tamamlanan İndirme İşlemini Etkinleştir", "ICalLink": "iCal Bağlantısı", "History": "Geçmiş", @@ -150,7 +150,7 @@ "Edit": "Düzenle", "Downloaded": "İndirildi", "DownloadClientCheckUnableToCommunicateMessage": "{downloadClientName} ile iletişim kurulamıyor. {errorMessage}", - "DigitalRelease": "Dijital Yayınlanan", + "DigitalRelease": "Dijital Yayın", "DelayProfiles": "Gecikme Profilleri", "CustomFilters": "Özel Filtreler", "ConnectSettingsSummary": "Bildirimler, medya sunucularına/oynatıcılara bağlantılar ve özel komut dosyaları", @@ -229,7 +229,7 @@ "FocusSearchBox": "Arama Kutusuna Odaklan", "Folders": "Klasörler", "FollowPerson": "Kişiyi Takip Et", - "GrabReleaseMessageText": "{appName}, bu yayının hangi film için olduğunu belirleyemedi. {appName} bu yayını otomatik olarak içe aktaramayabilir. '{0}'ı almak istiyor musunuz?", + "GrabReleaseMessageText": "{appName} bu sürümün hangi film için olduğunu belirleyemedi. {appName} bu sürümü otomatik olarak içe aktaramayabilir. '{0}' almak ister misiniz?", "IndexerPriority": "İndeksleyici Önceliği", "IndexerSearchCheckNoAvailableIndexersMessage": "Son zamanlardaki indeksleyici hataları nedeniyle tüm arama yeteneğine sahip indeksleyiciler geçici olarak kullanılamıyor", "InstallLatest": "En Sonu Yükle", @@ -351,7 +351,7 @@ "UpgradeUntil": "Kaliteye Kadar Yükseltme", "UpgradeUntilThisQualityIsMetOrExceeded": "Bu kalite karşılanana veya aşılana kadar yükseltin", "UrlBaseHelpText": "Ters proxy desteği için varsayılan boştur", - "UseHardlinksInsteadOfCopy": "Kopyalama yerine Sabit Bağlantıları Kullanın", + "UseHardlinksInsteadOfCopy": "Kopyalama yerine Sabit Bağlantıları Kullan", "UsenetDelay": "Usenet Gecikmesi", "UsenetDelayHelpText": "Usenet'ten bir yayın almadan önce beklemek için dakika cinsinden gecikme", "UsenetDelayTime": "Usenet Gecikmesi: {usenetDelay}", @@ -407,7 +407,7 @@ "QualityProfileInUseMovieListCollection": "Bir filme eklenmiş kaliteli bir profili silemezsiniz", "QueueIsEmpty": "Kuyruk boş", "CalendarFeed": "{appName} Takvim Beslemesi", - "DownloadPropersAndRepacksHelpTextCustomFormat": "Uygunluk ve Yeniden Paketlemeler üzerinden özel format puanına göre sıralamak için \"Tercih Etme\" seçeneğini kullanın", + "DownloadPropersAndRepacksHelpTextCustomFormat": "Özel format derecelendirmelerini Propers/Repacks aracılığıyla sıralamak için \"Tercih Etme\" seçeneğini kullanın", "Tomorrow": "Yarın", "DotNetVersion": ".NET", "NoHistory": "Geçmiş bulunamadı", @@ -594,7 +594,7 @@ "AddRemotePathMapping": "Uzak Yol Eşleme Ekleme", "AudioInfo": "Ses Bilgisi", "Cancel": "Vazgeç", - "PhysicalRelease": "Fiziksel Yayınlanan", + "PhysicalRelease": "Fiziksel Yayın", "Port": "Port No", "Close": "Kapat", "PortNumber": "Port numarası", @@ -650,12 +650,12 @@ "CopyToClipboard": "Panoya kopyala", "CopyUsingHardlinksMovieHelpText": "Sabit bağlantılar, {appName}'in fazladan disk alanı kaplamadan veya dosyanın tüm içeriğini kopyalamadan seed edilen torrentleri film klasörüne aktarmasına olanak tanır. Sabit bağlantılar yalnızca kaynak ve hedef aynı birimdeyse çalışır", "CouldNotFindResults": "'{term}' için herhangi bir sonuç bulunamadı", - "CreateEmptyMovieFolders": "Boş film klasörleri oluşturun", + "CreateEmptyMovieFolders": "Boş film klasörleri oluştur", "CreateGroup": "Grup oluştur", "CurrentlyInstalled": "Şuan Kurulu", "Custom": "Özel", "CustomFormat": "Özel Format", - "CustomFormatHelpText": "{appName}, özel formatlarla eşleşen puanların toplamını kullanarak her yayını puanlar. Yeni bir yayının, puanı aynı veya daha iyi kalitede iyileştirecekse, {appName} onu alacaktır.", + "CustomFormatHelpText": "{appName}, eşleşen özel formatların puanlarının toplamını kullanarak her sürümü puanlar. Yeni bir sürüm puanı aynı veya daha iyi kalitede iyileştirirse, {appName} onu alacaktır.", "CustomFormatScore": "Özel Format Puanı", "CustomFormatsSettings": "Özel Format Ayarları", "CustomFormatUnknownConditionOption": "'{implementation}' koşulu için bilinmeyen seçenek '{key}'", @@ -669,7 +669,7 @@ "DelayProfile": "Gecikme Profilleri", "DeleteDelayProfile": "Gecikme Profilini Sil", "DeleteDownloadClientMessageText": "'{name}' indirme istemcisini silmek istediğinizden emin misiniz?", - "DeleteEmptyFolders": "Boş klasörleri silin", + "DeleteEmptyFolders": "Boş klasörleri sil", "DeleteEmptyFoldersHelpText": "Disk taraması sırasında ve film dosyaları silindiğinde boş film klasörlerini silin", "DeleteFile": "Dosyayı sil", "DeleteImportListExclusion": "İçe Aktarma Listesi Hariç Tutmasını Sil", @@ -686,7 +686,7 @@ "Discord": "Discord", "Docker": "Docker", "Donations": "Bağış", - "DoNotPrefer": "Tercih etmeme", + "DoNotPrefer": "Tercih Etme", "DoNotUpgradeAutomatically": "Otomatik Olarak Yükseltme", "DownloadClient": "İndirme İstemcisi", "DownloadClientCheckNoneAvailableMessage": "İndirme istemcisi mevcut değil", @@ -698,9 +698,9 @@ "DownloadedButNotMonitored": "İndirildi (Takip Edilmiyor)", "DownloadFailed": "Yükleme başarısız", "Downloading": "İndiriliyor", - "DownloadPropersAndRepacks": "Uygunluj ve Yeniden Paketlemeler", - "DownloadPropersAndRepacksHelpText": "Propers / Repacks'e otomatik olarak yükseltme yapılıp yapılmayacağı", - "DownloadPropersAndRepacksHelpTextWarning": "Propers / Repacks'e otomatik yükseltmeler için özel formatlar kullanın", + "DownloadPropersAndRepacks": "Propers ve Repacks", + "DownloadPropersAndRepacksHelpText": "Otomatik olarak Proper/Repacks'e güncellenip güncellenmeyeceği", + "DownloadPropersAndRepacksHelpTextWarning": "Propers/Repacks'e otomatik yükseltmeler için özel formatlar kullanın", "DownloadWarning": "İndirme Uyası: {warningMessage}", "EditImportListExclusion": "Hariç Tutulanlar Listesini Düzenle", "EditMovie": "Filmi Düzenle", @@ -748,7 +748,7 @@ "Global": "Küresel", "GoToInterp": "{0}'a git", "Grabbed": "Alındı", - "GrabRelease": "Yayın Alma", + "GrabRelease": "Sürüm Yakala", "Group": "Grup", "HardlinkCopyFiles": "Hardlink / Dosyaları Kopyala", "NoIssuesWithYourConfiguration": "Yapılandırmanızla ilgili sorun yok", @@ -760,7 +760,7 @@ "IgnoredHelpText": "Bir veya daha fazla terim içeriyorsa izin reddedilecektir (büyük / küçük harfe duyarlı değildir)", "Images": "Görüntüler", "IMDb": "IMDb", - "Import": "İçe Aktarılacak", + "Import": "İçe Aktar", "ImportCustomFormat": "Özel Formatı İçe Aktar", "ImportedTo": "İçeri Aktarıldı", "ImportRootPath": "{appName}'ı belirli bir filmi değil, tüm filmlerinizi içeren klasöre yöneltin. Örneğin. {1} değil {0}. Ek olarak, her film kök / kitaplık klasöründe kendi klasöründe olmalıdır.", @@ -770,9 +770,9 @@ "IncludeRecommendationsHelpText": "{appName} tarafından önerilen filmleri keşif görünümüne dahil et", "IncludeUnmonitored": "Takip Edilmeyenleri Dahil Et", "ImportMovies": "Filmleri İçe Aktar", - "IndexerPriorityHelpText": "İndeksleyici Önceliği (En Yüksek) 1'den (En Düşük) 50'ye kadar. Varsayılan: 25'dir. Eşit olmayan yayınlar için eşitlik bozucu olarak yayınlar alınırken kullanılan {appName}, RSS Senkronizasyonu ve Arama için etkinleştirilmiş tüm indeksleyicileri kullanmaya devam edecek", + "IndexerPriorityHelpText": "Dizinleyici Önceliği 1 (En Yüksek) ile 50 (En Düşük) arasında. Varsayılan: 25. {appName}, aksi takdirde eşit sürümler için bir eşitlik bozucu olarak sürümleri alırken kullanılır, RSS Senkronizasyonu ve Arama için tüm etkin dizinleyicileri kullanmaya devam eder", "IndexerRssHealthCheckNoAvailableIndexers": "Son zamanlardaki indeksleyici hataları nedeniyle tüm rss uyumlu indeksleyiciler geçici olarak kullanılamıyor", - "IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonunun etkin olduğu indeksleyici bulunamadı, {appName} yeni yayınlar otomatik olarak almayacak", + "IndexerRssHealthCheckNoIndexers": "RSS senkronizasyonu etkinleştirildiğinde dizinleyiciler kullanılamaz, {appName} yeni sürümleri otomatik olarak almayacaktır", "Indexers": "İndeksleyiciler", "IndexerSearchCheckNoAutomaticMessage": "Otomatik Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir otomatik arama sonucu sağlamayacaktır", "IndexerSearchCheckNoInteractiveMessage": "Etkileşimli Arama etkinleştirildiğinde hiçbir indeksleyici kullanılamaz, {appName} herhangi bir etkileşimli arama sonucu sağlamayacaktır", @@ -913,7 +913,7 @@ "LongDateFormat": "Uzun Tarih Formatı", "ShowRelativeDatesHelpText": "Göreceli (Bugün/Dün/vb.) veya mutlak tarihleri göster", "WeekColumnHeaderHelpText": "Aktif görünüm hafta olduğunda her bir sütunun üzerinde gösterilir", - "ICalShowAsAllDayEvents": "Tüm Gün Olayları Olarak Göster", + "ICalShowAsAllDayEvents": "Tüm Gün Etkinlikleri olarak göster", "ShowMovieInformation": "Film Bilgilerini Göster", "ShowSearch": "Aramayı Göster", "ShowSearchHelpText": "Fareyle üzerine gelindiğinde arama düğmesini göster", @@ -955,11 +955,11 @@ "More": "Daha", "Download": "İndir", "DownloadClientRootFolderHealthCheckMessage": "İndirme istemcisi {downloadClientName}, indirmeleri kök klasöre yerleştirir {rootFolderPath}. Bir kök klasöre indirmemelisiniz.", - "Blocklist": "Engellenenler listesi", - "BlocklistRelease": "Kara Liste Sürümü", + "Blocklist": "Kara Liste", + "BlocklistRelease": "Sürüm Engelleme Seçeneği", "RemoveFromBlocklist": "Kara listeden kaldır", "Blocklisted": "Kara liste", - "BlocklistReleases": "Kara Liste Sürümü", + "BlocklistReleases": "Sürüm Engelleme Seçenekleri", "ImportList": "Listeler", "Filters": "Filtreler", "Rating": "Puan", @@ -988,7 +988,7 @@ "AddDownloadClientImplementation": "İndirme İstemcisi Ekle - {implementationName}", "AddImportList": "İçe Aktarım Listesi Ekle", "AddImportListImplementation": "İçe Aktarım Listesi Ekle -{implementationName}", - "AddReleaseProfile": "Yayın Profili Ekle", + "AddReleaseProfile": "Sürüm Profili Ekle", "CollectionOptions": "Koleksiyon Seçenekleri", "AutoRedownloadFailedFromInteractiveSearch": "Etkileşimli Arama'dan Başarısız İndirmeleri Yenile", "AutoTaggingNegateHelpText": "İşaretlenirse, {implementationName} koşulu eşleştiğinde otomatik etiketleme kuralı uygulanmayacaktır.", @@ -1005,10 +1005,10 @@ "AnnouncedMovieDescription": "Film duyuruldu", "AutomaticAdd": "Otomatik Ekle", "CollectionShowOverviewsHelpText": "Koleksiyonda genel bakışı göster", - "BlocklistAndSearchHint": "Engellenenler listesine ekledikten sonra yenisini aramaya başlayın", - "BlocklistAndSearchMultipleHint": "Engellenenler listesine ekledikten sonra yedekleri aramaya başlayın", - "BlocklistAndSearch": "Engellenenler Listesi ve Arama", - "BlocklistOnly": "Yalnızca Engellenenler Listesi", + "BlocklistAndSearchHint": "Kara Listeye ekledikten sonra yenisini aramaya başla", + "BlocklistAndSearchMultipleHint": "Kara liste aldıktan sonra yedekler için aramalara başla", + "BlocklistAndSearch": "Kara Liste Al ve Ara", + "BlocklistOnly": "Sadece Kara Listeye Al", "BlocklistOnlyHint": "Yenisini aramadan engelleme listesi", "BlocklistMultipleOnlyHint": "Yedekleri aramadan engelleme listesi", "CountImportListsSelected": "{count} içe aktarma listesi seçildi", @@ -1028,14 +1028,14 @@ "AuthenticationRequiredPasswordConfirmationHelpTextWarning": "Yeni şifreyi onayla", "BypassDelayIfAboveCustomFormatScoreMinimumScore": "Minimum Özel Format Puanı", "BypassDelayIfAboveCustomFormatScoreMinimumScoreHelpText": "Tercih edilen protokolde gecikmeyi atlamak için gereken Minimum Özel Format Puanı", - "BypassDelayIfAboveCustomFormatScoreHelpText": "Yayının puanı, yapılandırılan minimum özel format puanından yüksek olduğunda bypass'ı etkinleştirin", - "ClearBlocklistMessageText": "Engellenenler listesindeki tüm öğeleri temizlemek istediğinizden emin misiniz?", + "BypassDelayIfAboveCustomFormatScoreHelpText": "Sürümün yapılandırılmış minimum özel biçim puanından daha yüksek bir puanı olduğunda baypası etkinleştir", + "ClearBlocklistMessageText": "Kara listenin içerdiği tüm öğeleri temizlemek istediğinizden emin misiniz?", "CloneAutoTag": "Otomatik Etiketi Klonla", "ChooseImportMode": "İçe Aktarma Modunu Seçin", - "ClearBlocklist": "Engellenenler listesini temizle", + "ClearBlocklist": "Kara listeyi temizle", "AudioLanguages": "Ses Dilleri", - "BlocklistReleaseHelpText": "Bu yayın {appName} tarafından RSS veya Otomatik Arama yoluyla yeniden indirilmesi engelleniyor", - "BlocklistLoadError": "Engellenenler listesi yüklenemiyor", + "BlocklistReleaseHelpText": "Bu sürümün {appName} tarafından RSS veya Otomatik Arama yoluyla yeniden indirilmesini engeller", + "BlocklistLoadError": "Kara liste yüklenemiyor", "CountDownloadClientsSelected": "{count} indirme istemcisi seçildi", "AuthenticationRequiredHelpText": "İstekler için Kimlik doğrulamanın gereklilik ayarını değiştirin. Riskleri anlamadığınız sürece değiştirmeyin.", "AuthenticationRequiredWarning": "Kimlik doğrulaması olmadan uzaktan erişimi engellemek için, {appName}'da artık kimlik doğrulamanın etkinleştirilmesini gerektiriyor. İsteğe bağlı olarak yerel adresler için kimlik doğrulamayı devre dışı bırakabilirsiniz.", @@ -1043,7 +1043,7 @@ "AuthenticationMethod": "Kimlik Doğrulama Yöntemi", "AuthenticationMethodHelpTextWarning": "Lütfen geçerli bir kimlik doğrulama yöntemi seçin", "ClickToChangeIndexerFlags": "İndeksleyici bayraklarını değiştirmek için tıklayın", - "BypassDelayIfHighestQualityHelpText": "Tercih edilen protokolle kalite profilinde en yüksek etkin kaliteye sahip yayın olduğunda gecikmeyi atlayın", + "BypassDelayIfHighestQualityHelpText": "Tercih edilen protokol ile kalite profilinde sürüm en yüksek etkin kaliteye sahip olduğunda gecikmeyi atla", "AutoTaggingRequiredHelpText": "Otomatik etiketleme kuralının uygulanabilmesi için bu {implementationName} koşulunun eşleşmesi gerekir. Aksi takdirde tek bir {implementationName} eşleşmesi yeterlidir.", "CustomFilter": "Özel Filtre", "ApplyTagsHelpTextAdd": "Ekle: Etiketleri mevcut etiket listesine ekleyin", @@ -1080,7 +1080,7 @@ "DeleteSelectedMovieFilesHelpText": "Seçilen film dosyalarını silmek istediğinizden emin misiniz?", "DeletedReasonUpgrade": "Bir yükseltmeyi içe aktarmak için dosya silindi", "AutoTaggingSpecificationTag": "Etiket", - "CustomFormatsSettingsTriggerInfo": "Bir yayına veya dosyaya, seçilen farklı koşul türlerinden en az biriyle eşleştiğinde Özel Format uygulanacaktır.", + "CustomFormatsSettingsTriggerInfo": "Özel Biçim, seçilen farklı koşul türlerinden en az biriyle eşleştiğinde bir sürüme veya dosyaya uygulanır.", "CutoffNotMet": "Kesinti Karşılanmadı", "Default": "Varsayılan", "Dash": "Çizgi", @@ -1090,9 +1090,9 @@ "Directory": "Dizin", "Donate": "Bağış yap", "DeleteImportListExclusionMessageText": "Bu içe aktarma listesi hariç tutma işlemini silmek istediğinizden emin misiniz?", - "DoNotBlocklist": "Engelleme Listesine Eklemeyin", + "DoNotBlocklist": "Engelleme Listesine Ekleme", "DiscordUrlInSlackNotification": "Slack bildirimi olarak bir Discord bildirim kurulumunuz var. Daha iyi işlevsellik için bunu bir Discord bildirimi olarak ayarlayın. Etkilenen bildirimler şunlardır: {0}", - "DoNotBlocklistHint": "Engellenenler listesine eklemeden kaldır", + "DoNotBlocklistHint": "Kara listeye almadan kaldır", "Database": "Veri tabanı", "DownloadClientDelugeSettingsUrlBaseHelpText": "Deluge json URL'sine bir önek ekler, bkz. {url}", "DownloadClientDelugeValidationLabelPluginFailure": "Etiket yapılandırılması başarısız oldu", @@ -1394,7 +1394,7 @@ "IgnoreDownloads": "İndirilenleri Yoksay", "ListQualityProfileHelpText": "Kalite Profili liste öğeleri eklenecektir", "ListRootFolderHelpText": "Kök Klasör listesi öğeleri eklenecek", - "MustContainHelpText": "Yayın, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarsız)", + "MustContainHelpText": "Sürüm, bu terimlerden en az birini içermelidir (büyük/küçük harfe duyarlı değildir)", "NewNonExcluded": "Yeni Hariç Tutulmayanlar", "NotificationsAppriseSettingsStatelessUrls": "Apprise Durum bilgisi olmayan URL'ler", "NotificationsDiscordSettingsAuthor": "Yazar", @@ -1426,7 +1426,7 @@ "NotificationsNotifiarrSettingsApiKeyHelpText": "Profilinizdeki API anahtarınız", "Menu": "Menü", "MovieSearchResultsLoadError": "Bu film aramasına ilişkin sonuçlar yüklenemiyor. Daha sonra tekrar deneyin", - "MustNotContainHelpText": "Yayın, bir veya daha fazla terim içeriyorsa reddedilir (büyük/ küçük harfe duyarsız)", + "MustNotContainHelpText": "Sürüm, bir veya daha fazla terim içeriyorsa reddedilir (büyük/ küçük harfe duyarsız)", "Never": "Asla", "NoHistoryFound": "Geçmiş bulunamadı", "NotificationsAppriseSettingsPasswordHelpText": "HTTP Temel Kimlik Doğrulama Parolası", @@ -1662,7 +1662,7 @@ "Waiting": "Bekleniyor", "SetReleaseGroup": "Yayımlama Grubunu Ayarla", "RemoveSelectedItemsQueueMessageText": "{selectedCount} öğeyi kuyruktan kaldırmak istediğinizden emin misiniz?", - "RemoveSelectedBlocklistMessageText": "Seçilen öğeleri engellenenler listesinden kaldırmak istediğinizden emin misiniz?", + "RemoveSelectedBlocklistMessageText": "Seçilen öğeleri kara listeden kaldırmak istediğinizden emin misiniz?", "RemoveTagsAutomatically": "Otomatik Etiketlemeyi Kaldır", "RemotePathMappingsInfo": "Uzak Yol Eşlemeleri çok nadiren gereklidir, {appName} ve indirme istemciniz aynı sistemdeyse yollarınızı eşleştirmeniz daha iyidir. Daha fazla bilgi için [wiki]({wikiLink}) adresini ziyaret edin.", "ResetDefinitions": "Tanımları Sıfırla", @@ -1822,7 +1822,7 @@ "CustomFormatsSpecificationExceptLanguageHelpText": "Seçilen dil dışında herhangi bir dil mevcutsa eşleşir", "CustomFormatsSpecificationExceptLanguage": "Dil Dışında", "Logout": "Çıkış", - "NoBlocklistItems": "Engellenenler listesi öğesi yok", + "NoBlocklistItems": "Kara Listeye henüz öğe alınmadı", "LastSearched": "Son Aranan", "ShowTraktRatingPosterHelpText": "Poster altında Trakt derecelendirmesini göster", "FolderNameTokens": "Klasör Adı Belirteçleri", @@ -1892,5 +1892,6 @@ "CustomFormatsSpecificationQualityModifier": "Kalite Değiştirici", "ReleaseSource": "Yayın Kaynağı", "UserInvokedSearch": "Kullanıcı Tarafından Çağrılan Arama", - "ReleasePush": "Yayın İtimi" + "ReleasePush": "Yayın İtimi", + "Mixed": "Karışık" } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 7b9680e79d..56af611822 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1308,5 +1308,6 @@ "CustomFormatsSpecificationMinimumYear": "Мінімальний рік", "CustomFormatsSpecificationResolution": "Роздільна здатність", "CustomFormatsSpecificationSource": "Джерело", - "AutoTaggingSpecificationOriginalLanguage": "Мова" + "AutoTaggingSpecificationOriginalLanguage": "Мова", + "Mixed": "Виправлено" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 087a251999..2636be8b81 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1119,5 +1119,6 @@ "AutoTaggingSpecificationStatus": "Trạng thái", "CustomFormatsSpecificationLanguage": "Ngôn ngữ", "CustomFormatsSpecificationMaximumSize": "Kích thước tối đa", - "CustomFormatsSpecificationSource": "Nguồn" + "CustomFormatsSpecificationSource": "Nguồn", + "Mixed": "đã sửa" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 3cc4c55728..695f0565ad 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1883,5 +1883,6 @@ "CustomFormatsSpecificationResolution": "分辨率", "CustomFormatsSpecificationSource": "代码", "AutoTaggingSpecificationGenre": "类型", - "AutoTaggingSpecificationMaximumYear": "最大年份" + "AutoTaggingSpecificationMaximumYear": "最大年份", + "Mixed": "混合" } From c0e5646f07014c9544d0288f7dcb6f1f15b69697 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 26 Jan 2025 15:42:43 +0200 Subject: [PATCH 186/579] Bump Polly and NLog.Layouts.ClefJsonLayout --- src/NzbDrone.Common/Radarr.Common.csproj | 2 +- src/NzbDrone.Core/Radarr.Core.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Common/Radarr.Common.csproj b/src/NzbDrone.Common/Radarr.Common.csproj index eb1cc9eb41..da838b6549 100644 --- a/src/NzbDrone.Common/Radarr.Common.csproj +++ b/src/NzbDrone.Common/Radarr.Common.csproj @@ -10,7 +10,7 @@ - + diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index 8590c401e6..d60cd3a483 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -10,7 +10,7 @@ - + From 743c977e5b242bb68e658c2ba9dba609cd00e86b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 31 Jan 2025 21:55:45 +0200 Subject: [PATCH 187/579] New: Refresh cache for tracked queue on movies update --- .../TrackedDownloadService.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs index 341536f5bf..fee706f7b1 100644 --- a/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs +++ b/src/NzbDrone.Core/Download/TrackedDownloads/TrackedDownloadService.cs @@ -29,6 +29,8 @@ public interface ITrackedDownloadService public class TrackedDownloadService : ITrackedDownloadService, IHandle, + IHandle, + IHandle, IHandle { private readonly IParsingService _parsingService; @@ -272,6 +274,38 @@ public void Handle(MovieAddedEvent message) } } + public void Handle(MovieEditedEvent message) + { + var cachedItems = _cache.Values + .Where(t => + t.RemoteMovie?.Movie != null && + (t.RemoteMovie.Movie.Id == message.Movie?.Id || t.RemoteMovie.Movie.TmdbId == message.Movie?.TmdbId)) + .ToList(); + + if (cachedItems.Any()) + { + cachedItems.ForEach(UpdateCachedItem); + + _eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads())); + } + } + + public void Handle(MoviesBulkEditedEvent message) + { + var cachedItems = _cache.Values + .Where(t => + t.RemoteMovie?.Movie != null && + message.Movies.Any(m => m.Id == t.RemoteMovie.Movie.Id || m.TmdbId == t.RemoteMovie.Movie.TmdbId)) + .ToList(); + + if (cachedItems.Any()) + { + cachedItems.ForEach(UpdateCachedItem); + + _eventAggregator.PublishEvent(new TrackedDownloadRefreshedEvent(GetTrackedDownloads())); + } + } + public void Handle(MoviesDeletedEvent message) { var cachedItems = _cache.Values From 6236bc9b4f4d8fb208d920314d46630a50fd5147 Mon Sep 17 00:00:00 2001 From: Weblate Date: Fri, 31 Jan 2025 21:29:48 +0000 Subject: [PATCH 188/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Dani Talens Co-authored-by: Mailme Dashite Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ca.json | 29 ++++++++-- src/NzbDrone.Core/Localization/Core/de.json | 63 ++++++++++++++++++--- src/NzbDrone.Core/Localization/Core/fi.json | 4 +- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 58aec56a69..4219922eed 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -227,7 +227,7 @@ "Genres": "Gèneres", "DownloadClientOptionsLoadError": "No es poden carregar les opcions del client de baixada", "ImportList": "Llista", - "MappedNetworkDrivesWindowsService": "Les unitats de xarxa assignades no estan disponibles quan s'executen com a servei de Windows. Si us plau, consulteu les PMF per a obtenir més informació", + "MappedNetworkDrivesWindowsService": "Les unitats de xarxa assignades no estan disponibles quan s'executen com a servei de Windows. Si us plau, consulteu les [PMF]{url} per a obtenir més informació.", "MissingMonitoredAndConsideredAvailable": "Absent (Monitorada)", "MissingNotMonitored": "Absent (No monitorada)", "Mode": "Mode", @@ -311,7 +311,7 @@ "ICalIncludeUnmonitoredMoviesHelpText": "Inclou pel·lícules no monitorades al canal iCal", "UpdateAll": "Actualitzar-ho tot", "UpdateAutomaticallyHelpText": "Baixeu i instal·leu les actualitzacions automàticament. Encara podreu instal·lar des de Sistema: Actualitzacions", - "UpdateAvailableHealthCheckMessage": "Nova actualització disponible", + "UpdateAvailableHealthCheckMessage": "Nova actualització disponible: {version}", "Week": "Setmana", "WeekColumnHeader": "Capçalera de la columna de la setmana", "Weeks": "Setmanes", @@ -429,7 +429,7 @@ "DeleteEmptyFolders": "Suprimeix les carpetes buides", "DeleteEmptyFoldersHelpText": "Suprimeix les carpetes de pel·lícules buides durant l'exploració del disc i quan s'esborren els fitxers de pel·lícules", "DeleteFile": "Esborrar Arxiu", - "DeleteMovieFiles": "Suprimeix {0} fitxers de pel·lícula", + "DeleteMovieFiles": "Suprimeix {movieFileCount} fitxers de pel·lícula", "DeleteSelectedMovieFiles": "Suprimeix els fitxers de pel·lícules seleccionats", "DeleteIndexer": "Suprimeix l'indexador", "DeleteIndexerMessageText": "Esteu segur que voleu suprimir l'indexador '{name}'?", @@ -1404,5 +1404,26 @@ "Mixed": "Combinat", "CountCustomFormatsSelected": "{count} format(s) personalitzat(s) seleccionat(s)", "BlocklistFilterHasNoItems": "El filtre de la llista de bloqueig seleccionat no conté elements", - "CountVotes": "{votes} vots" + "CountVotes": "{votes} vots", + "NotificationsKodiSettingsDisplayTime": "Temps de visualització", + "TestParsing": "Prova anàlisi", + "SubtitleLanguages": "Idiomes de subtítols", + "DownloadClientFloodSettingsAdditionalTags": "Etiquetes addicionals", + "DownloadClientFreeboxSettingsAppId": "Identificador de l'aplicació", + "Install": "Instal·la", + "DownloadClientFreeboxSettingsApiUrl": "URL de l'API", + "AnnouncedMovieAvailabilityDescription": "Les pel·lícules es consideren disponibles tan bon punt s'afegeixen a {appName}.", + "NotificationsEmailSettingsBccAddress": "Adreça(es) BCC", + "NotificationsKodiSettingsGuiNotification": "Notificació d'interfície gràfica", + "MetadataKometaDeprecatedSetting": "Obsolet", + "NotificationsMailgunSettingsSenderDomain": "Domini del remitent", + "PasswordConfirmation": "Confirmeu la contrasenya", + "UnknownEventTooltip": "Esdeveniment desconegut", + "UpdateFiltered": "Actualitza filtrats", + "Warning": "Advertència", + "Disposition": "Disposició", + "DownloadClientFloodSettingsAddPaused": "Afegeix pausats", + "NotificationsAppriseSettingsTags": "Etiquetes d'Apprise", + "NotificationsSettingsWebhookHeaders": "Capçaleres", + "PreviouslyInstalled": "Instal·lat anteriorment" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 7f6d809b83..2814e6e225 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -166,7 +166,7 @@ "QualitySettingsSummary": "Qualitätsgrößen und Namensgebung", "Protocol": "Protokoll", "Progress": "Fortschritt", - "ProfilesSettingsSummary": "Profile für Qualität, Sprache und Verzögerung", + "ProfilesSettingsSummary": "Qualitäts-, Sprach-, Verzögerungs- und Release-Profile", "PhysicalRelease": "VÖ Disc", "OutputPath": "Ausgabe-Pfad", "MovieTitle": "Filmtitel", @@ -533,7 +533,7 @@ "RemoveHelpTextWarning": "Dies wird den Download und alle bereits heruntergeladenen Dateien aus dem Downloader entfernen.", "AnalyseVideoFilesHelpText": "Videoinformationen wie Auflösung, Laufzeit und Codec aus Datien erkennen. Dazu ist es erforderlich, dass {appName} Teile der Datei liest, was zu hoher Festplatten- oder Netzwerkaktivität während der Scans führen kann.", "AddImportListExclusion": "Listenausschluss hinzufügen", - "RequiredHelpText": "Diese {0} Bedingungen müsen zutreffen damit das eigene Format zutrifft. Ansonsten reicht ein einzelner {1} Treffer.", + "RequiredHelpText": "Diese {implementationName} Bedingung muss übereinstimmen, damit das benutzerdefinierte Format angewendet wird. Andernfalls reicht eine einzelne {implementationName} Übereinstimmung aus.", "AllowHardcodedSubsHelpText": "Filme mit hartcodierten Untertiteln werden auch automatisch heruntergeladen", "ICalFeedHelpText": "Kopiere diese URL in deine(n) Client(s) oder klicke zum Abonnieren, wenn dein Browser webcal unterstützt", "NoMinimumForAnyRuntime": "Kein Minimum für beliebige Laufzeit", @@ -543,7 +543,7 @@ "ApiKey": "API-Schlüssel", "ImportedTo": "Importiert nach", "Permissions": "Berechtigungen", - "ImportExtraFilesMovieHelpText": "Importiere zutreffende Extra Dateien (Untertitel, nfo, etc.) nach dem Importieren einer Filmdatei", + "ImportExtraFilesMovieHelpText": "Passende zusätzliche Dateien (Untertitel, NFO, etc.) nach dem Import eines Filmdateiformats importieren", "PreferIndexerFlags": "Bevorzugte Indexer Flags", "CopyUsingHardlinksMovieHelpText": "Hardlinks erlauben es {appName}, Torrents zu importieren die derzeit geseeded werden, ohne dabei weiteren Speicherplatz zu belegen oder die Datei vollständig zu kopieren. Hardlinks funktionieren nur, wenn sich die Quelle und das Ziel auf dem selben Volume befinden", "SearchForMovie": "Film suchen", @@ -609,7 +609,7 @@ "IncludeRadarrRecommendations": "{appName} Empfehlungen einbeziehen", "ImportFailed": "Import fehlgeschlagen: {0}", "HiddenClickToShow": "Versteckt, zum Anzeigen anklicken", - "GrabReleaseMessageText": "Das Release konnte keinem Film zugeordnet werden. Ein automatischer Import wird nicht möglich sein. Trotzdem '{0}' erfassen?", + "GrabReleaseMessageText": "{appName} konnte nicht bestimmen, für welchen Film dieser Release ist. {appName} könnte diesen Release möglicherweise nicht automatisch importieren. Möchtest du '{0}' grabben?", "GoToInterp": "Zu {0} gehen", "ExistingTag": "Vorhandener Tag", "ExcludeMovie": "Film ausschließen", @@ -766,7 +766,7 @@ "WhatsNew": "Was gibt's Neues?", "Weeks": "Wochen", "UsenetDisabled": "Usenet deaktiviert", - "UsenetDelayTime": "Usenet Verzögerung: {0}", + "UsenetDelayTime": "Usenet-Verzögerung: {usenetDelay}", "Uppercase": "Großgeschrieben", "UpgradeUntil": "Upgrade bis zur Qualität", "UpgradeUntilCustomFormatScore": "Upgrade bis zur benutzerdefinierten Formatbewertung", @@ -780,7 +780,7 @@ "Trakt": "Trakt", "Trailer": "Trailer", "TorrentsDisabled": "Torrents deaktiviert", - "TorrentDelayTime": "Torrent Verzögerung: {0}", + "TorrentDelayTime": "Torrent-Verzögerung: {torrentDelay}", "TMDb": "TMDb", "ThisCannotBeCancelled": "Nach dem Start kann dies nicht mehr abgebrochen werden ohne alle Indexer zu deaktivieren.", "TheLogLevelDefault": "Die Protokollebene ist standardmäßig auf „Info“ eingestellt und kann unter „Allgemeine Einstellungen“ (/settings/general) geändert werden.", @@ -895,7 +895,7 @@ "DockerUpdater": "aktualisiere den Docker Container um das Update zu erhalten", "Discord": "Discord", "DeleteMovieFolderConfirmation": "Der Filmordner und dessen Inhalt wird gelöscht.", - "DeleteSelectedMovie": "Lösche ausgewählte Film/e", + "DeleteSelectedMovie": "Lösche ausgewählten Film", "DeleteMovieFolder": "Filmordner löschen", "DeleteMovieFolderHelpText": "Lösche den Filmordner mitsamt Inhalt", "DeleteHeader": "Löschen - {0}", @@ -937,7 +937,7 @@ "SqliteVersionCheckUpgradeRequiredMessage": "Die derzeit installierte SQLite-Version {0} wird nicht mehr unterstützt. Bitte aktualisieren Sie SQLite auf mindestens Version {1}.", "ShowCinemaRelease": "Erscheinungsdatum des Kinos anzeigen", "ShowReleaseDate": "Veröffentlichungsdatum anzeigen", - "ShowReleaseDateHelpText": "Erscheinungsdatum unter Poster anzeigen", + "ShowReleaseDateHelpText": "Veröffentlichungsdatum basierend auf der minimalen Verfügbarkeit unter dem Poster anzeigen", "OnMovieDelete": "Beim Löschen des Films", "OnMovieFileDelete": "Bei Filmdatei löschen", "OnMovieFileDeleteForUpgrade": "Bei Filmdatei Zum Upgrade löschen", @@ -1818,5 +1818,50 @@ "Mixed": "Gemischt", "ReleasePush": "Veröffentlichung-Push", "ReleaseSource": "Veröffentlichungsquelle", - "UserInvokedSearch": "Benutzerinitiierte Suche" + "UserInvokedSearch": "Benutzerinitiierte Suche", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo mit vollständigen Film-Metadaten", + "IncludeTrendingMoviesHelpText": "Trendige Filme auf TMDb einbeziehen", + "ExistsInLibrary": "Existiert in der Bibliothek", + "InvalidMovieInfoLanguageLanguage": "Die Sprache für Film-Informationen ist auf einen ungültigen Wert eingestellt, korrigiere ihn und speichere deine Einstellungen", + "CustomFormatsSpecificationQualityModifier": "Qualitätsmodifikator", + "Disposition": "Disposition", + "EditionFootNote": "Steuere optional die Kürzung auf eine maximale Anzahl von Bytes, einschließlich Auslassungspunkten (`...`). Das Kürzen vom Ende (z. B. `{Edition Tags:30}`) oder vom Anfang (z. B. `{Edition Tags:-30}`) wird beide unterstützt.", + "InCinemasMovieAvailabilityDescription": "Filme gelten als verfügbar, sobald sie in den Kinos erscheinen.", + "IncludePopular": "Beliebte einbeziehen", + "IncludePopularMoviesHelpText": "Beliebte Filme auf TMDb einbeziehen", + "IncludeTrending": "Trendige Filme einbeziehen", + "MetadataKometaDeprecated": "Kometa-Dateien werden nicht mehr erstellt, die Unterstützung wird in v6 vollständig entfernt", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Die ausgewählte Sprache, falls verfügbar, in .nfo einbeziehen", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Metadaten in movie.nfo statt der standardmäßigen .nfo schreiben", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "TMDb- und IMDb-Film-URLs in .nfo einbeziehen", + "MovieDownloaded": "Film heruntergeladen", + "MovieFootNote": "Optional die Kürzung auf eine maximale Anzahl von Bytes einschließlich der Auslassungspunkte (`...`) steuern. Eine Kürzung vom Ende (z. B. `{Movie Title:30}`) oder vom Anfang (z. B. `{Movie Title:-30}`) wird beides unterstützt.", + "MovieGrabbedTooltip": "Film von {indexer} abgerufen und an {downloadClient} gesendet", + "MovieIsNotAvailable": "Film ist nicht verfügbar", + "MovieIsPopular": "Film ist beliebt auf TMDb", + "MovieIsTrending": "Film ist trendig auf TMDb", + "MovieMissingFromDisk": "Film fehlt auf der Festplatte", + "NewNonExcluded": "Neu, nicht ausgeschlossen", + "NoMovieReleaseDatesAvailable": "Keine Veröffentlichungstermine auf [TMDb]({url}) für diesen Film verfügbar.", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Füge Links zu den Film-Metadaten hinzu, wenn Benachrichtigungen gesendet werden", + "ShowTraktRating": "Trakt-Bewertung anzeigen", + "ShowTraktRatingPosterHelpText": "Trakt-Bewertung unter dem Poster anzeigen", + "TraktRating": "Trakt-Bewertung", + "TraktVotes": "Trakt-Stimmen", + "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Füge Links zu den Film-Metadaten hinzu, wenn Benachrichtigungen gesendet werden", + "OnExcludedList": "Auf der Ausgeschlossenen Liste", + "OrganizeNamingPattern": "Namensmuster: `{standardMovieFormat}`", + "Popular": "Beliebt", + "ReleasedMovieAvailabilityDescription": "Filme gelten als verfügbar, sobald die Blu-Ray- oder Streaming-Version veröffentlicht wird.", + "SearchMoviesOnAdd": "Filme bei der Hinzufügung suchen", + "Trending": "Trendig", + "NotificationsSettingsUpdateMapPathsFromMovieHelpText": "{appName} Pfad, der verwendet wird, um Film-Pfade zu ändern, wenn {serviceName} den Bibliothekspfad anders sieht als {appName} (erfordert 'Bibliothek aktualisieren')", + "NotificationsSettingsUpdateMapPathsToMovieHelpText": "{serviceName} Pfad, der verwendet wird, um Film-Pfade zu ändern, wenn {serviceName} den Bibliothekspfad anders sieht als {appName} (erfordert 'Bibliothek aktualisieren')", + "MetadataSettingsMovieImages": "Film-Bilder", + "MetadataSettingsMovieMetadata": "Film-Metadaten", + "MetadataSettingsMovieMetadataCollectionName": "Name der Filmsammlung", + "MetadataSettingsMovieMetadataLanguage": "Sprache der Film-Metadaten", + "MetadataSettingsMovieMetadataNfo": "Verwende movie.nfo", + "MetadataSettingsMovieMetadataUrl": "URL der Film-Metadaten", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Sammlungsname in .nfo einbeziehen" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index dd2f782d31..cf17435a00 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -323,7 +323,7 @@ "MovieYear": "Elokuvan vuosi", "TestAllClients": "Koesta latauspalvelut", "TestAllIndexers": "Tietolähteiden testaus", - "TestAllLists": "Kaikkien listojen testaus", + "TestAllLists": "Koesta listat", "AddRemotePathMapping": "Lisää etäsijainnin kohdistus", "Apply": "Käytä", "Analytics": "Analytiikka", @@ -1160,7 +1160,7 @@ "SelectFolderModalTitle": "{modalTitle} – Valitse kansio", "OverrideGrabModalTitle": "Ohitetaan ja kaapataan – {title}", "OverrideAndAddToDownloadQueue": "Ohita ja lisää latausjonoon", - "TestParsing": "Testaa jäsennystä", + "TestParsing": "Koesta jäsennys", "DeleteRootFolder": "Poista juurikansio", "DeleteRootFolderMessageText": "Haluatko varmasti poistaa juurikansion \"{path}\"?", "DisabledForLocalAddresses": "Ei käytössä paikallisissa osoitteissa", From 405ae77070754b55dd842c9d053da2a134cfb426 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 1 Feb 2025 22:28:31 +0200 Subject: [PATCH 189/579] New: Prefer newer Usenet releases (cherry picked from commit 6a439f03273b376feda713ef04a6912fc3af9d0a) --- src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs index 55165c42d8..712696eb15 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionComparer.cs @@ -159,7 +159,7 @@ private int CompareAgeIfUsenet(DownloadDecision x, DownloadDecision y) return 10; } - return 1; + return Math.Round(Math.Log10(age)) * -1; }); } From c7aa1bae5e06cd834e096141c70a86f8bebca0ca Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Thu, 30 Jan 2025 18:50:48 -0800 Subject: [PATCH 190/579] Fixed: Ignore special folders inside Blackhole watch folders (cherry picked from commit e79dd6f8e689617b1fd9f96c639ac300669112c5) --- .../Disk/FileSystemLookupService.cs | 33 +------------ src/NzbDrone.Common/Disk/SpecialFolders.cs | 47 +++++++++++++++++++ .../Blackhole/ScanWatchFolderFixture.cs | 17 +++++++ .../Clients/Blackhole/ScanWatchFolder.cs | 8 +++- 4 files changed, 72 insertions(+), 33 deletions(-) create mode 100644 src/NzbDrone.Common/Disk/SpecialFolders.cs diff --git a/src/NzbDrone.Common/Disk/FileSystemLookupService.cs b/src/NzbDrone.Common/Disk/FileSystemLookupService.cs index 8b9d1bae07..efd2fcbdb0 100644 --- a/src/NzbDrone.Common/Disk/FileSystemLookupService.cs +++ b/src/NzbDrone.Common/Disk/FileSystemLookupService.cs @@ -17,37 +17,6 @@ public class FileSystemLookupService : IFileSystemLookupService private readonly IDiskProvider _diskProvider; private readonly IRuntimeInfo _runtimeInfo; - private readonly HashSet _setToRemove = new HashSet - { - // Windows - "boot", - "bootmgr", - "cache", - "msocache", - "recovery", - "$recycle.bin", - "recycler", - "system volume information", - "temporary internet files", - "windows", - - // OS X - ".fseventd", - ".spotlight", - ".trashes", - ".vol", - "cachedmessages", - "caches", - "trash", - - // QNAP - ".@__thumb", - - // Synology - "@eadir", - "#recycle" - }; - public FileSystemLookupService(IDiskProvider diskProvider, IRuntimeInfo runtimeInfo) { _diskProvider = diskProvider; @@ -158,7 +127,7 @@ private List GetDirectories(string path) }) .ToList(); - directories.RemoveAll(d => _setToRemove.Contains(d.Name.ToLowerInvariant())); + directories.RemoveAll(d => SpecialFolders.IsSpecialFolder(d.Name)); return directories; } diff --git a/src/NzbDrone.Common/Disk/SpecialFolders.cs b/src/NzbDrone.Common/Disk/SpecialFolders.cs new file mode 100644 index 0000000000..b1339a7ed4 --- /dev/null +++ b/src/NzbDrone.Common/Disk/SpecialFolders.cs @@ -0,0 +1,47 @@ +using System.Collections.Generic; + +namespace NzbDrone.Common.Disk; + +public static class SpecialFolders +{ + private static readonly HashSet _specialFolders = new HashSet + { + // Windows + "boot", + "bootmgr", + "cache", + "msocache", + "recovery", + "$recycle.bin", + "recycler", + "system volume information", + "temporary internet files", + "windows", + + // OS X + ".fseventd", + ".spotlight", + ".trashes", + ".vol", + "cachedmessages", + "caches", + "trash", + + // QNAP + ".@__thumb", + + // Synology + "@eadir", + "#recycle" + }; + + public static bool IsSpecialFolder(string folder) + { + if (folder == null) + { + return false; + } + + return _specialFolders.Contains(folder.ToLowerInvariant()); + } +} diff --git a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs index de9cb85937..968c040234 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadClientTests/Blackhole/ScanWatchFolderFixture.cs @@ -95,5 +95,22 @@ public void GetItems_should_considered_changing_files_queued() VerifySingleItem(DownloadItemStatus.Completed); } + + [TestCase("@eaDir")] + [TestCase(".@__thumb")] + public void GetItems_should_not_include_special_subfolders(string folderName) + { + GivenCompletedItem(); + + var targetDir = Path.Combine(_completedDownloadFolder, folderName); + + Mocker.GetMock() + .Setup(c => c.GetDirectories(_completedDownloadFolder)) + .Returns(new[] { targetDir }); + + var items = Subject.GetItems(_completedDownloadFolder, TimeSpan.FromMilliseconds(50)).ToList(); + + items.Count.Should().Be(0); + } } } diff --git a/src/NzbDrone.Core/Download/Clients/Blackhole/ScanWatchFolder.cs b/src/NzbDrone.Core/Download/Clients/Blackhole/ScanWatchFolder.cs index ef5bb0a0d2..6aa21ab382 100644 --- a/src/NzbDrone.Core/Download/Clients/Blackhole/ScanWatchFolder.cs +++ b/src/NzbDrone.Core/Download/Clients/Blackhole/ScanWatchFolder.cs @@ -52,7 +52,13 @@ private IEnumerable GetDownloadItems(string watchFolder, Dictio { foreach (var folder in _diskScanService.FilterPaths(watchFolder, _diskProvider.GetDirectories(watchFolder))) { - var title = FileNameBuilder.CleanFileName(Path.GetFileName(folder)); + var folderName = Path.GetFileName(folder); + var title = FileNameBuilder.CleanFileName(folderName); + + if (SpecialFolders.IsSpecialFolder(folderName)) + { + continue; + } var newWatchItem = new WatchFolderItem { From 8853dced9fecc1d8c92163ae532352a44268d3d5 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 31 Jan 2025 17:04:55 +0200 Subject: [PATCH 191/579] Fixed: Health warning for downloading inside root folders (cherry picked from commit 1e9fd02e9d2bf57247adcac5728e2a0d2b084b86) --- .../DownloadClientRootFolderCheckFixture.cs | 15 ++++++++++++++- .../Checks/DownloadClientRootFolderCheck.cs | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/NzbDrone.Core.Test/HealthCheck/Checks/DownloadClientRootFolderCheckFixture.cs b/src/NzbDrone.Core.Test/HealthCheck/Checks/DownloadClientRootFolderCheckFixture.cs index f3e826fd6e..7da5fac02b 100644 --- a/src/NzbDrone.Core.Test/HealthCheck/Checks/DownloadClientRootFolderCheckFixture.cs +++ b/src/NzbDrone.Core.Test/HealthCheck/Checks/DownloadClientRootFolderCheckFixture.cs @@ -76,6 +76,19 @@ public void should_return_downloads_in_root_folder_if_downloading_to_root_folder Subject.Check().ShouldBeWarning(wikiFragment: "downloads-in-root-folder"); } + [Test] + public void should_return_warning_if_downloading_inside_root_folder() + { + var rootFolderPath = "c:\\Test".AsOsAgnostic(); + var downloadRootPath = "c:\\Test\\Downloads".AsOsAgnostic(); + + GivenRootFolder(rootFolderPath); + + _clientStatus.OutputRootFolders = new List { new (downloadRootPath) }; + + Subject.Check().ShouldBeWarning(); + } + [Test] public void should_return_ok_if_not_downloading_to_root_folder() { @@ -87,7 +100,7 @@ public void should_return_ok_if_not_downloading_to_root_folder() } [Test] - [TestCaseSource("DownloadClientExceptions")] + [TestCaseSource(nameof(DownloadClientExceptions))] public void should_return_ok_if_client_throws_downloadclientexception(Exception ex) { _downloadClient.Setup(s => s.GetStatus()) diff --git a/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs b/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs index 15b727fdb4..4e1b54bc3a 100644 --- a/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs +++ b/src/NzbDrone.Core/HealthCheck/Checks/DownloadClientRootFolderCheck.cs @@ -48,7 +48,7 @@ public override HealthCheck Check() try { var status = client.GetStatus(); - var folders = status.OutputRootFolders.Where(folder => rootFolders.Any(r => r.Path.PathEquals(folder.FullPath))); + var folders = rootFolders.Where(r => status.OutputRootFolders.Any(folder => r.Path.PathEquals(folder.FullPath) || r.Path.IsParentPath(folder.FullPath))); foreach (var folder in folders) { @@ -57,7 +57,7 @@ public override HealthCheck Check() _localizationService.GetLocalizedString("DownloadClientRootFolderHealthCheckMessage", new Dictionary { { "downloadClientName", client.Definition.Name }, - { "rootFolderPath", folder.FullPath } + { "rootFolderPath", folder.Path } }), "#downloads-in-root-folder"); } From 1edcbee5e134da296e34f27441010288b07ad6c9 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 2 Feb 2025 12:49:50 +0200 Subject: [PATCH 192/579] Bump version to 5.18.4 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c15e32fe60..c282c030b1 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.18.3' + majorVersion: '5.18.4' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 528b93dabe5df8811a11a6d0dc28bdaa2721393d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 24 Jan 2025 15:43:08 +0200 Subject: [PATCH 193/579] Fixed: Format bitrate for primary streams in media info Co-authored-by: Mark McDowall --- frontend/src/MovieFile/Editor/MediaInfo.tsx | 17 +++++++++++--- .../src/Utilities/Number/formatBitrate.ts | 19 +++++++++++++++ .../MediaInfo/VideoFileInfoReader.cs | 23 +++++++++++++++---- 3 files changed, 52 insertions(+), 7 deletions(-) create mode 100644 frontend/src/Utilities/Number/formatBitrate.ts diff --git a/frontend/src/MovieFile/Editor/MediaInfo.tsx b/frontend/src/MovieFile/Editor/MediaInfo.tsx index d0a8951750..f5e3db21f6 100644 --- a/frontend/src/MovieFile/Editor/MediaInfo.tsx +++ b/frontend/src/MovieFile/Editor/MediaInfo.tsx @@ -2,6 +2,7 @@ import React from 'react'; import DescriptionList from 'Components/DescriptionList/DescriptionList'; import DescriptionListItem from 'Components/DescriptionList/DescriptionListItem'; import MediaInfoProps from 'typings/MediaInfo'; +import formatBitrate from 'Utilities/Number/formatBitrate'; import getEntries from 'Utilities/Object/getEntries'; function MediaInfo(props: MediaInfoProps) { @@ -16,9 +17,19 @@ function MediaInfo(props: MediaInfoProps) { return null; } - return ( - - ); + if (key === 'audioBitrate' || key === 'videoBitrate') { + return ( + {formatBitrate(value)} + } + /> + ); + } + + return ; })} ); diff --git a/frontend/src/Utilities/Number/formatBitrate.ts b/frontend/src/Utilities/Number/formatBitrate.ts new file mode 100644 index 0000000000..5d7d25ae4a --- /dev/null +++ b/frontend/src/Utilities/Number/formatBitrate.ts @@ -0,0 +1,19 @@ +import { filesize } from 'filesize'; + +function formatBitrate(input: string | number) { + const size = Number(input); + + if (isNaN(size)) { + return ''; + } + + const { value, symbol } = filesize(size, { + base: 10, + round: 1, + output: 'object', + }); + + return `${value} ${symbol}/s`; +} + +export default formatBitrate; diff --git a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs index 868d7749a6..cbfb17e888 100644 --- a/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs +++ b/src/NzbDrone.Core/MediaFiles/MediaInfo/VideoFileInfoReader.cs @@ -21,8 +21,8 @@ public class VideoFileInfoReader : IVideoFileInfoReader private readonly Logger _logger; private readonly List _pixelFormats; - public const int MINIMUM_MEDIA_INFO_SCHEMA_REVISION = 8; - public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 13; + public const int MINIMUM_MEDIA_INFO_SCHEMA_REVISION = 14; + public const int CURRENT_MEDIA_INFO_SCHEMA_REVISION = 14; private static readonly string[] ValidHdrColourPrimaries = { "bt2020" }; private static readonly string[] HlgTransferFunctions = { "arib-std-b67" }; @@ -80,7 +80,7 @@ public MediaInfoModel GetMediaInfo(string filename) mediaInfoModel.VideoFormat = primaryVideoStream?.CodecName; mediaInfoModel.VideoCodecID = primaryVideoStream?.CodecTagString; mediaInfoModel.VideoProfile = primaryVideoStream?.Profile; - mediaInfoModel.VideoBitrate = primaryVideoStream?.BitRate ?? 0; + mediaInfoModel.VideoBitrate = GetBitrate(primaryVideoStream); mediaInfoModel.VideoMultiViewCount = primaryVideoStream?.Tags?.ContainsKey("stereo_mode") ?? false ? 2 : 1; mediaInfoModel.VideoBitDepth = GetPixelFormat(primaryVideoStream?.PixelFormat)?.Components.Min(x => x.BitDepth) ?? 8; mediaInfoModel.VideoColourPrimaries = primaryVideoStream?.ColorPrimaries; @@ -91,7 +91,7 @@ public MediaInfoModel GetMediaInfo(string filename) mediaInfoModel.AudioFormat = analysis.PrimaryAudioStream?.CodecName; mediaInfoModel.AudioCodecID = analysis.PrimaryAudioStream?.CodecTagString; mediaInfoModel.AudioProfile = analysis.PrimaryAudioStream?.Profile; - mediaInfoModel.AudioBitrate = analysis.PrimaryAudioStream?.BitRate ?? 0; + mediaInfoModel.AudioBitrate = GetBitrate(analysis.PrimaryAudioStream); mediaInfoModel.RunTime = GetBestRuntime(analysis.PrimaryAudioStream?.Duration, primaryVideoStream?.Duration, analysis.Format.Duration); mediaInfoModel.AudioStreamCount = analysis.AudioStreams.Count; mediaInfoModel.AudioChannels = analysis.PrimaryAudioStream?.Channels ?? 0; @@ -161,6 +161,21 @@ private static TimeSpan GetBestRuntime(TimeSpan? audio, TimeSpan? video, TimeSpa return video.Value; } + private static long GetBitrate(MediaStream mediaStream) + { + if (mediaStream?.BitRate is > 0) + { + return mediaStream.BitRate; + } + + if ((mediaStream?.Tags?.TryGetValue("BPS", out var bitratePerSecond) ?? false) && bitratePerSecond.IsNotNullOrWhiteSpace()) + { + return Convert.ToInt64(bitratePerSecond); + } + + return 0; + } + private VideoStream GetPrimaryVideoStream(IMediaAnalysis mediaAnalysis) { if (mediaAnalysis.VideoStreams.Count <= 1) From b0bfbe767c515c37565094663f84aa2155a7461d Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sat, 25 Jan 2025 20:56:16 -0800 Subject: [PATCH 194/579] Add MediaInfo AudioLanguagesAll and update styling (cherry picked from commit 572b8620c9693f6824ae0919d6a37ba69c7590b1) --- .../MediaManagement/Naming/NamingModal.css | 4 +- .../Naming/NamingModal.css.d.ts | 2 +- .../MediaManagement/Naming/NamingModal.tsx | 69 +++++++++++-------- .../MediaManagement/Naming/NamingOption.css | 2 +- .../Naming/NamingOption.css.d.ts | 2 +- .../MediaManagement/Naming/NamingOption.tsx | 12 ++-- src/NzbDrone.Core/Localization/Core/en.json | 1 + 7 files changed, 53 insertions(+), 39 deletions(-) diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.css b/frontend/src/Settings/MediaManagement/Naming/NamingModal.css index b9b28e45f2..3b26c6f247 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.css +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.css @@ -21,8 +21,8 @@ display: flex; color: var(--helpTextColor); - .icon { - margin-top: 3px; + .identifier { + margin-top: 8px; margin-right: 5px; padding: 2px; } diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.css.d.ts b/frontend/src/Settings/MediaManagement/Naming/NamingModal.css.d.ts index 5dd30b0d38..89da9f9b4c 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.css.d.ts +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.css.d.ts @@ -3,7 +3,7 @@ interface CssExports { 'footNote': string; 'groups': string; - 'icon': string; + 'identifier': string; 'namingSelect': string; 'namingSelectContainer': string; } diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingModal.tsx b/frontend/src/Settings/MediaManagement/Naming/NamingModal.tsx index 01391c32d8..e39d565462 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingModal.tsx +++ b/frontend/src/Settings/MediaManagement/Naming/NamingModal.tsx @@ -2,7 +2,6 @@ import React, { useCallback, useState } from 'react'; import FieldSet from 'Components/FieldSet'; import SelectInput from 'Components/Form/SelectInput'; import TextInput from 'Components/Form/TextInput'; -import Icon from 'Components/Icon'; import Button from 'Components/Link/Button'; import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; import Modal from 'Components/Modal/Modal'; @@ -10,7 +9,7 @@ import ModalBody from 'Components/Modal/ModalBody'; import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; -import { icons, sizes } from 'Helpers/Props'; +import { sizes } from 'Helpers/Props'; import NamingConfig from 'typings/Settings/NamingConfig'; import translate from 'Utilities/String/translate'; import NamingOption from './NamingOption'; @@ -88,32 +87,32 @@ const fileNameTokens = [ ]; const movieTokens = [ - { token: '{Movie Title}', example: "Movie's Title", footNote: true }, - { token: '{Movie Title:DE}', example: 'Titel des Films', footNote: true }, - { token: '{Movie CleanTitle}', example: 'Movies Title', footNote: true }, + { token: '{Movie Title}', example: "Movie's Title", footNotes: '1' }, + { token: '{Movie Title:DE}', example: 'Titel des Films', footNotes: '1' }, + { token: '{Movie CleanTitle}', example: 'Movies Title', footNotes: '1' }, { token: '{Movie CleanTitle:DE}', example: 'Titel des Films', - footNote: true, + footNotes: '1', }, - { token: '{Movie TitleThe}', example: "Movie's Title, The", footNote: true }, + { token: '{Movie TitleThe}', example: "Movie's Title, The", footNotes: '1' }, { token: '{Movie CleanTitleThe}', example: 'Movies Title, The', - footNote: true, + footNotes: '1', }, - { token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας', footNote: true }, + { token: '{Movie OriginalTitle}', example: 'Τίτλος ταινίας', footNotes: '1' }, { token: '{Movie CleanOriginalTitle}', example: 'Τίτλος ταινίας', - footNote: true, + footNotes: '1', }, { token: '{Movie TitleFirstCharacter}', example: 'M' }, { token: '{Movie TitleFirstCharacter:DE}', example: 'T' }, { token: '{Movie Collection}', example: 'The Movie Collection', - footNote: true, + footNotes: '1', }, { token: '{Movie Certification}', example: 'R' }, { token: '{Release Year}', example: '2009' }, @@ -131,12 +130,21 @@ const qualityTokens = [ const mediaInfoTokens = [ { token: '{MediaInfo Simple}', example: 'x264 DTS' }, - { token: '{MediaInfo Full}', example: 'x264 DTS [EN+DE]', footNote: true }, + { token: '{MediaInfo Full}', example: 'x264 DTS [EN+DE]', footNotes: '1' }, { token: '{MediaInfo AudioCodec}', example: 'DTS' }, { token: '{MediaInfo AudioChannels}', example: '5.1' }, - { token: '{MediaInfo AudioLanguages}', example: '[EN+DE]', footNote: true }, - { token: '{MediaInfo SubtitleLanguages}', example: '[DE]', footNote: true }, + { + token: '{MediaInfo AudioLanguages}', + example: '[EN+DE]', + footNotes: '1,2', + }, + { + token: '{MediaInfo AudioLanguagesAll}', + example: '[EN]', + footNotes: '1', + }, + { token: '{MediaInfo SubtitleLanguages}', example: '[DE]', footNotes: '1' }, { token: '{MediaInfo VideoCodec}', example: 'x264' }, { token: '{MediaInfo VideoBitDepth}', example: '10' }, @@ -146,11 +154,11 @@ const mediaInfoTokens = [ ]; const releaseGroupTokens = [ - { token: '{Release Group}', example: 'Rls Grp', footNote: true }, + { token: '{Release Group}', example: 'Rls Grp', footNotes: '1' }, ]; const editionTokens = [ - { token: '{Edition Tags}', example: 'IMAX', footNote: true }, + { token: '{Edition Tags}', example: 'IMAX', footNotes: '1' }, ]; const customFormatTokens = [ @@ -287,13 +295,13 @@ function NamingModal(props: NamingModalProps) {
- {movieTokens.map(({ token, example, footNote }) => { + {movieTokens.map(({ token, example, footNotes }) => { return (
- + 1
@@ -346,13 +354,13 @@ function NamingModal(props: NamingModalProps) {
- {mediaInfoTokens.map(({ token, example, footNote }) => { + {mediaInfoTokens.map(({ token, example, footNotes }) => { return (
- + 1
+ +
+ 2 + +
- {releaseGroupTokens.map(({ token, example, footNote }) => { + {releaseGroupTokens.map(({ token, example, footNotes }) => { return (
- + 1
- {editionTokens.map(({ token, example, footNote }) => { + {editionTokens.map(({ token, example, footNotes }) => { return (
- + 1
diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingOption.css b/frontend/src/Settings/MediaManagement/Naming/NamingOption.css index c744989971..6dd0691458 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingOption.css +++ b/frontend/src/Settings/MediaManagement/Naming/NamingOption.css @@ -40,7 +40,7 @@ padding: 6px; background-color: var(--popoverBodyBackgroundColor); - .footNote { + .footNotes { padding: 2px; color: #aaa; } diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingOption.css.d.ts b/frontend/src/Settings/MediaManagement/Naming/NamingOption.css.d.ts index 5c50bfab2b..0005e896b2 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingOption.css.d.ts +++ b/frontend/src/Settings/MediaManagement/Naming/NamingOption.css.d.ts @@ -2,7 +2,7 @@ // Please do not change this file! interface CssExports { 'example': string; - 'footNote': string; + 'footNotes': string; 'isFullFilename': string; 'large': string; 'lower': string; diff --git a/frontend/src/Settings/MediaManagement/Naming/NamingOption.tsx b/frontend/src/Settings/MediaManagement/Naming/NamingOption.tsx index e9bcf11ff4..5a3a03ff21 100644 --- a/frontend/src/Settings/MediaManagement/Naming/NamingOption.tsx +++ b/frontend/src/Settings/MediaManagement/Naming/NamingOption.tsx @@ -1,8 +1,6 @@ import classNames from 'classnames'; import React, { useCallback } from 'react'; -import Icon from 'Components/Icon'; import Link from 'Components/Link/Link'; -import { icons } from 'Helpers/Props'; import { Size } from 'Helpers/Props/sizes'; import TokenCase from './TokenCase'; import TokenSeparator from './TokenSeparator'; @@ -14,7 +12,7 @@ interface NamingOptionProps { example: string; tokenCase: TokenCase; isFullFilename?: boolean; - footNote?: boolean; + footNotes?: string; size?: Extract; onPress: ({ isFullFilename, @@ -32,7 +30,7 @@ function NamingOption(props: NamingOptionProps) { example, tokenCase, isFullFilename = false, - footNote = false, + footNotes, size = 'small', onPress, } = props; @@ -66,8 +64,10 @@ function NamingOption(props: NamingOptionProps) {
{example.replace(/ /g, tokenSeparator)} - {footNote ? ( - + {footNotes ? ( +
+ {footNotes} +
) : null}
diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 70cb30ee38..f8b4309437 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -929,6 +929,7 @@ "Mechanism": "Mechanism", "MediaInfo": "Media Info", "MediaInfoFootNote": "MediaInfo Full/AudioLanguages/SubtitleLanguages support a `:EN+DE` suffix allowing you to filter the languages included in the filename. Use `-DE` to exclude specific languages. Appending `+` (eg `:EN+`) will output `[EN]`/`[EN+--]`/`[--]` depending on excluded languages. For example `{MediaInfo Full:EN+DE}`.", + "MediaInfoFootNote2": "MediaInfo AudioLanguages excludes English if it is the only language. Use MediaInfo AudioLanguagesAll to include English-only", "MediaManagement": "Media Management", "MediaManagementSettings": "Media Management Settings", "MediaManagementSettingsLoadError": "Unable to load Media Management settings", From cd836fef38d58765044c91958096489819bb3c4c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 3 Feb 2025 14:12:21 +0200 Subject: [PATCH 195/579] Bump version to 5.19.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c282c030b1..c62cbab8cf 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.18.4' + majorVersion: '5.19.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 7977e0be05a3ea85e7b55d0647a7aad96d3daa74 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 2 Feb 2025 19:15:46 +0200 Subject: [PATCH 196/579] Add reason enum to decision engine rejections Co-authored-by: Mark McDowall --- .../DownloadDecisionMakerFixture.cs | 40 +++++------ .../ImportFixture.cs | 9 ++- .../DownloadApprovedFixture.cs | 12 ++-- .../PendingReleaseServiceTests/AddFixture.cs | 2 +- .../RemoveGrabbedFixture.cs | 2 +- .../RemoveRejectedFixture.cs | 2 +- .../ImportApprovedMoviesFixture.cs | 7 +- .../MovieImport/ImportDecisionMakerFixture.cs | 13 ++-- src/NzbDrone.Core/DecisionEngine/Decision.cs | 32 --------- .../DecisionEngine/DownloadDecision.cs | 4 +- .../DecisionEngine/DownloadDecisionMaker.cs | 20 +++--- .../DecisionEngine/DownloadRejection.cs | 9 +++ .../DecisionEngine/DownloadRejectionReason.cs | 67 +++++++++++++++++++ .../DecisionEngine/DownloadSpecDecision.cs | 34 ++++++++++ src/NzbDrone.Core/DecisionEngine/Rejection.cs | 10 +-- .../AcceptableSizeSpecification.cs | 14 ++-- .../AlreadyImportedSpecification.cs | 20 +++--- .../BlockedIndexerSpecification.cs | 8 +-- .../Specifications/BlocklistSpecification.cs | 8 +-- ...stomFormatAllowedByProfileSpecification.cs | 8 +-- .../Specifications/FreeSpaceSpecification.cs | 14 ++-- .../HardcodeSubsSpecification.cs | 10 +-- ...> IDownloadDecisionEngineSpecification.cs} | 4 +- .../Specifications/LanguageSpecification.cs | 14 ++-- .../MaximumSizeSpecification.cs | 12 ++-- .../Specifications/MinimumAgeSpecification.cs | 12 ++-- .../Specifications/NotSampleSpecification.cs | 8 +-- .../Specifications/ProtocolSpecification.cs | 10 +-- .../QualityAllowedByProfileSpecification.cs | 8 +-- .../Specifications/QueueSpecification.cs | 24 +++---- .../Specifications/RawDiskSpecification.cs | 16 ++--- .../ReleaseRestrictionsSpecification.cs | 10 +-- .../Specifications/RepackSpecification.cs | 19 +++--- .../RequiredIndexerFlagsSpecification.cs | 17 ++--- .../Specifications/RetentionSpecification.cs | 10 +-- .../RssSync/AvailabilitySpecification.cs | 10 +-- .../RssSync/DelaySpecification.cs | 20 +++--- .../RssSync/HistorySpecification.cs | 30 ++++----- .../RssSync/IndexerTagSpecification.cs | 12 ++-- .../RssSync/MonitoredMovieSpecification.cs | 11 +-- .../RssSync/ProperSpecification.cs | 16 ++--- .../Search/MovieSpecification.cs | 10 +-- .../TorrentSeedingSpecification.cs | 12 ++-- .../UpgradeAllowedSpecification.cs | 10 +-- .../UpgradeDiskSpecification.cs | 26 +++---- .../DownloadedMovieImportService.cs | 19 +++--- .../IImportDecisionEngineSpecification.cs | 3 +- .../MovieImport/ImportApprovedMovie.cs | 2 +- .../MediaFiles/MovieImport/ImportDecision.cs | 15 +---- .../MovieImport/ImportDecisionMaker.cs | 13 ++-- .../MediaFiles/MovieImport/ImportRejection.cs | 11 +++ .../MovieImport/ImportRejectionReason.cs | 28 ++++++++ .../MovieImport/ImportSpecDecision.cs | 34 ++++++++++ .../MovieImport/Manual/ManualImportItem.cs | 3 +- .../MovieImport/Manual/ManualImportService.cs | 9 ++- .../AlreadyImportedSpecification.cs | 16 ++--- .../Specifications/FreeSpaceSpecification.cs | 13 ++-- .../GrabbedReleaseQualitySpecification.cs | 9 ++- .../HasAudioTrackSpecification.cs | 9 ++- .../MatchesFolderSpecification.cs | 9 ++- .../MatchesGrabSpecification.cs | 11 ++- .../NotMultiPartSpecification.cs | 28 ++++---- .../Specifications/NotSampleSpecification.cs | 11 ++- .../NotUnpackingSpecification.cs | 11 ++- .../UnverifiedSceneNumberingSpecification.cs | 21 ------ .../Specifications/UpgradeSpecification.cs | 14 ++-- src/Radarr.Api.V3/Indexers/ReleaseResource.cs | 2 +- .../ManualImport/ManualImportController.cs | 2 +- .../ManualImportReprocessResource.cs | 3 +- .../ManualImport/ManualImportResource.cs | 28 +++++++- 70 files changed, 560 insertions(+), 430 deletions(-) delete mode 100644 src/NzbDrone.Core/DecisionEngine/Decision.cs create mode 100644 src/NzbDrone.Core/DecisionEngine/DownloadRejection.cs create mode 100644 src/NzbDrone.Core/DecisionEngine/DownloadRejectionReason.cs create mode 100644 src/NzbDrone.Core/DecisionEngine/DownloadSpecDecision.cs rename src/NzbDrone.Core/DecisionEngine/Specifications/{IDecisionEngineSpecification.cs => IDownloadDecisionEngineSpecification.cs} (60%) create mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejection.cs create mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejectionReason.cs create mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/ImportSpecDecision.cs delete mode 100644 src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UnverifiedSceneNumberingSpecification.cs diff --git a/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs b/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs index 5332589be0..0c3978f9f4 100644 --- a/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs +++ b/src/NzbDrone.Core.Test/DecisionEngineTests/DownloadDecisionMakerFixture.cs @@ -20,32 +20,32 @@ public class DownloadDecisionMakerFixture : CoreTest private List _reports; private RemoteMovie _remoteEpisode; - private Mock _pass1; - private Mock _pass2; - private Mock _pass3; + private Mock _pass1; + private Mock _pass2; + private Mock _pass3; - private Mock _fail1; - private Mock _fail2; - private Mock _fail3; + private Mock _fail1; + private Mock _fail2; + private Mock _fail3; [SetUp] public void Setup() { - _pass1 = new Mock(); - _pass2 = new Mock(); - _pass3 = new Mock(); + _pass1 = new Mock(); + _pass2 = new Mock(); + _pass3 = new Mock(); - _fail1 = new Mock(); - _fail2 = new Mock(); - _fail3 = new Mock(); + _fail1 = new Mock(); + _fail2 = new Mock(); + _fail3 = new Mock(); - _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); - _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); - _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Accept); + _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Accept); + _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Accept); + _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Accept); - _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail1")); - _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail2")); - _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(Decision.Reject("fail3")); + _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Reject(DownloadRejectionReason.Unknown, "fail1")); + _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Reject(DownloadRejectionReason.Unknown, "fail2")); + _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), null)).Returns(DownloadSpecDecision.Reject(DownloadRejectionReason.Unknown, "fail3")); _reports = new List { new ReleaseInfo { Title = "Trolls.2016.720p.WEB-DL.DD5.1.H264-FGT" } }; _remoteEpisode = new RemoteMovie @@ -58,9 +58,9 @@ public void Setup() .Setup(c => c.Map(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())).Returns(_remoteEpisode); } - private void GivenSpecifications(params Mock[] mocks) + private void GivenSpecifications(params Mock[] mocks) { - Mocker.SetConstant>(mocks.Select(c => c.Object)); + Mocker.SetConstant>(mocks.Select(c => c.Object)); } [Test] diff --git a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs index cd098da27e..2e9d1ff6c5 100644 --- a/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs +++ b/src/NzbDrone.Core.Test/Download/CompletedDownloadServiceTests/ImportFixture.cs @@ -4,7 +4,6 @@ using Moq; using NUnit.Framework; using NzbDrone.Common.Disk; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.History; @@ -107,11 +106,11 @@ public void should_not_mark_as_imported_if_all_files_were_rejected() { new ImportResult( new ImportDecision( - new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new Rejection("Rejected!")), "Test Failure"), + new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new ImportRejection(ImportRejectionReason.Unknown, "Rejected!")), "Test Failure"), new ImportResult( new ImportDecision( - new LocalMovie { Path = @"C:\TestPath\Droned.1999.mkv" }, new Rejection("Rejected!")), "Test Failure") + new LocalMovie { Path = @"C:\TestPath\Droned.1999.mkv" }, new ImportRejection(ImportRejectionReason.Unknown, "Rejected!")), "Test Failure") }); Subject.Import(_trackedDownload); @@ -131,11 +130,11 @@ public void should_not_mark_as_imported_if_no_movies_were_parsed() { new ImportResult( new ImportDecision( - new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new Rejection("Rejected!")), "Test Failure"), + new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new ImportRejection(ImportRejectionReason.Unknown, "Rejected!")), "Test Failure"), new ImportResult( new ImportDecision( - new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new Rejection("Rejected!")), "Test Failure") + new LocalMovie { Path = @"C:\TestPath\Droned.1998.mkv" }, new ImportRejection(ImportRejectionReason.Unknown, "Rejected!")), "Test Failure") }); _trackedDownload.RemoteMovie.Movie = new Movie(); diff --git a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs index 6d0ee4b540..7f6da7b73e 100644 --- a/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/DownloadApprovedReportsTests/DownloadApprovedFixture.cs @@ -189,8 +189,8 @@ public void should_return_an_empty_list_when_none_are_appproved() { var decisions = new List(); RemoteMovie remoteMovie = null; - decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!"))); - decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!"))); + decisions.Add(new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!"))); + decisions.Add(new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!"))); Subject.GetQualifiedReports(decisions).Should().BeEmpty(); } @@ -201,7 +201,7 @@ public async Task should_not_grab_if_pending() var remoteMovie = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); - decisions.Add(new DownloadDecision(remoteMovie, new Rejection("Failure!", RejectionType.Temporary))); + decisions.Add(new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!", RejectionType.Temporary))); await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.DownloadReport(It.IsAny(), null), Times.Never()); @@ -214,7 +214,7 @@ public async Task should_not_add_to_pending_if_movie_was_grabbed() var decisions = new List(); decisions.Add(new DownloadDecision(removeMovie)); - decisions.Add(new DownloadDecision(removeMovie, new Rejection("Failure!", RejectionType.Temporary))); + decisions.Add(new DownloadDecision(removeMovie, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!", RejectionType.Temporary))); await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.AddMany(It.IsAny>>()), Times.Never()); @@ -226,8 +226,8 @@ public async Task should_add_to_pending_even_if_already_added_to_pending() var remoteEpisode = GetRemoteMovie(new QualityModel(Quality.HDTV720p)); var decisions = new List(); - decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary))); - decisions.Add(new DownloadDecision(remoteEpisode, new Rejection("Failure!", RejectionType.Temporary))); + decisions.Add(new DownloadDecision(remoteEpisode, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!", RejectionType.Temporary))); + decisions.Add(new DownloadDecision(remoteEpisode, new DownloadRejection(DownloadRejectionReason.Unknown, "Failure!", RejectionType.Temporary))); await Subject.ProcessDecisions(decisions); Mocker.GetMock().Verify(v => v.AddMany(It.IsAny>>()), Times.Once()); diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs index bac4c9aa45..face5dfd8c 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/AddFixture.cs @@ -56,7 +56,7 @@ public void Setup() _remoteMovie.ParsedMovieInfo = _parsedMovieInfo; _remoteMovie.Release = _release; - _temporarilyRejected = new DownloadDecision(_remoteMovie, new Rejection("Temp Rejected", RejectionType.Temporary)); + _temporarilyRejected = new DownloadDecision(_remoteMovie, new DownloadRejection(DownloadRejectionReason.MinimumAgeDelay, "Temp Rejected", RejectionType.Temporary)); _heldReleases = new List(); diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs index 3f86e1f232..2457fe8265 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveGrabbedFixture.cs @@ -56,7 +56,7 @@ public void Setup() _remoteMovie.ParsedMovieInfo = _parsedMovieInfo; _remoteMovie.Release = _release; - _temporarilyRejected = new DownloadDecision(_remoteMovie, new Rejection("Temp Rejected", RejectionType.Temporary)); + _temporarilyRejected = new DownloadDecision(_remoteMovie, new DownloadRejection(DownloadRejectionReason.MinimumAgeDelay, "Temp Rejected", RejectionType.Temporary)); _heldReleases = new List(); diff --git a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs index 9778581158..ade605a8c9 100644 --- a/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs +++ b/src/NzbDrone.Core.Test/Download/Pending/PendingReleaseServiceTests/RemoveRejectedFixture.cs @@ -59,7 +59,7 @@ public void Setup() _remoteMovie.ParsedMovieInfo = _parsedMovieInfo; _remoteMovie.Release = _release; - _temporarilyRejected = new DownloadDecision(_remoteMovie, new Rejection("Temp Rejected", RejectionType.Temporary)); + _temporarilyRejected = new DownloadDecision(_remoteMovie, new DownloadRejection(DownloadRejectionReason.MinimumAgeDelay, "Temp Rejected", RejectionType.Temporary)); Mocker.GetMock() .Setup(s => s.All()) diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportApprovedMoviesFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportApprovedMoviesFixture.cs index 099b6580a9..6e23a21f45 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportApprovedMoviesFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportApprovedMoviesFixture.cs @@ -7,7 +7,6 @@ using NUnit.Framework; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles; @@ -46,9 +45,9 @@ public void Setup() .With(s => s.Path = @"C:\Test\TV\30 Rock".AsOsAgnostic()) .Build(); - _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new Rejection("Rejected!"))); - _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new Rejection("Rejected!"))); - _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new Rejection("Rejected!"))); + _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new ImportRejection(ImportRejectionReason.Unknown, "Rejected!"))); + _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new ImportRejection(ImportRejectionReason.Unknown, "Rejected!"))); + _rejectedDecisions.Add(new ImportDecision(new LocalMovie(), new ImportRejection(ImportRejectionReason.Unknown, "Rejected!"))); _approvedDecisions.Add(new ImportDecision( new LocalMovie diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportDecisionMakerFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportDecisionMakerFixture.cs index 8ef04bfcbc..493621bfa2 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportDecisionMakerFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/ImportDecisionMakerFixture.cs @@ -4,7 +4,6 @@ using FluentAssertions; using Moq; using NUnit.Framework; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.MediaFiles; using NzbDrone.Core.MediaFiles.MovieImport; @@ -49,13 +48,13 @@ public void Setup() _fail2 = new Mock(); _fail3 = new Mock(); - _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Accept()); - _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Accept()); - _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Accept()); + _pass1.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Accept()); + _pass2.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Accept()); + _pass3.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Accept()); - _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Reject("_fail1")); - _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Reject("_fail2")); - _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(Decision.Reject("_fail3")); + _fail1.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Reject(ImportRejectionReason.Unknown, "_fail1")); + _fail2.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Reject(ImportRejectionReason.Unknown, "_fail2")); + _fail3.Setup(c => c.IsSatisfiedBy(It.IsAny(), It.IsAny())).Returns(ImportSpecDecision.Reject(ImportRejectionReason.Unknown, "_fail3")); _movie = Builder.CreateNew() .With(e => e.Path = @"C:\Test\Movie".AsOsAgnostic()) diff --git a/src/NzbDrone.Core/DecisionEngine/Decision.cs b/src/NzbDrone.Core/DecisionEngine/Decision.cs deleted file mode 100644 index 160e2599d7..0000000000 --- a/src/NzbDrone.Core/DecisionEngine/Decision.cs +++ /dev/null @@ -1,32 +0,0 @@ -namespace NzbDrone.Core.DecisionEngine -{ - public class Decision - { - public bool Accepted { get; private set; } - public string Reason { get; private set; } - - private static readonly Decision AcceptDecision = new Decision { Accepted = true }; - private Decision() - { - } - - public static Decision Accept() - { - return AcceptDecision; - } - - public static Decision Reject(string reason, params object[] args) - { - return Reject(string.Format(reason, args)); - } - - public static Decision Reject(string reason) - { - return new Decision - { - Accepted = false, - Reason = reason - }; - } - } -} diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecision.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecision.cs index 382c787bf8..fce86b2fea 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecision.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecision.cs @@ -8,7 +8,7 @@ public class DownloadDecision { public RemoteMovie RemoteMovie { get; private set; } - public IEnumerable Rejections { get; private set; } + public IEnumerable Rejections { get; private set; } public bool Approved => !Rejections.Any(); @@ -28,7 +28,7 @@ public bool Rejected } } - public DownloadDecision(RemoteMovie movie, params Rejection[] rejections) + public DownloadDecision(RemoteMovie movie, params DownloadRejection[] rejections) { RemoteMovie = movie; Rejections = rejections.ToList(); diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index b7d05f541e..e1d3f09063 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -23,14 +23,14 @@ public interface IMakeDownloadDecision public class DownloadDecisionMaker : IMakeDownloadDecision { - private readonly IEnumerable _specifications; + private readonly IEnumerable _specifications; private readonly IParsingService _parsingService; private readonly IConfigService _configService; private readonly ICustomFormatCalculationService _formatCalculator; private readonly IRemoteMovieAggregationService _aggregationService; private readonly Logger _logger; - public DownloadDecisionMaker(IEnumerable specifications, + public DownloadDecisionMaker(IEnumerable specifications, IParsingService parsingService, IConfigService configService, ICustomFormatCalculationService formatCalculator, @@ -85,9 +85,7 @@ private IEnumerable GetDecisions(List reports, bo if (remoteMovie.Movie == null) { - var reason = "Unknown Movie"; - - decision = new DownloadDecision(remoteMovie, new Rejection(reason)); + decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnknownMovie, "Unknown Movie")); } else { @@ -123,7 +121,7 @@ private IEnumerable GetDecisions(List reports, bo Languages = parsedMovieInfo.Languages }; - decision = new DownloadDecision(remoteMovie, new Rejection("Unable to parse release")); + decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnableToParse, "Unable to parse release")); } } } @@ -132,7 +130,7 @@ private IEnumerable GetDecisions(List reports, bo _logger.Error(e, "Couldn't process release."); var remoteMovie = new RemoteMovie { Release = report }; - decision = new DownloadDecision(remoteMovie, new Rejection("Unexpected error processing release")); + decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.Error, "Unexpected error processing release")); } reportNumber++; @@ -175,7 +173,7 @@ private IEnumerable GetDecisions(List reports, bo private DownloadDecision GetDecisionForReport(RemoteMovie remoteMovie, SearchCriteriaBase searchCriteria = null) { - var reasons = Array.Empty(); + var reasons = Array.Empty(); foreach (var specifications in _specifications.GroupBy(v => v.Priority).OrderBy(v => v.Key)) { @@ -192,7 +190,7 @@ private DownloadDecision GetDecisionForReport(RemoteMovie remoteMovie, SearchCri return new DownloadDecision(remoteMovie, reasons.ToArray()); } - private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteMovie remoteMovie, SearchCriteriaBase searchCriteriaBase = null) + private DownloadRejection EvaluateSpec(IDownloadDecisionEngineSpecification spec, RemoteMovie remoteMovie, SearchCriteriaBase searchCriteriaBase = null) { try { @@ -200,7 +198,7 @@ private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteMovie re if (!result.Accepted) { - return new Rejection(result.Reason, spec.Type); + return new DownloadRejection(result.Reason, result.Message, spec.Type); } } catch (NotImplementedException) @@ -212,7 +210,7 @@ private Rejection EvaluateSpec(IDecisionEngineSpecification spec, RemoteMovie re e.Data.Add("report", remoteMovie.Release.ToJson()); e.Data.Add("parsed", remoteMovie.ParsedMovieInfo.ToJson()); _logger.Error(e, "Couldn't evaluate decision on {0}, with spec: {1}", remoteMovie.Release.Title, spec.GetType().Name); - return new Rejection($"{spec.GetType().Name}: {e.Message}"); + return new DownloadRejection(DownloadRejectionReason.DecisionError, $"{spec.GetType().Name}: {e.Message}"); } return null; diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadRejection.cs b/src/NzbDrone.Core/DecisionEngine/DownloadRejection.cs new file mode 100644 index 0000000000..fbaeccdf12 --- /dev/null +++ b/src/NzbDrone.Core/DecisionEngine/DownloadRejection.cs @@ -0,0 +1,9 @@ +namespace NzbDrone.Core.DecisionEngine; + +public class DownloadRejection : Rejection +{ + public DownloadRejection(DownloadRejectionReason reason, string message, RejectionType type = RejectionType.Permanent) + : base(reason, message, type) + { + } +} diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadRejectionReason.cs b/src/NzbDrone.Core/DecisionEngine/DownloadRejectionReason.cs new file mode 100644 index 0000000000..887acc1216 --- /dev/null +++ b/src/NzbDrone.Core/DecisionEngine/DownloadRejectionReason.cs @@ -0,0 +1,67 @@ +namespace NzbDrone.Core.DecisionEngine; + +public enum DownloadRejectionReason +{ + Unknown, + UnknownMovie, + UnableToParse, + Error, + DecisionError, + Availability, + MinimumAgeDelay, + MovieNotMonitored, + HistoryRecentCutoffMet, + HistoryCdhDisabledCutoffMet, + HistoryHigherPreference, + HistoryHigherRevision, + HistoryCutoffMet, + HistoryCustomFormatCutoffMet, + HistoryCustomFormatScore, + HistoryCustomFormatScoreIncrement, + HistoryUpgradesNotAllowed, + NoMatchingTag, + PropersDisabled, + ProperForOldFile, + WrongMovie, + UnknownRuntime, + BelowMinimumSize, + AboveMaximumSize, + AlreadyImportedSameHash, + AlreadyImportedSameName, + IndexerDisabled, + Blocklisted, + CustomFormatMinimumScore, + MinimumFreeSpace, + HardcodeSubtitles, + WantedLanguage, + MaximumSizeExceeded, + MinimumAge, + MaximumAge, + Sample, + ProtocolDisabled, + QualityNotWanted, + QualityUpgradesDisabled, + QueueHigherPreference, + QueueHigherRevision, + QueueCutoffMet, + QueueCustomFormatCutoffMet, + QueueCustomFormatScore, + QueueCustomFormatScoreIncrement, + QueueUpgradesNotAllowed, + QueuePropersDisabled, + Raw, + MustContainMissing, + MustNotContainPresent, + RepackDisabled, + RepackUnknownReleaseGroup, + RepackReleaseGroupDoesNotMatch, + RequiredFlags, + MinimumSeeders, + DiskHigherPreference, + DiskHigherRevision, + DiskCutoffMet, + DiskCustomFormatCutoffMet, + DiskCustomFormatScore, + DiskCustomFormatScoreIncrement, + DiskUpgradesNotAllowed +} diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadSpecDecision.cs b/src/NzbDrone.Core/DecisionEngine/DownloadSpecDecision.cs new file mode 100644 index 0000000000..53653293d7 --- /dev/null +++ b/src/NzbDrone.Core/DecisionEngine/DownloadSpecDecision.cs @@ -0,0 +1,34 @@ +namespace NzbDrone.Core.DecisionEngine +{ + public class DownloadSpecDecision + { + public bool Accepted { get; private set; } + public DownloadRejectionReason Reason { get; set; } + public string Message { get; private set; } + + private static readonly DownloadSpecDecision AcceptDownloadSpecDecision = new () { Accepted = true }; + private DownloadSpecDecision() + { + } + + public static DownloadSpecDecision Accept() + { + return AcceptDownloadSpecDecision; + } + + public static DownloadSpecDecision Reject(DownloadRejectionReason reason, string message, params object[] args) + { + return Reject(reason, string.Format(message, args)); + } + + public static DownloadSpecDecision Reject(DownloadRejectionReason reason, string message) + { + return new DownloadSpecDecision + { + Accepted = false, + Reason = reason, + Message = message + }; + } + } +} diff --git a/src/NzbDrone.Core/DecisionEngine/Rejection.cs b/src/NzbDrone.Core/DecisionEngine/Rejection.cs index 723968f9b6..1f7057ea27 100644 --- a/src/NzbDrone.Core/DecisionEngine/Rejection.cs +++ b/src/NzbDrone.Core/DecisionEngine/Rejection.cs @@ -1,19 +1,21 @@ namespace NzbDrone.Core.DecisionEngine { - public class Rejection + public class Rejection { - public string Reason { get; set; } + public TRejectionReason Reason { get; set; } + public string Message { get; set; } public RejectionType Type { get; set; } - public Rejection(string reason, RejectionType type = RejectionType.Permanent) + public Rejection(TRejectionReason reason, string message, RejectionType type = RejectionType.Permanent) { Reason = reason; + Message = message; Type = type; } public override string ToString() { - return string.Format("[{0}] {1}", Type, Reason); + return string.Format("[{0}] {1}", Type, Message); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs index 8d9f3cfd8c..7eff909836 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AcceptableSizeSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class AcceptableSizeSpecification : IDecisionEngineSpecification + public class AcceptableSizeSpecification : IDownloadDecisionEngineSpecification { private readonly IQualityDefinitionService _qualityDefinitionService; private readonly Logger _logger; @@ -20,7 +20,7 @@ public AcceptableSizeSpecification(IQualityDefinitionService qualityDefinitionSe public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Beginning size check for: {0}", subject); @@ -29,7 +29,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (subject.Release.Size == 0) { _logger.Debug("Release has unknown size, skipping size check"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var qualityDefinition = _qualityDefinitionService.Get(quality); @@ -53,7 +53,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit var runtimeMessage = subject.Movie.Title; _logger.Debug("Item: {0}, Size: {1} is smaller than minimum allowed size ({2} bytes for {3}), rejecting.", subject, subject.Release.Size, minSize, runtimeMessage); - return Decision.Reject("{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage); + return DownloadSpecDecision.Reject(DownloadRejectionReason.BelowMinimumSize, "{0} is smaller than minimum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), minSize.SizeSuffix(), runtimeMessage); } } @@ -64,7 +64,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit else if (subject.Movie.MovieMetadata.Value.Runtime == 0) { _logger.Debug("Movie runtime is 0, unable to validate size until it is available, rejecting"); - return Decision.Reject("Movie runtime is 0, unable to validate size until it is available"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.UnknownRuntime, "Movie runtime is 0, unable to validate size until it is available"); } else { @@ -77,12 +77,12 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (subject.Release.Size > maxSize) { _logger.Debug("Item: {0}, Size: {1} is greater than maximum allowed size ({2} for {3}), rejecting", subject, subject.Release.Size, maxSize, subject.Movie.Title); - return Decision.Reject("{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), subject.Movie.Title); + return DownloadSpecDecision.Reject(DownloadRejectionReason.AboveMaximumSize, "{0} is larger than maximum allowed {1} (for {2})", subject.Release.Size.SizeSuffix(), maxSize.SizeSuffix(), subject.Movie.Title); } } _logger.Debug("Item: {0}, meets size constraints", subject); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs index 47bba7aafb..6d46a22dda 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/AlreadyImportedSpecification.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class AlreadyImportedSpecification : IDecisionEngineSpecification + public class AlreadyImportedSpecification : IDownloadDecisionEngineSpecification { private readonly IHistoryService _historyService; private readonly IConfigService _configService; @@ -27,14 +27,14 @@ public AlreadyImportedSpecification(IHistoryService historyService, public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var cdhEnabled = _configService.EnableCompletedDownloadHandling; if (!cdhEnabled) { _logger.Debug("Skipping already imported check because CDH is disabled"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var movie = subject.Movie; @@ -45,7 +45,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (!movie.HasFile) { _logger.Debug("Skipping already imported check for movie without file"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var historyForMovie = _historyService.GetByMovieId(movie.Id, null); @@ -53,7 +53,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (lastGrabbed == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var imported = historyForMovie.FirstOrDefault(h => @@ -62,7 +62,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (imported == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } // This is really only a guard against redownloading the same release over @@ -70,7 +70,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit // match skip this check. if (lastGrabbed.Quality.Equals(imported.Quality)) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var release = subject.Release; @@ -82,7 +82,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (torrentInfo?.InfoHash != null && torrentInfo.InfoHash.ToUpper() == lastGrabbed.DownloadId) { _logger.Debug("Has same torrent hash as a grabbed and imported release"); - return Decision.Reject("Has same torrent hash as a grabbed and imported release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.AlreadyImportedSameHash, "Has same torrent hash as a grabbed and imported release"); } } @@ -91,11 +91,11 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (release.Title.Equals(lastGrabbed.SourceTitle, StringComparison.InvariantCultureIgnoreCase)) { _logger.Debug("Has same release name as a grabbed and imported release"); - return Decision.Reject("Has same release name as a grabbed and imported release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.AlreadyImportedSameName, "Has same release name as a grabbed and imported release"); } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/BlockedIndexerSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/BlockedIndexerSpecification.cs index de462311dc..cdbaecd0a2 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/BlockedIndexerSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/BlockedIndexerSpecification.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class BlockedIndexerSpecification : IDecisionEngineSpecification + public class BlockedIndexerSpecification : IDownloadDecisionEngineSpecification { private readonly IIndexerStatusService _indexerStatusService; private readonly Logger _logger; @@ -27,15 +27,15 @@ public BlockedIndexerSpecification(IIndexerStatusService indexerStatusService, I public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Temporary; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var status = _blockedIndexerCache.Find(subject.Release.IndexerId.ToString()); if (status != null) { - return Decision.Reject($"Indexer {subject.Release.Indexer} is blocked till {status.DisabledTill} due to failures, cannot grab release."); + return DownloadSpecDecision.Reject(DownloadRejectionReason.IndexerDisabled, $"Indexer {subject.Release.Indexer} is blocked till {status.DisabledTill} due to failures, cannot grab release."); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } private IDictionary FetchBlockedIndexer() diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/BlocklistSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/BlocklistSpecification.cs index 113f99a6c7..8d59181597 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/BlocklistSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/BlocklistSpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class BlocklistSpecification : IDecisionEngineSpecification + public class BlocklistSpecification : IDownloadDecisionEngineSpecification { private readonly IBlocklistService _blocklistService; private readonly Logger _logger; @@ -19,15 +19,15 @@ public BlocklistSpecification(IBlocklistService blocklistService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (_blocklistService.Blocklisted(subject.Movie.Id, subject.Release)) { _logger.Debug("{0} is blocklisted, rejecting.", subject.Release.Title); - return Decision.Reject("Release is blocklisted"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Blocklisted, "Release is blocklisted"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs index 891a4c26d2..81d0e110f4 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/CustomFormatAllowedByProfileSpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class CustomFormatAllowedbyProfileSpecification : IDecisionEngineSpecification + public class CustomFormatAllowedbyProfileSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -17,19 +17,19 @@ public CustomFormatAllowedbyProfileSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var minScore = subject.Movie.QualityProfile.MinFormatScore; var score = subject.CustomFormatScore; if (score < minScore) { - return Decision.Reject("Custom Formats {0} have score {1} below Movie's profile minimum {2}", subject.CustomFormats.ConcatToString(), score, minScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.CustomFormatMinimumScore, "Custom Formats {0} have score {1} below Movie's profile minimum {2}", subject.CustomFormats.ConcatToString(), score, minScore); } _logger.Trace("Custom Format Score of {0} [{1}] above Movie's profile minimum {2}", score, subject.CustomFormats.ConcatToString(), minScore); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs index e35a609462..2067615d27 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class FreeSpaceSpecification : IDecisionEngineSpecification + public class FreeSpaceSpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly IDiskProvider _diskProvider; @@ -24,12 +24,12 @@ public FreeSpaceSpecification(IConfigService configService, IDiskProvider diskPr public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (_configService.SkipFreeSpaceCheckWhenImporting) { _logger.Debug("Skipping free space check"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var size = subject.Release.Size; @@ -49,7 +49,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit { _logger.Debug("Unable to get available space for {0}. Skipping", path); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var minimumSpace = _configService.MinimumFreeSpaceWhenImporting.Megabytes(); @@ -60,7 +60,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit var message = "Importing after download will exceed available disk space"; _logger.Debug(message); - return Decision.Reject(message); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MinimumFreeSpace, message); } if (remainingSpace < minimumSpace) @@ -68,10 +68,10 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit var message = $"Not enough free space ({minimumSpace.SizeSuffix()}) to import after download: {remainingSpace.SizeSuffix()}. (Settings: Media Management: Minimum Free Space)"; _logger.Debug(message); - return Decision.Reject(message); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MinimumFreeSpace, message); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/HardcodeSubsSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/HardcodeSubsSpecification.cs index 16fd5efc43..dadb6fac59 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/HardcodeSubsSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/HardcodeSubsSpecification.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class HardcodeSubsSpecification : IDecisionEngineSpecification + public class HardcodeSubsSpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly Logger _logger; @@ -21,13 +21,13 @@ public HardcodeSubsSpecification(IConfigService configService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var hardcodeSubs = subject.ParsedMovieInfo.HardcodedSubs; if (_configService.AllowHardcodedSubs || hardcodeSubs.IsNullOrWhiteSpace()) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var whitelisted = _configService.WhitelistedHardcodedSubs.Split(','); @@ -35,12 +35,12 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (whitelisted != null && whitelisted.Any(t => (hardcodeSubs.ToLower().Contains(t.ToLower()) && t.IsNotNullOrWhiteSpace()))) { _logger.Debug("Release hardcode subs ({0}) are in allowed values ({1})", hardcodeSubs, whitelisted); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } else { _logger.Debug("Hardcode subs found: {0}", hardcodeSubs); - return Decision.Reject("Hardcode subs found: {0}", hardcodeSubs); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HardcodeSubtitles, "Hardcode subs found: {0}", hardcodeSubs); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/IDecisionEngineSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/IDownloadDecisionEngineSpecification.cs similarity index 60% rename from src/NzbDrone.Core/DecisionEngine/Specifications/IDecisionEngineSpecification.cs rename to src/NzbDrone.Core/DecisionEngine/Specifications/IDownloadDecisionEngineSpecification.cs index 9d94e945f1..c4bb1a49cb 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/IDecisionEngineSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/IDownloadDecisionEngineSpecification.cs @@ -3,12 +3,12 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public interface IDecisionEngineSpecification + public interface IDownloadDecisionEngineSpecification { RejectionType Type { get; } SpecificationPriority Priority { get; } - Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria); + DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria); } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs index eb557b170c..c480ea20dc 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/LanguageSpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class LanguageSpecification : IDecisionEngineSpecification + public class LanguageSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -17,14 +17,14 @@ public LanguageSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var wantedLanguage = subject.Movie.QualityProfile.Language; if (wantedLanguage == Language.Any) { _logger.Debug("Profile allows any language, accepting release."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var originalLanguage = subject.Movie.MovieMetadata.Value.OriginalLanguage; @@ -34,10 +34,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (!subject.Languages.Contains(originalLanguage)) { _logger.Debug("Original Language({0}) is wanted, but found {1}", originalLanguage, subject.Languages.ToExtendedString()); - return Decision.Reject("Original Language ({0}) is wanted, but found {1}", originalLanguage, subject.Languages.ToExtendedString()); + return DownloadSpecDecision.Reject(DownloadRejectionReason.WantedLanguage, "Original Language ({0}) is wanted, but found {1}", originalLanguage, subject.Languages.ToExtendedString()); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } _logger.Debug("Checking if report meets language requirements. {0}", subject.ParsedMovieInfo.Languages.ToExtendedString()); @@ -45,10 +45,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (!subject.Languages.Contains(wantedLanguage)) { _logger.Debug("Report Language: {0} rejected because it is not wanted, wanted {1}", subject.Languages.ToExtendedString(), wantedLanguage); - return Decision.Reject("{0} is wanted, but found {1}", wantedLanguage, subject.Languages.ToExtendedString()); + return DownloadSpecDecision.Reject(DownloadRejectionReason.WantedLanguage, "{0} is wanted, but found {1}", wantedLanguage, subject.Languages.ToExtendedString()); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/MaximumSizeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/MaximumSizeSpecification.cs index 65e42c5e20..731a62001b 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/MaximumSizeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/MaximumSizeSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class MaximumSizeSpecification : IDecisionEngineSpecification + public class MaximumSizeSpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly Logger _logger; @@ -20,7 +20,7 @@ public MaximumSizeSpecification(IConfigService configService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var size = subject.Release.Size; var maximumSize = _configService.MaximumSize.Megabytes(); @@ -28,13 +28,13 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (maximumSize == 0) { _logger.Debug("Maximum size is not set."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (size == 0) { _logger.Debug("Release has unknown size, skipping size check."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } _logger.Debug("Checking if release meets maximum size requirements. {0}", size.SizeSuffix()); @@ -44,10 +44,10 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit var message = $"{size.SizeSuffix()} is too big, maximum size is {maximumSize.SizeSuffix()} (Settings->Indexers->Maximum Size)"; _logger.Debug(message); - return Decision.Reject(message); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MaximumSizeExceeded, message); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/MinimumAgeSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/MinimumAgeSpecification.cs index 53e228de03..d979fd5958 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/MinimumAgeSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/MinimumAgeSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class MinimumAgeSpecification : IDecisionEngineSpecification + public class MinimumAgeSpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly Logger _logger; @@ -20,12 +20,12 @@ public MinimumAgeSpecification(IConfigService configService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Temporary; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (subject.Release.DownloadProtocol != Indexers.DownloadProtocol.Usenet) { _logger.Debug("Not checking minimum age requirement for non-usenet report"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var age = subject.Release.AgeMinutes; @@ -35,7 +35,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (minimumAge == 0) { _logger.Debug("Minimum age is not set."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } _logger.Debug("Checking if report meets minimum age requirements. {0}", ageRounded); @@ -43,12 +43,12 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (age < minimumAge) { _logger.Debug("Only {0} minutes old, minimum age is {1} minutes", ageRounded, minimumAge); - return Decision.Reject("Only {0} minutes old, minimum age is {1} minutes", ageRounded, minimumAge); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MinimumAge, "Only {0} minutes old, minimum age is {1} minutes", ageRounded, minimumAge); } _logger.Debug("Release is {0} minutes old, greater than minimum age of {1} minutes", ageRounded, minimumAge); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs index 0c4a9cdec3..37c4347a64 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/NotSampleSpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class NotSampleSpecification : IDecisionEngineSpecification + public class NotSampleSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -17,15 +17,15 @@ public NotSampleSpecification(Logger logger) _logger = logger; } - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (subject.Release.Title.ToLower().Contains("sample") && subject.Release.Size < 70.Megabytes()) { _logger.Debug("Sample release, rejecting."); - return Decision.Reject("Sample"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Sample, "Sample"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/ProtocolSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/ProtocolSpecification.cs index abf8abc00f..96f14bcfde 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/ProtocolSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/ProtocolSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class ProtocolSpecification : IDecisionEngineSpecification + public class ProtocolSpecification : IDownloadDecisionEngineSpecification { private readonly IDelayProfileService _delayProfileService; private readonly Logger _logger; @@ -21,23 +21,23 @@ public ProtocolSpecification(IDelayProfileService delayProfileService, public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var delayProfile = _delayProfileService.BestForTags(subject.Movie.Tags); if (subject.Release.DownloadProtocol == DownloadProtocol.Usenet && !delayProfile.EnableUsenet) { _logger.Debug("[{0}] Usenet is not enabled for this movie", subject.Release.Title); - return Decision.Reject("Usenet is not enabled for this movie"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.ProtocolDisabled, "Usenet is not enabled for this movie"); } if (subject.Release.DownloadProtocol == DownloadProtocol.Torrent && !delayProfile.EnableTorrent) { _logger.Debug("[{0}] Torrent is not enabled for this movie", subject.Release.Title); - return Decision.Reject("Torrent is not enabled for this movie"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.ProtocolDisabled, "Torrent is not enabled for this movie"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs index 88a1432f88..d360f035e3 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QualityAllowedByProfileSpecification.cs @@ -4,7 +4,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class QualityAllowedByProfileSpecification : IDecisionEngineSpecification + public class QualityAllowedByProfileSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -16,7 +16,7 @@ public QualityAllowedByProfileSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Checking if report meets quality requirements. {0}", subject.ParsedMovieInfo.Quality); @@ -27,10 +27,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (!qualityOrGroup.Allowed) { _logger.Debug("Quality {0} rejected by Movie's quality profile", subject.ParsedMovieInfo.Quality); - return Decision.Reject("{0} is not wanted in profile", subject.ParsedMovieInfo.Quality.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QualityNotWanted, "{0} is not wanted in profile", subject.ParsedMovieInfo.Quality.Quality); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs index f4d96eb763..8eefb2ada3 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/QueueSpecification.cs @@ -11,7 +11,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class QueueSpecification : IDecisionEngineSpecification + public class QueueSpecification : IDownloadDecisionEngineSpecification { private readonly IQueueService _queueService; private readonly UpgradableSpecification _upgradableSpecification; @@ -35,7 +35,7 @@ public QueueSpecification(IQueueService queueService, public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var queue = _queueService.GetQueue(); var matchingMovies = queue.Where(q => q.RemoteMovie?.Movie != null && @@ -66,7 +66,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit queuedItemCustomFormats, subject.ParsedMovieInfo.Quality)) { - return Decision.Reject("Quality for release in queue already meets cutoff: {0}", remoteMovie.ParsedMovieInfo.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueCutoffMet, "Quality for release in queue already meets cutoff: {0}", remoteMovie.ParsedMovieInfo.Quality); } _logger.Debug("Checking if release is higher quality than queued release. Queued quality is: {0}", remoteMovie.ParsedMovieInfo.Quality); @@ -80,25 +80,25 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit switch (upgradeableRejectReason) { case UpgradeableRejectReason.BetterQuality: - return Decision.Reject("Release in queue is of equal or higher preference: {0}", remoteMovie.ParsedMovieInfo.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueHigherPreference, "Release in queue is of equal or higher preference: {0}", remoteMovie.ParsedMovieInfo.Quality); case UpgradeableRejectReason.BetterRevision: - return Decision.Reject("Release in queue is of equal or higher revision: {0}", remoteMovie.ParsedMovieInfo.Quality.Revision); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueHigherRevision, "Release in queue is of equal or higher revision: {0}", remoteMovie.ParsedMovieInfo.Quality.Revision); case UpgradeableRejectReason.QualityCutoff: - return Decision.Reject("Release in queue meets quality cutoff: {0}", qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueCutoffMet, "Release in queue meets quality cutoff: {0}", qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); case UpgradeableRejectReason.CustomFormatCutoff: - return Decision.Reject("Release in queue meets Custom Format cutoff: {0}", qualityProfile.CutoffFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueCustomFormatCutoffMet, "Release in queue meets Custom Format cutoff: {0}", qualityProfile.CutoffFormatScore); case UpgradeableRejectReason.CustomFormatScore: - return Decision.Reject("Release in queue has an equal or higher Custom Format score: {0}", qualityProfile.CalculateCustomFormatScore(queuedItemCustomFormats)); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueCustomFormatScore, "Release in queue has an equal or higher Custom Format score: {0}", qualityProfile.CalculateCustomFormatScore(queuedItemCustomFormats)); case UpgradeableRejectReason.MinCustomFormatScore: - return Decision.Reject("Release in queue has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueCustomFormatScoreIncrement, "Release in queue has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); case UpgradeableRejectReason.UpgradesNotAllowed: - return Decision.Reject("Release in queue and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueueUpgradesNotAllowed, "Release in queue and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); } if (_upgradableSpecification.IsRevisionUpgrade(remoteMovie.ParsedMovieInfo.Quality, subject.ParsedMovieInfo.Quality)) @@ -106,12 +106,12 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (_configService.DownloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade) { _logger.Debug("Auto downloading of propers is disabled"); - return Decision.Reject("Proper downloading is disabled"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QueuePropersDisabled, "Proper downloading is disabled"); } } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RawDiskSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RawDiskSpecification.cs index bde4efcfc5..884fb6f9d1 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RawDiskSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RawDiskSpecification.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class RawDiskSpecification : IDecisionEngineSpecification + public class RawDiskSpecification : IDownloadDecisionEngineSpecification { private static readonly Regex[] DiscRegex = new[] { @@ -29,11 +29,11 @@ public RawDiskSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (subject.Release == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } foreach (var regex in DiscRegex) @@ -41,28 +41,28 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (regex.IsMatch(subject.Release.Title)) { _logger.Debug("Release contains raw Bluray/DVD, rejecting."); - return Decision.Reject("Raw Bluray/DVD release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Raw, "Raw Bluray/DVD release"); } } if (subject.Release.Container.IsNullOrWhiteSpace()) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (_dvdContainerTypes.Contains(subject.Release.Container.ToLower())) { _logger.Debug("Release contains raw DVD, rejecting."); - return Decision.Reject("Raw DVD release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Raw, "Raw DVD release"); } if (_blurayContainerTypes.Contains(subject.Release.Container.ToLower())) { _logger.Debug("Release contains raw Bluray, rejecting."); - return Decision.Reject("Raw Bluray release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Raw, "Raw Bluray release"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs index 232b42d61e..3f0f360029 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/ReleaseRestrictionsSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class ReleaseRestrictionsSpecification : IDecisionEngineSpecification + public class ReleaseRestrictionsSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; private readonly IReleaseProfileService _releaseProfileService; @@ -24,7 +24,7 @@ public ReleaseRestrictionsSpecification(ITermMatcherService termMatcherService, public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { _logger.Debug("Checking if release meets restrictions: {0}", subject); @@ -43,7 +43,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se { var terms = string.Join(", ", requiredTerms); _logger.Debug("[{0}] does not contain one of the required terms: {1}", title, terms); - return Decision.Reject("Does not contain one of the required terms: {0}", terms); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MustContainMissing, "Does not contain one of the required terms: {0}", terms); } } @@ -56,12 +56,12 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se { var terms = string.Join(", ", foundTerms); _logger.Debug("[{0}] contains these ignored terms: {1}", title, terms); - return Decision.Reject("Contains these ignored terms: {0}", terms); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MustNotContainPresent, "Contains these ignored terms: {0}", terms); } } _logger.Debug("[{0}] No restrictions apply, allowing", subject); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } private List ContainsAny(List terms, string title) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RepackSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RepackSpecification.cs index f6d713281b..eb18c53130 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RepackSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RepackSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class RepackSpecification : IDecisionEngineSpecification + public class RepackSpecification : IDownloadDecisionEngineSpecification { private readonly UpgradableSpecification _upgradableSpecification; private readonly IConfigService _configService; @@ -24,19 +24,19 @@ public RepackSpecification(UpgradableSpecification upgradableSpecification, ICon public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks; if (!subject.ParsedMovieInfo.Quality.Revision.IsRepack) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer) { _logger.Debug("Repacks are not preferred, skipping check"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (subject.Movie.MovieFileId != 0) @@ -51,17 +51,17 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade) { _logger.Debug("Auto downloading of repacks is disabled"); - return Decision.Reject("Repack downloading is disabled"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.RepackDisabled, "Repack downloading is disabled"); } if (fileReleaseGroup.IsNullOrWhiteSpace()) { - return Decision.Reject("Unable to determine release group for the existing file"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.RepackUnknownReleaseGroup, "Unable to determine release group for the existing file"); } if (releaseGroup.IsNullOrWhiteSpace()) { - return Decision.Reject("Unable to determine release group for this release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.RepackUnknownReleaseGroup, "Unable to determine release group for this release"); } if (!fileReleaseGroup.Equals(releaseGroup, StringComparison.InvariantCultureIgnoreCase)) @@ -70,7 +70,8 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit "Release is a repack for a different release group. Release Group: {0}. File release group: {1}", releaseGroup, fileReleaseGroup); - return Decision.Reject( + return DownloadSpecDecision.Reject( + DownloadRejectionReason.RepackReleaseGroupDoesNotMatch, "Release is a repack for a different release group. Release Group: {0}. File release group: {1}", releaseGroup, fileReleaseGroup); @@ -78,7 +79,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RequiredIndexerFlagsSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RequiredIndexerFlagsSpecification.cs index 91a682fd6f..9dddd51ea6 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RequiredIndexerFlagsSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RequiredIndexerFlagsSpecification.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class RequiredIndexerFlagsSpecification : IDecisionEngineSpecification + public class RequiredIndexerFlagsSpecification : IDownloadDecisionEngineSpecification { private readonly IIndexerFactory _indexerFactory; private readonly Logger _logger; @@ -21,7 +21,7 @@ public RequiredIndexerFlagsSpecification(IIndexerFactory indexerFactory, Logger public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var torrentInfo = subject.Release; @@ -37,34 +37,35 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (torrentInfo == null || indexerSettings == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (indexerSettings is ITorrentIndexerSettings torrentIndexerSettings) { var requiredFlags = torrentIndexerSettings.RequiredFlags; - var requiredFlag = (IndexerFlags)0; if (requiredFlags == null || !requiredFlags.Any()) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } + var requiredFlag = (IndexerFlags)0; + foreach (var flag in requiredFlags) { if (torrentInfo.IndexerFlags.HasFlag((IndexerFlags)flag)) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } requiredFlag |= (IndexerFlags)flag; } _logger.Debug("None of the required indexer flags {0} where found. Found flags: {1}", requiredFlag, torrentInfo.IndexerFlags); - return Decision.Reject("None of the required indexer flags {0} where found. Found flags: {1}", requiredFlag, torrentInfo.IndexerFlags); + return DownloadSpecDecision.Reject(DownloadRejectionReason.RequiredFlags, "None of the required indexer flags {0} where found. Found flags: {1}", requiredFlag, torrentInfo.IndexerFlags); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs index f9860b6df2..8f34570ed6 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RetentionSpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class RetentionSpecification : IDecisionEngineSpecification + public class RetentionSpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly Logger _logger; @@ -19,12 +19,12 @@ public RetentionSpecification(IConfigService configService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (subject.Release.DownloadProtocol != Indexers.DownloadProtocol.Usenet) { _logger.Debug("Not checking retention requirement for non-usenet report"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var age = subject.Release.Age; @@ -34,10 +34,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (retention > 0 && age > retention) { _logger.Debug("Report age: {0} rejected by user's retention limit", age); - return Decision.Reject("Older than configured retention"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MaximumAge, "Older than configured retention"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/AvailabilitySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/AvailabilitySpecification.cs index 036be785bb..2a5d64ed42 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/AvailabilitySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/AvailabilitySpecification.cs @@ -5,7 +5,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class AvailabilitySpecification : IDecisionEngineSpecification + public class AvailabilitySpecification : IDownloadDecisionEngineSpecification { private readonly IConfigService _configService; private readonly Logger _logger; @@ -19,22 +19,22 @@ public AvailabilitySpecification(IConfigService configService, Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria is { UserInvokedSearch: true }) { _logger.Debug("Skipping availability check during search"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var availabilityDelay = _configService.AvailabilityDelay; if (!subject.Movie.IsAvailable(availabilityDelay)) { - return Decision.Reject("Movie {0} will only be considered available {1} days after {2}", subject.Movie, availabilityDelay, subject.Movie.MinimumAvailability.ToString()); + return DownloadSpecDecision.Reject(DownloadRejectionReason.Availability, "Movie {0} will only be considered available {1} days after {2}", subject.Movie, availabilityDelay, subject.Movie.MinimumAvailability.ToString()); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs index d7640e25b6..19eb003a46 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/DelaySpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class DelaySpecification : IDecisionEngineSpecification + public class DelaySpecification : IDownloadDecisionEngineSpecification { private readonly IPendingReleaseService _pendingReleaseService; private readonly IUpgradableSpecification _qualityUpgradableSpecification; @@ -32,12 +32,12 @@ public DelaySpecification(IPendingReleaseService pendingReleaseService, public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Temporary; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null && searchCriteria.UserInvokedSearch) { _logger.Debug("Ignoring delay for user invoked search"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var profile = subject.Movie.QualityProfile; @@ -48,7 +48,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (delay == 0) { _logger.Debug("Delay Profile does not require a waiting period before download for {0}.", subject.Release.DownloadProtocol); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } _logger.Debug("Delay Profile requires a waiting period of {0} minutes for {1}", delay, subject.Release.DownloadProtocol); @@ -73,7 +73,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (revisionUpgrade) { _logger.Debug("New quality is a better revision for existing quality, skipping delay"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } @@ -87,7 +87,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (isBestInProfile && isPreferredProtocol) { _logger.Debug("Quality is highest in profile for preferred protocol, will not delay."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } @@ -100,7 +100,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (score >= minimum && isPreferredProtocol) { _logger.Debug("Custom format score ({0}) meets minimum ({1}) for preferred protocol, will not delay", score, minimum); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } @@ -109,16 +109,16 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (oldest != null && oldest.Release.AgeMinutes > delay) { _logger.Debug("Oldest pending release {0} has been delayed for {1}, longer than the set delay of {2}. Release will be accepted", oldest.Release.Title, oldest.Release.AgeMinutes, delay); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (subject.Release.AgeMinutes < delay) { _logger.Debug("Waiting for better quality release, There is a {0} minute delay on {1}", delay, subject.Release.DownloadProtocol); - return Decision.Reject("Waiting for better quality release"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MinimumAgeDelay, "Waiting for better quality release"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs index 48b0709723..1171c6ff8b 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/HistorySpecification.cs @@ -9,7 +9,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class HistorySpecification : IDecisionEngineSpecification + public class HistorySpecification : IDownloadDecisionEngineSpecification { private readonly IHistoryService _historyService; private readonly UpgradableSpecification _upgradableSpecification; @@ -33,12 +33,12 @@ public HistorySpecification(IHistoryService historyService, public SpecificationPriority Priority => SpecificationPriority.Database; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { _logger.Debug("Skipping history check during search"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var cdhEnabled = _configService.EnableCompletedDownloadHandling; @@ -55,7 +55,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (!recent && cdhEnabled) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var customFormats = _formatService.ParseCustomFormat(mostRecent, subject.Movie); @@ -77,10 +77,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se { if (recent) { - return Decision.Reject("Recent grab event in history already meets cutoff: {0}", mostRecent.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryRecentCutoffMet, "Recent grab event in history already meets cutoff: {0}", mostRecent.Quality); } - return Decision.Reject("CDH is disabled and grab event in history already meets cutoff: {0}", mostRecent.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryCdhDisabledCutoffMet, "CDH is disabled and grab event in history already meets cutoff: {0}", mostRecent.Quality); } var rejectionSubject = recent ? "Recent" : "CDH is disabled and"; @@ -88,32 +88,32 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se switch (upgradeableRejectReason) { case UpgradeableRejectReason.None: - return Decision.Accept(); + return DownloadSpecDecision.Accept(); case UpgradeableRejectReason.BetterQuality: - return Decision.Reject("{0} grab event in history is of equal or higher preference: {1}", rejectionSubject, mostRecent.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryHigherPreference, "{0} grab event in history is of equal or higher preference: {1}", rejectionSubject, mostRecent.Quality); case UpgradeableRejectReason.BetterRevision: - return Decision.Reject("{0} grab event in history is of equal or higher revision: {1}", rejectionSubject, mostRecent.Quality.Revision); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryHigherRevision, "{0} grab event in history is of equal or higher revision: {1}", rejectionSubject, mostRecent.Quality.Revision); case UpgradeableRejectReason.QualityCutoff: - return Decision.Reject("{0} grab event in history meets quality cutoff: {1}", rejectionSubject, qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryCutoffMet, "{0} grab event in history meets quality cutoff: {1}", rejectionSubject, qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); case UpgradeableRejectReason.CustomFormatCutoff: - return Decision.Reject("{0} grab event in history meets Custom Format cutoff: {1}", rejectionSubject, qualityProfile.CutoffFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryCustomFormatCutoffMet, "{0} grab event in history meets Custom Format cutoff: {1}", rejectionSubject, qualityProfile.CutoffFormatScore); case UpgradeableRejectReason.CustomFormatScore: - return Decision.Reject("{0} grab event in history has an equal or higher Custom Format score: {1}", rejectionSubject, qualityProfile.CalculateCustomFormatScore(customFormats)); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryCustomFormatScore, "{0} grab event in history has an equal or higher Custom Format score: {1}", rejectionSubject, qualityProfile.CalculateCustomFormatScore(customFormats)); case UpgradeableRejectReason.MinCustomFormatScore: - return Decision.Reject("{0} grab event in history has Custom Format score within Custom Format score increment: {1}", rejectionSubject, qualityProfile.MinUpgradeFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryCustomFormatScoreIncrement, "{0} grab event in history has Custom Format score within Custom Format score increment: {1}", rejectionSubject, qualityProfile.MinUpgradeFormatScore); case UpgradeableRejectReason.UpgradesNotAllowed: - return Decision.Reject("{0} grab event in history and Quality Profile '{1}' does not allow upgrades", rejectionSubject, qualityProfile.Name); + return DownloadSpecDecision.Reject(DownloadRejectionReason.HistoryUpgradesNotAllowed, "{0} grab event in history and Quality Profile '{1}' does not allow upgrades", rejectionSubject, qualityProfile.Name); } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs index 4f02eb0656..ff391b96e9 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/IndexerTagSpecification.cs @@ -8,7 +8,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class IndexerTagSpecification : IDecisionEngineSpecification + public class IndexerTagSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; private readonly IIndexerFactory _indexerFactory; @@ -22,11 +22,11 @@ public IndexerTagSpecification(Logger logger, IIndexerFactory indexerFactory) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (subject.Release == null || subject.Movie?.Tags == null || subject.Release.IndexerId == 0) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } IndexerDefinition indexer; @@ -37,7 +37,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se catch (ModelNotFoundException) { _logger.Debug("Indexer with id {0} does not exist, skipping indexer tags check", subject.Release.IndexerId); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } // If indexer has tags, check that at least one of them is present on the series @@ -47,10 +47,10 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se { _logger.Debug("Indexer {0} has tags. None of these are present on movie {1}. Rejecting", subject.Release.Indexer, subject.Movie); - return Decision.Reject("Movie tags do not match any of the indexer tags"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.NoMatchingTag, "Movie tags do not match any of the indexer tags"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredMovieSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredMovieSpecification.cs index 0e032a03b2..de8be51e82 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredMovieSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/MonitoredMovieSpecification.cs @@ -4,7 +4,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class MonitoredMovieSpecification : IDecisionEngineSpecification + public class MonitoredMovieSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -16,23 +16,24 @@ public MonitoredMovieSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { if (searchCriteria.UserInvokedSearch) { _logger.Debug("Skipping monitored check during search"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } if (!subject.Movie.Monitored) { - return Decision.Reject("Movie is not monitored"); + _logger.Debug("{0} is present in the DB but not tracked. Rejecting", subject.Movie); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MovieNotMonitored, "Movie is not monitored"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs index 74d823849f..13b6218693 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/RssSync/ProperSpecification.cs @@ -7,7 +7,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.RssSync { - public class ProperSpecification : IDecisionEngineSpecification + public class ProperSpecification : IDownloadDecisionEngineSpecification { private readonly UpgradableSpecification _qualityUpgradableSpecification; private readonly IConfigService _configService; @@ -23,11 +23,11 @@ public ProperSpecification(UpgradableSpecification qualityUpgradableSpecificatio public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria != null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks; @@ -35,12 +35,12 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotPrefer) { _logger.Debug("Propers are not preferred, skipping check"); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } if (subject.Movie.MovieFile == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var file = subject.Movie.MovieFile; @@ -50,17 +50,17 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (downloadPropersAndRepacks == ProperDownloadTypes.DoNotUpgrade) { _logger.Debug("Auto downloading of propers is disabled"); - return Decision.Reject("Proper downloading is disabled"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.PropersDisabled, "Proper downloading is disabled"); } if (file.DateAdded < DateTime.Today.AddDays(-7)) { _logger.Debug("Proper for old file, rejecting: {0}", subject); - return Decision.Reject("Proper for old file"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.ProperForOldFile, "Proper for old file"); } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/MovieSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/MovieSpecification.cs index 5715c8d388..f7be18f9ba 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/Search/MovieSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/Search/MovieSpecification.cs @@ -4,7 +4,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications.Search { - public class MovieSpecification : IDecisionEngineSpecification + public class MovieSpecification : IDownloadDecisionEngineSpecification { private readonly Logger _logger; @@ -16,11 +16,11 @@ public MovieSpecification(Logger logger) public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { if (searchCriteria == null) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } _logger.Debug("Checking if movie matches searched movie"); @@ -28,10 +28,10 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (subject.Movie.Id != searchCriteria.Movie.Id) { _logger.Debug("Movie {0} does not match {1}", subject.Movie, searchCriteria.Movie); - return Decision.Reject("Wrong movie"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.WrongMovie, "Wrong movie"); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs index a7a6d53697..507f1f1a48 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/TorrentSeedingSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class TorrentSeedingSpecification : IDecisionEngineSpecification + public class TorrentSeedingSpecification : IDownloadDecisionEngineSpecification { private readonly IIndexerFactory _indexerFactory; private readonly Logger _logger; @@ -20,13 +20,13 @@ public TorrentSeedingSpecification(IIndexerFactory indexerFactory, Logger logger public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var torrentInfo = subject.Release as TorrentInfo; if (torrentInfo == null || torrentInfo.IndexerId == 0) { - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } IndexerDefinition indexer; @@ -37,7 +37,7 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit catch (ModelNotFoundException) { _logger.Debug("Indexer with id {0} does not exist, skipping seeders check", torrentInfo.IndexerId); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } var torrentIndexerSettings = indexer.Settings as ITorrentIndexerSettings; @@ -49,11 +49,11 @@ public Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCrit if (torrentInfo.Seeders.HasValue && torrentInfo.Seeders.Value < minimumSeeders) { _logger.Debug("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders); - return Decision.Reject("Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders); + return DownloadSpecDecision.Reject(DownloadRejectionReason.MinimumSeeders, "Not enough seeders: {0}. Minimum seeders: {1}", torrentInfo.Seeders, minimumSeeders); } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeAllowedSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeAllowedSpecification.cs index 728c6e3f45..44b0145157 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeAllowedSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeAllowedSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class UpgradeAllowedSpecification : IDecisionEngineSpecification + public class UpgradeAllowedSpecification : IDownloadDecisionEngineSpecification { private readonly UpgradableSpecification _upgradableSpecification; private readonly ICustomFormatCalculationService _formatService; @@ -24,7 +24,7 @@ public UpgradeAllowedSpecification(UpgradableSpecification upgradableSpecificati public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var qualityProfile = subject.Movie.QualityProfile; @@ -35,7 +35,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (file == null) { _logger.Debug("File is no longer available, skipping this file."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } file.Movie = subject.Movie; @@ -50,11 +50,11 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se { _logger.Debug("Upgrading is not allowed by the quality profile"); - return Decision.Reject("Existing file and the Quality profile does not allow upgrades"); + return DownloadSpecDecision.Reject(DownloadRejectionReason.QualityUpgradesDisabled, "Existing file and the Quality profile does not allow upgrades"); } } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs index ac864b0b39..ed7503c6b5 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/UpgradeDiskSpecification.cs @@ -6,7 +6,7 @@ namespace NzbDrone.Core.DecisionEngine.Specifications { - public class UpgradeDiskSpecification : IDecisionEngineSpecification + public class UpgradeDiskSpecification : IDownloadDecisionEngineSpecification { private readonly UpgradableSpecification _upgradableSpecification; private readonly ICustomFormatCalculationService _formatService; @@ -24,7 +24,7 @@ public UpgradeDiskSpecification(UpgradableSpecification upgradableSpecification, public SpecificationPriority Priority => SpecificationPriority.Default; public RejectionType Type => RejectionType.Permanent; - public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) + public virtual DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) { var qualityProfile = subject.Movie.QualityProfile; @@ -33,7 +33,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se if (file == null) { _logger.Debug("File is no longer available, skipping this file."); - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } file.Movie = subject.Movie; @@ -52,7 +52,7 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se var cutoff = qualityProfile.UpgradeAllowed ? qualityProfile.Cutoff : qualityProfile.FirststAllowedQuality().Id; var qualityCutoff = qualityProfile.Items[qualityProfile.GetIndex(cutoff).Index]; - return Decision.Reject("Existing file meets cutoff: {0} [{1}]", qualityCutoff, customFormats.ConcatToString()); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskCutoffMet, "Existing file meets cutoff: {0} [{1}]", qualityCutoff, customFormats.ConcatToString()); } var upgradeableRejectReason = _upgradableSpecification.IsUpgradable(qualityProfile, @@ -64,31 +64,31 @@ public virtual Decision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase se switch (upgradeableRejectReason) { case UpgradeableRejectReason.None: - return Decision.Accept(); + return DownloadSpecDecision.Accept(); case UpgradeableRejectReason.BetterQuality: - return Decision.Reject("Existing file on disk is of equal or higher preference: {0}", file.Quality); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskHigherPreference, "Existing file on disk is of equal or higher preference: {0}", file.Quality); case UpgradeableRejectReason.BetterRevision: - return Decision.Reject("Existing file on disk is of equal or higher revision: {0}", file.Quality.Revision); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskHigherRevision, "Existing file on disk is of equal or higher revision: {0}", file.Quality.Revision); case UpgradeableRejectReason.QualityCutoff: - return Decision.Reject("Existing file on disk meets quality cutoff: {0}", qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskCutoffMet, "Existing file on disk meets quality cutoff: {0}", qualityProfile.Items[qualityProfile.GetIndex(qualityProfile.Cutoff).Index]); case UpgradeableRejectReason.CustomFormatCutoff: - return Decision.Reject("Existing file on disk meets Custom Format cutoff: {0}", qualityProfile.CutoffFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskCustomFormatCutoffMet, "Existing file on disk meets Custom Format cutoff: {0}", qualityProfile.CutoffFormatScore); case UpgradeableRejectReason.CustomFormatScore: - return Decision.Reject("Existing file on disk has a equal or higher Custom Format score: {0}", qualityProfile.CalculateCustomFormatScore(customFormats)); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskCustomFormatScore, "Existing file on disk has a equal or higher Custom Format score: {0}", qualityProfile.CalculateCustomFormatScore(customFormats)); case UpgradeableRejectReason.MinCustomFormatScore: - return Decision.Reject("Existing file on disk has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskCustomFormatScoreIncrement, "Existing file on disk has Custom Format score within Custom Format score increment: {0}", qualityProfile.MinUpgradeFormatScore); case UpgradeableRejectReason.UpgradesNotAllowed: - return Decision.Reject("Existing file on disk and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); + return DownloadSpecDecision.Reject(DownloadRejectionReason.DiskUpgradesNotAllowed, "Existing file on disk and Quality Profile '{0}' does not allow upgrades", qualityProfile.Name); } - return Decision.Accept(); + return DownloadSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/DownloadedMovieImportService.cs b/src/NzbDrone.Core/MediaFiles/DownloadedMovieImportService.cs index 465ad0ab49..e8a0b715c0 100644 --- a/src/NzbDrone.Core/MediaFiles/DownloadedMovieImportService.cs +++ b/src/NzbDrone.Core/MediaFiles/DownloadedMovieImportService.cs @@ -7,7 +7,6 @@ using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.History; using NzbDrone.Core.MediaFiles.MovieImport; @@ -186,7 +185,7 @@ private List ProcessFolder(DirectoryInfo directoryInfo, ImportMode _logger.Warn("Unable to process folder that is mapped to an existing movie"); return new List { - RejectionResult("Import path is mapped to a movie folder") + RejectionResult(ImportRejectionReason.MovieFolder, "Import path is mapped to a movie folder") }; } @@ -272,7 +271,7 @@ private List ProcessFile(FileInfo fileInfo, ImportMode importMode, return new List { - new ImportResult(new ImportDecision(new LocalMovie { Path = fileInfo.FullName }, new Rejection("Invalid video file, filename starts with '._'")), "Invalid video file, filename starts with '._'") + new ImportResult(new ImportDecision(new LocalMovie { Path = fileInfo.FullName }, new ImportRejection(ImportRejectionReason.InvalidFilePath, "Invalid video file, filename starts with '._'")), "Invalid video file, filename starts with '._'") }; } @@ -285,7 +284,7 @@ private List ProcessFile(FileInfo fileInfo, ImportMode importMode, return new List { new ImportResult(new ImportDecision(new LocalMovie { Path = fileInfo.FullName }, - new Rejection($"Invalid video file, unsupported extension: '{extension}'")), + new ImportRejection(ImportRejectionReason.UnsupportedExtension, $"Invalid video file, unsupported extension: '{extension}'")), $"Invalid video file, unsupported extension: '{extension}'") }; } @@ -317,19 +316,19 @@ private string GetCleanedUpFolderName(string folder) private ImportResult FileIsLockedResult(string videoFile) { _logger.Debug("[{0}] is currently locked by another process, skipping", videoFile); - return new ImportResult(new ImportDecision(new LocalMovie { Path = videoFile }, new Rejection("Locked file, try again later")), "Locked file, try again later"); + return new ImportResult(new ImportDecision(new LocalMovie { Path = videoFile }, new ImportRejection(ImportRejectionReason.FileLocked, "Locked file, try again later")), "Locked file, try again later"); } private ImportResult UnknownMovieResult(string message, string videoFile = null) { var localMovie = videoFile == null ? null : new LocalMovie { Path = videoFile }; - return new ImportResult(new ImportDecision(localMovie, new Rejection("Unknown Movie")), message); + return new ImportResult(new ImportDecision(localMovie, new ImportRejection(ImportRejectionReason.UnknownMovie, "Unknown Movie")), message); } - private ImportResult RejectionResult(string message) + private ImportResult RejectionResult(ImportRejectionReason reason, string message) { - return new ImportResult(new ImportDecision(null, new Rejection(message)), message); + return new ImportResult(new ImportDecision(null, new ImportRejection(reason, message)), message); } private ImportResult CheckEmptyResultForIssue(string folder) @@ -338,12 +337,12 @@ private ImportResult CheckEmptyResultForIssue(string folder) if (files.Any(file => FileExtensions.ExecutableExtensions.Contains(Path.GetExtension(file)))) { - return RejectionResult("Caution: Found executable file"); + return RejectionResult(ImportRejectionReason.ExecutableFile, "Caution: Found executable file"); } if (files.Any(file => FileExtensions.ArchiveExtensions.Contains(Path.GetExtension(file)))) { - return RejectionResult("Found archive file, might need to be extracted"); + return RejectionResult(ImportRejectionReason.ArchiveFile, "Found archive file, might need to be extracted"); } return null; diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/IImportDecisionEngineSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/IImportDecisionEngineSpecification.cs index 9d6fe6f0a0..20d16b3dfd 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/IImportDecisionEngineSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/IImportDecisionEngineSpecification.cs @@ -1,4 +1,3 @@ -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -6,6 +5,6 @@ namespace NzbDrone.Core.MediaFiles.MovieImport { public interface IImportDecisionEngineSpecification { - Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem); + ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem); } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs index 4d14c0620d..5bf3cad387 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportApprovedMovie.cs @@ -203,7 +203,7 @@ public List Import(List decisions, bool newDownloa // Adding all the rejected decisions importResults.AddRange(decisions.Where(c => !c.Approved) - .Select(d => new ImportResult(d, d.Rejections.Select(r => r.Reason).ToArray()))); + .Select(d => new ImportResult(d, d.Rejections.Select(r => r.Message).ToArray()))); return importResults; } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecision.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecision.cs index a8574e64c0..7f33d08ff1 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecision.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecision.cs @@ -1,7 +1,6 @@ using System.Collections.Generic; using System.Linq; using NzbDrone.Common.Extensions; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Parser.Model; namespace NzbDrone.Core.MediaFiles.MovieImport @@ -9,24 +8,14 @@ namespace NzbDrone.Core.MediaFiles.MovieImport public class ImportDecision { public LocalMovie LocalMovie { get; private set; } - public IEnumerable Rejections { get; private set; } + public IEnumerable Rejections { get; private set; } public bool Approved => Rejections.Empty(); - public ImportDecision(LocalMovie localMovie, params Rejection[] rejections) + public ImportDecision(LocalMovie localMovie, params ImportRejection[] rejections) { LocalMovie = localMovie; Rejections = rejections.ToList(); - - // LocalMovie = new LocalMovie - // { - // Quality = localMovie.Quality, - // ExistingFile = localMovie.ExistingFile, - // MediaInfo = localMovie.MediaInfo, - // ParsedMovieInfo = localMovie.ParsedMovieInfo, - // Path = localMovie.Path, - // Size = localMovie.Size - // }; } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecisionMaker.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecisionMaker.cs index 33028a76af..46c464fefd 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecisionMaker.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportDecisionMaker.cs @@ -5,7 +5,6 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.CustomFormats; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.MediaFiles.MovieImport.Aggregation; @@ -128,7 +127,7 @@ private ImportDecision GetDecision(LocalMovie localMovie, DownloadClientItem dow if (localMovie.Movie == null) { - decision = new ImportDecision(localMovie, new Rejection("Invalid movie")); + decision = new ImportDecision(localMovie, new ImportRejection(ImportRejectionReason.InvalidMovie, "Invalid movie")); } else { @@ -150,13 +149,13 @@ private ImportDecision GetDecision(LocalMovie localMovie, DownloadClientItem dow } catch (AugmentingFailedException) { - decision = new ImportDecision(localMovie, new Rejection("Unable to parse file")); + decision = new ImportDecision(localMovie, new ImportRejection(ImportRejectionReason.UnableToParse, "Unable to parse file")); } catch (Exception ex) { _logger.Error(ex, "Couldn't import file. {0}", localMovie.Path); - decision = new ImportDecision(localMovie, new Rejection("Unexpected error processing file")); + decision = new ImportDecision(localMovie, new ImportRejection(ImportRejectionReason.Error, "Unexpected error processing file")); } if (decision == null) @@ -175,7 +174,7 @@ private ImportDecision GetDecision(LocalMovie localMovie, DownloadClientItem dow return decision; } - private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMovie localMovie, DownloadClientItem downloadClientItem) + private ImportRejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMovie localMovie, DownloadClientItem downloadClientItem) { try { @@ -183,7 +182,7 @@ private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMov if (!result.Accepted) { - return new Rejection(result.Reason); + return new ImportRejection(result.Reason, result.Message); } } catch (NotImplementedException e) @@ -194,7 +193,7 @@ private Rejection EvaluateSpec(IImportDecisionEngineSpecification spec, LocalMov catch (Exception ex) { _logger.Error(ex, "Couldn't evaluate decision on {0}", localMovie.Path); - return new Rejection($"{spec.GetType().Name}: {ex.Message}"); + return new ImportRejection(ImportRejectionReason.DecisionError, $"{spec.GetType().Name}: {ex.Message}"); } return null; diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejection.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejection.cs new file mode 100644 index 0000000000..8a75de9e4e --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejection.cs @@ -0,0 +1,11 @@ +using NzbDrone.Core.DecisionEngine; + +namespace NzbDrone.Core.MediaFiles.MovieImport; + +public class ImportRejection : Rejection +{ + public ImportRejection(ImportRejectionReason reason, string message, RejectionType type = RejectionType.Permanent) + : base(reason, message, type) + { + } +} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejectionReason.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejectionReason.cs new file mode 100644 index 0000000000..9240599fd7 --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportRejectionReason.cs @@ -0,0 +1,28 @@ +namespace NzbDrone.Core.MediaFiles.MovieImport; + +public enum ImportRejectionReason +{ + Unknown, + FileLocked, + UnknownMovie, + ExecutableFile, + ArchiveFile, + MovieFolder, + InvalidFilePath, + UnsupportedExtension, + InvalidMovie, + UnableToParse, + Error, + DecisionError, + MovieAlreadyImported, + MinimumFreeSpace, + NoAudio, + MovieNotFoundInRelease, + Sample, + SampleIndeterminate, + Unpacking, + MultiPartMovie, + NotQualityUpgrade, + NotRevisionUpgrade, + NotCustomFormatUpgrade +} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/ImportSpecDecision.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportSpecDecision.cs new file mode 100644 index 0000000000..d796073bcd --- /dev/null +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/ImportSpecDecision.cs @@ -0,0 +1,34 @@ +namespace NzbDrone.Core.MediaFiles.MovieImport +{ + public class ImportSpecDecision + { + public bool Accepted { get; private set; } + public ImportRejectionReason Reason { get; set; } + public string Message { get; private set; } + + private static readonly ImportSpecDecision AcceptDecision = new () { Accepted = true }; + private ImportSpecDecision() + { + } + + public static ImportSpecDecision Accept() + { + return AcceptDecision; + } + + public static ImportSpecDecision Reject(ImportRejectionReason reason, string message, params object[] args) + { + return Reject(reason, string.Format(message, args)); + } + + public static ImportSpecDecision Reject(ImportRejectionReason reason, string message) + { + return new ImportSpecDecision + { + Accepted = false, + Reason = reason, + Message = message + }; + } + } +} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs index a809868fb1..af6bf94d1d 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs @@ -1,6 +1,5 @@ using System.Collections.Generic; using NzbDrone.Core.CustomFormats; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Languages; using NzbDrone.Core.Movies; using NzbDrone.Core.Qualities; @@ -21,7 +20,7 @@ public class ManualImportItem public List CustomFormats { get; set; } public int CustomFormatScore { get; set; } public int IndexerFlags { get; set; } - public IEnumerable Rejections { get; set; } + public IEnumerable Rejections { get; set; } public Movie Movie { get; set; } public ManualImportItem() diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs index 4bc6fe16c5..cfb96548e5 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs @@ -7,7 +7,6 @@ using NzbDrone.Common.Extensions; using NzbDrone.Common.Instrumentation.Extensions; using NzbDrone.Core.CustomFormats; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Download.TrackedDownloads; using NzbDrone.Core.Languages; @@ -255,7 +254,11 @@ private ManualImportItem ProcessFile(string rootFolder, string baseFolder, strin localMovie.Languages = LanguageParser.ParseLanguages(file); localMovie.Size = _diskProvider.GetFileSize(file); - return MapItem(new ImportDecision(localMovie, new Rejection("Unknown Movie")), rootFolder, downloadId, null); + return MapItem(new ImportDecision(localMovie, + new ImportRejection(ImportRejectionReason.UnknownMovie, "Unknown Movie")), + rootFolder, + downloadId, + null); } var importDecisions = _importDecisionMaker.GetImportDecisions(new List { file }, movie, trackedDownload?.DownloadItem, null, SceneSource(movie, baseFolder)); @@ -277,7 +280,7 @@ private ManualImportItem ProcessFile(string rootFolder, string baseFolder, strin RelativePath = rootFolder.GetRelativePath(file), Name = Path.GetFileNameWithoutExtension(file), Size = _diskProvider.GetFileSize(file), - Rejections = new List() + Rejections = new List() }; } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs index ea2bfbbdd4..98c09a89e3 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/AlreadyImportedSpecification.cs @@ -22,12 +22,12 @@ public AlreadyImportedSpecification(IHistoryService historyService, public SpecificationPriority Priority => SpecificationPriority.Database; - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (downloadClientItem == null) { _logger.Debug("No download client information is available, skipping"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var movie = localMovie.Movie; @@ -35,7 +35,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (!movie.HasFile) { _logger.Debug("Skipping already imported check for movie without file"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var movieImportedHistory = _historyService.GetByMovieId(movie.Id, null); @@ -48,7 +48,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (lastImported == null) { _logger.Trace("Movie file has not been imported"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } if (lastGrabbed != null) @@ -57,23 +57,23 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (lastGrabbed.Date.After(lastImported.Date)) { _logger.Trace("Movie file was grabbed again after importing"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } // If the release was imported after the last grab reject it if (lastImported.Date.After(lastGrabbed.Date)) { _logger.Debug("Movie file previously imported at {0}", lastImported.Date); - return Decision.Reject("Movie file already imported at {0}", lastImported.Date.ToLocalTime()); + return ImportSpecDecision.Reject(ImportRejectionReason.MovieAlreadyImported, "Movie file already imported at {0}", lastImported.Date.ToLocalTime()); } } else { _logger.Debug("Movie file previously imported at {0}", lastImported.Date); - return Decision.Reject("Movie file already imported at {0}", lastImported.Date.ToLocalTime()); + return ImportSpecDecision.Reject(ImportRejectionReason.MovieAlreadyImported, "Movie file already imported at {0}", lastImported.Date.ToLocalTime()); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/FreeSpaceSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/FreeSpaceSpecification.cs index bdc17611f3..cc9330f6a8 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/FreeSpaceSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/FreeSpaceSpecification.cs @@ -4,7 +4,6 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -23,12 +22,12 @@ public FreeSpaceSpecification(IDiskProvider diskProvider, IConfigService configS _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (_configService.SkipFreeSpaceCheckWhenImporting) { _logger.Debug("Skipping free space check when importing"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } try @@ -36,7 +35,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (localMovie.ExistingFile) { _logger.Debug("Skipping free space check for existing movie"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var path = Directory.GetParent(localMovie.Movie.Path); @@ -45,13 +44,13 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (!freeSpace.HasValue) { _logger.Debug("Free space check returned an invalid result for: {0}", path); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } if (freeSpace < localMovie.Size + _configService.MinimumFreeSpaceWhenImporting.Megabytes()) { _logger.Warn("Not enough free space ({0}) to import: {1} ({2})", freeSpace, localMovie, localMovie.Size); - return Decision.Reject("Not enough free space"); + return ImportSpecDecision.Reject(ImportRejectionReason.MinimumFreeSpace, "Not enough free space"); } } catch (DirectoryNotFoundException ex) @@ -63,7 +62,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download _logger.Error(ex, "Unable to check free disk space while importing: {0}", localMovie.Path); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs index 0592f3b3e6..f96568378a 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/GrabbedReleaseQualitySpecification.cs @@ -1,7 +1,6 @@ using System.Linq; using NLog; using NzbDrone.Common.Extensions; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.History; using NzbDrone.Core.Parser.Model; @@ -21,11 +20,11 @@ public GrabbedReleaseQualitySpecification(Logger logger, _historyService = historyService; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (downloadClientItem == null) { - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var grabbedHistory = _historyService.FindByDownloadId(downloadClientItem.DownloadId) @@ -35,7 +34,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (grabbedHistory.Empty()) { _logger.Debug("No grabbed history for this download client item"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } foreach (var item in grabbedHistory) @@ -47,7 +46,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download } } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs index 2be157725f..743a0859e9 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/HasAudioTrackSpecification.cs @@ -1,5 +1,4 @@ using NLog; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -14,22 +13,22 @@ public HasAudioTrackSpecification(Logger logger) _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (localMovie.MediaInfo == null) { _logger.Debug("Failed to get media info from the file, make sure ffprobe is available, skipping check"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } if (localMovie.MediaInfo.AudioStreamCount == 0) { _logger.Debug("No audio tracks found in file"); - return Decision.Reject("No audio tracks detected"); + return ImportSpecDecision.Reject(ImportRejectionReason.NoAudio, "No audio tracks detected"); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesFolderSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesFolderSpecification.cs index b957486d72..666ae2c2e0 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesFolderSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesFolderSpecification.cs @@ -1,6 +1,5 @@ using System.IO; using NLog; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -15,18 +14,18 @@ public MatchesFolderSpecification(Logger logger) _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (localMovie.ExistingFile) { - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var dirInfo = new FileInfo(localMovie.Path).Directory; if (dirInfo == null) { - return Decision.Accept(); + return ImportSpecDecision.Accept(); } // TODO: Actually implement this!!!! @@ -37,7 +36,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download return Decision.Accept(); }*/ - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesGrabSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesGrabSpecification.cs index 0cabb7c3e2..c116a2feba 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesGrabSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/MatchesGrabSpecification.cs @@ -1,7 +1,6 @@ using System.Linq; using NLog; using NzbDrone.Common.Extensions; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -16,28 +15,28 @@ public MatchesGrabSpecification(Logger logger) _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (localMovie.ExistingFile) { - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var releaseInfo = localMovie.Release; if (releaseInfo == null || releaseInfo.MovieIds.Empty()) { - return Decision.Accept(); + return ImportSpecDecision.Accept(); } if (releaseInfo.MovieIds.All(o => o != localMovie.Movie.Id)) { _logger.Debug("Unexpected movie(s) in file: {0}", localMovie.Movie.ToString()); - return Decision.Reject("Movie {0} was not found in the grabbed release: {1}", localMovie.Movie.ToString(), releaseInfo.Title); + return ImportSpecDecision.Reject(ImportRejectionReason.MovieNotFoundInRelease, "Movie {0} was not found in the grabbed release: {1}", localMovie.Movie.ToString(), releaseInfo.Title); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs index 1f1bc9e6c3..a6694a8bca 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs @@ -3,7 +3,6 @@ using NLog; using NzbDrone.Common.Disk; using NzbDrone.Common.Extensions; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -11,8 +10,14 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications { public class NotMultiPartSpecification : IImportDecisionEngineSpecification { - private readonly Logger _logger; + private static readonly Regex[] MovieMultiPartRegex = new[] + { + new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[a-d]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + }; + private readonly IDiskProvider _diskProvider; + private readonly Logger _logger; public NotMultiPartSpecification(IDiskProvider diskProvider, Logger logger) { @@ -20,33 +25,24 @@ public NotMultiPartSpecification(IDiskProvider diskProvider, Logger logger) _logger = logger; } - private static readonly Regex[] MovieMultiPartRegex = new Regex[] + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { - new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[a-d]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - }; - - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) - { - var regexReplace = MovieMultiPartRegex.First().Replace(localMovie.Path, ""); - if (MovieMultiPartRegex.Any(v => v.IsMatch(localMovie.Path))) { - var parentPath = localMovie.Path.GetParentPath(); - var filesInDirectory = _diskProvider.GetFiles(localMovie.Path.GetParentPath(), false); + var filesInDirectory = _diskProvider.GetFiles(localMovie.Path.GetParentPath(), false).ToList(); foreach (var regex in MovieMultiPartRegex) { - if (filesInDirectory.Where(file => regex.Replace(file, "") == regex.Replace(localMovie.Path, "")).Count() > 1) + if (filesInDirectory.Count(file => regex.Replace(file, "") == regex.Replace(localMovie.Path, "")) > 1) { _logger.Debug("Rejected Multi-Part File: {0}", localMovie.Path); - return Decision.Reject("File is suspected multi-part file, Radarr doesn't support this"); + return ImportSpecDecision.Reject(ImportRejectionReason.MultiPartMovie, "File is suspected multi-part file, Radarr doesn't support this"); } } } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotSampleSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotSampleSpecification.cs index 73c19e53b4..75d9f72cb4 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotSampleSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotSampleSpecification.cs @@ -1,5 +1,4 @@ using NLog; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -17,26 +16,26 @@ public NotSampleSpecification(IDetectSample detectSample, _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (localMovie.ExistingFile) { _logger.Debug("Existing file, skipping sample check"); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var sample = _detectSample.IsSample(localMovie.Movie.MovieMetadata, localMovie.Path); if (sample == DetectSampleResult.Sample) { - return Decision.Reject("Sample"); + return ImportSpecDecision.Reject(ImportRejectionReason.Sample, "Sample"); } else if (sample == DetectSampleResult.Indeterminate) { - return Decision.Reject("Unable to determine if file is a sample"); + return ImportSpecDecision.Reject(ImportRejectionReason.SampleIndeterminate, "Unable to determine if file is a sample"); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotUnpackingSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotUnpackingSpecification.cs index 54aff4a638..05773fac83 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotUnpackingSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotUnpackingSpecification.cs @@ -4,7 +4,6 @@ using NzbDrone.Common.Disk; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Core.Configuration; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; @@ -23,12 +22,12 @@ public NotUnpackingSpecification(IDiskProvider diskProvider, IConfigService conf _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { if (localMovie.ExistingFile) { _logger.Debug("{0} is in movie folder, skipping unpacking check", localMovie.Path); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } foreach (var workingFolder in _configService.DownloadClientWorkingFolders.Split('|')) @@ -41,13 +40,13 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (OsInfo.IsNotWindows) { _logger.Debug("{0} is still being unpacked", localMovie.Path); - return Decision.Reject("File is still being unpacked"); + return ImportSpecDecision.Reject(ImportRejectionReason.Unpacking, "File is still being unpacked"); } if (_diskProvider.FileGetLastWrite(localMovie.Path) > DateTime.UtcNow.AddMinutes(-5)) { _logger.Debug("{0} appears to be unpacking still", localMovie.Path); - return Decision.Reject("File is still being unpacked"); + return ImportSpecDecision.Reject(ImportRejectionReason.Unpacking, "File is still being unpacked"); } } @@ -55,7 +54,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download } } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UnverifiedSceneNumberingSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UnverifiedSceneNumberingSpecification.cs deleted file mode 100644 index 8ea6634a24..0000000000 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UnverifiedSceneNumberingSpecification.cs +++ /dev/null @@ -1,21 +0,0 @@ -using NLog; -using NzbDrone.Core.DecisionEngine; -using NzbDrone.Core.Download; -using NzbDrone.Core.Parser.Model; -namespace NzbDrone.Core.MediaFiles.MovieImport.Specifications -{ - public class UnverifiedSceneNumberingSpecification : IImportDecisionEngineSpecification - { - private readonly Logger _logger; - - public UnverifiedSceneNumberingSpecification(Logger logger) - { - _logger = logger; - } - - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) - { - return Decision.Accept(); - } - } -} diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UpgradeSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UpgradeSpecification.cs index fcd7ffc934..aac399bc43 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UpgradeSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/UpgradeSpecification.cs @@ -2,7 +2,6 @@ using NzbDrone.Common.Extensions; using NzbDrone.Core.Configuration; using NzbDrone.Core.CustomFormats; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Download; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.Qualities; @@ -24,7 +23,7 @@ public UpgradeSpecification(IConfigService configService, _logger = logger; } - public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) + public ImportSpecDecision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem downloadClientItem) { var downloadPropersAndRepacks = _configService.DownloadPropersAndRepacks; var qualityProfile = localMovie.Movie.QualityProfile; @@ -38,7 +37,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download { _logger.Trace("Unable to get movie file details from the DB. MovieId: {0} MovieFileId: {1}", localMovie.Movie.Id, localMovie.Movie.MovieFileId); - return Decision.Accept(); + return ImportSpecDecision.Accept(); } var qualityCompare = qualityComparer.Compare(localMovie.Quality.Quality, movieFile.Quality.Quality); @@ -46,7 +45,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download if (qualityCompare < 0) { _logger.Debug("This file isn't a quality upgrade for movie. Existing quality: {0}. New Quality {1}. Skipping {2}", movieFile.Quality.Quality, localMovie.Quality.Quality, localMovie.Path); - return Decision.Reject("Not an upgrade for existing movie file. Existing quality: {0}. New Quality {1}.", movieFile.Quality.Quality, localMovie.Quality.Quality); + return ImportSpecDecision.Reject(ImportRejectionReason.NotQualityUpgrade, "Not an upgrade for existing movie file. Existing quality: {0}. New Quality {1}.", movieFile.Quality.Quality, localMovie.Quality.Quality); } // Same quality, propers/repacks are preferred and it is not a revision update. Reject revision downgrade. @@ -56,7 +55,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download localMovie.Quality.Revision.CompareTo(movieFile.Quality.Revision) < 0) { _logger.Debug("This file isn't a quality revision upgrade for movie. Skipping {0}", localMovie.Path); - return Decision.Reject("Not a quality revision upgrade for existing movie file(s)"); + return ImportSpecDecision.Reject(ImportRejectionReason.NotRevisionUpgrade, "Not a quality revision upgrade for existing movie file(s)"); } movieFile.Movie = localMovie.Movie; @@ -73,7 +72,8 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download currentCustomFormats != null ? currentCustomFormats.ConcatToString() : "", currentFormatScore); - return Decision.Reject("Not a Custom Format upgrade for existing movie file(s). New: [{0}] ({1}) do not improve on Existing: [{2}] ({3})", + return ImportSpecDecision.Reject(ImportRejectionReason.NotCustomFormatUpgrade, + "Not a Custom Format upgrade for existing movie file(s). New: [{0}] ({1}) do not improve on Existing: [{2}] ({3})", newCustomFormats != null ? newCustomFormats.ConcatToString() : "", newFormatScore, currentCustomFormats != null ? currentCustomFormats.ConcatToString() : "", @@ -87,7 +87,7 @@ public Decision IsSatisfiedBy(LocalMovie localMovie, DownloadClientItem download currentFormatScore); } - return Decision.Accept(); + return ImportSpecDecision.Accept(); } } } diff --git a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs index 22b24cbb45..d77897a6f5 100644 --- a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs +++ b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs @@ -105,7 +105,7 @@ public static ReleaseResource ToResource(this DownloadDecision model) Rejected = model.Rejected, TmdbId = releaseInfo.TmdbId, ImdbId = releaseInfo.ImdbId, - Rejections = model.Rejections.Select(r => r.Reason).ToList(), + Rejections = model.Rejections.Select(r => r.Message).ToList(), PublishDate = releaseInfo.PublishDate, CommentUrl = releaseInfo.CommentUrl, DownloadUrl = releaseInfo.DownloadUrl, diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs index 40f877d7f8..8c1f3ba38a 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs @@ -38,7 +38,7 @@ public object ReprocessItems([FromBody] List item item.Movie = processedItem.Movie.ToResource(0); item.IndexerFlags = processedItem.IndexerFlags; - item.Rejections = processedItem.Rejections; + item.Rejections = processedItem.Rejections.Select(r => r.ToResource()); item.CustomFormats = processedItem.CustomFormats.ToResource(false); item.CustomFormatScore = processedItem.CustomFormatScore; diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs index 659fea56f1..3ec7152c34 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportReprocessResource.cs @@ -1,5 +1,4 @@ using System.Collections.Generic; -using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Languages; using NzbDrone.Core.Qualities; using Radarr.Api.V3.CustomFormats; @@ -20,6 +19,6 @@ public class ManualImportReprocessResource : RestResource public List CustomFormats { get; set; } public int CustomFormatScore { get; set; } public int IndexerFlags { get; set; } - public IEnumerable Rejections { get; set; } + public IEnumerable Rejections { get; set; } } } diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs index b895614039..deae5dad71 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs @@ -3,6 +3,7 @@ using NzbDrone.Common.Crypto; using NzbDrone.Core.DecisionEngine; using NzbDrone.Core.Languages; +using NzbDrone.Core.MediaFiles.MovieImport; using NzbDrone.Core.MediaFiles.MovieImport.Manual; using NzbDrone.Core.Qualities; using Radarr.Api.V3.CustomFormats; @@ -27,7 +28,7 @@ public class ManualImportResource : RestResource public List CustomFormats { get; set; } public int CustomFormatScore { get; set; } public int IndexerFlags { get; set; } - public IEnumerable Rejections { get; set; } + public IEnumerable Rejections { get; set; } } public static class ManualImportResourceMapper @@ -60,7 +61,7 @@ public static ManualImportResource ToResource(this ManualImportItem model) // QualityWeight DownloadId = model.DownloadId, IndexerFlags = model.IndexerFlags, - Rejections = model.Rejections + Rejections = model.Rejections.Select(r => r.ToResource()) }; } @@ -69,4 +70,27 @@ public static List ToResource(this IEnumerable Date: Mon, 3 Feb 2025 18:06:48 +0200 Subject: [PATCH 197/579] Improve message for unknown movie rejection in release searching --- src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs index e1d3f09063..dc2ce57aa9 100644 --- a/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs +++ b/src/NzbDrone.Core/DecisionEngine/DownloadDecisionMaker.cs @@ -85,7 +85,7 @@ private IEnumerable GetDecisions(List reports, bo if (remoteMovie.Movie == null) { - decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnknownMovie, "Unknown Movie")); + decision = new DownloadDecision(remoteMovie, new DownloadRejection(DownloadRejectionReason.UnknownMovie, "Unknown Movie. Unable to identify correct movie using release name.")); } else { From d888a0a2b3bac62f6511f54824d69658de69bfd8 Mon Sep 17 00:00:00 2001 From: Servarr Date: Mon, 3 Feb 2025 16:17:41 +0000 Subject: [PATCH 198/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index fab0fcfd8f..1dc5face03 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -9908,6 +9908,19 @@ ], "type": "string" }, + "ImportRejectionResource": { + "type": "object", + "properties": { + "reason": { + "type": "string", + "nullable": true + }, + "type": { + "$ref": "#/components/schemas/RejectionType" + } + }, + "additionalProperties": false + }, "IndexerBulkResource": { "type": "object", "properties": { @@ -10284,7 +10297,7 @@ "rejections": { "type": "array", "items": { - "$ref": "#/components/schemas/Rejection" + "$ref": "#/components/schemas/ImportRejectionResource" }, "nullable": true } @@ -10361,7 +10374,7 @@ "rejections": { "type": "array", "items": { - "$ref": "#/components/schemas/Rejection" + "$ref": "#/components/schemas/ImportRejectionResource" }, "nullable": true } @@ -11882,19 +11895,6 @@ }, "additionalProperties": false }, - "Rejection": { - "type": "object", - "properties": { - "reason": { - "type": "string", - "nullable": true - }, - "type": { - "$ref": "#/components/schemas/RejectionType" - } - }, - "additionalProperties": false - }, "RejectionType": { "enum": [ "permanent", From 66aae0c91cd5ac6614c6b54c8e4f9137404025b8 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 3 Feb 2025 22:57:42 +0200 Subject: [PATCH 199/579] Fixed: Reject multi-part files with P1, P2, etc. --- .../NotMultiPartSpecificationFixture.cs | 11 +++++++++++ .../Specifications/NotMultiPartSpecification.cs | 4 ++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/NotMultiPartSpecificationFixture.cs b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/NotMultiPartSpecificationFixture.cs index 7331605499..0a91afe98f 100644 --- a/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/NotMultiPartSpecificationFixture.cs +++ b/src/NzbDrone.Core.Test/MediaFiles/MovieImport/Specifications/NotMultiPartSpecificationFixture.cs @@ -54,6 +54,17 @@ public void should_be_accepted_for_legitimate_files(object[] paths) @"C:\Test\Downloaded\Bad Boys (2006) part1.mkv", @"C:\Test\Downloaded\Bad Boys (2006) part2.mkv" })] + + [TestCase(new object[] + { + @"C:\Test\Downloaded\Bad Boys (2006) pt1.mkv", + @"C:\Test\Downloaded\Bad Boys (2006) pt2.mkv" + })] + [TestCase(new object[] + { + @"C:\Test\Downloaded\Bad Boys (2006) P1.mkv", + @"C:\Test\Downloaded\Bad Boys (2006) P2.mkv" + })] [TestCase(new object[] { @"C:\Test\Downloaded\blah blah - cd 1.mvk", diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs index a6694a8bca..ead4680cc1 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Specifications/NotMultiPartSpecification.cs @@ -12,8 +12,8 @@ public class NotMultiPartSpecification : IImportDecisionEngineSpecification { private static readonly Regex[] MovieMultiPartRegex = new[] { - new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), - new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:ar)?t|dis[ck])[ _.-]*[a-d]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:(?:ar)?t)?|dis[ck])[ _.-]*[0-9]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), + new Regex(@"(?[ _.-]*(?:cd|dvd|p(?:(?:ar)?t)?|dis[ck])[ _.-]*[a-d]+)", RegexOptions.Compiled | RegexOptions.IgnoreCase), }; private readonly IDiskProvider _diskProvider; From dd900eb7395144b6d299f10fe9475d49d194664e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 6 Feb 2025 00:36:13 +0200 Subject: [PATCH 200/579] Building docs on ARM Co-authored-by: Mark McDowall (cherry picked from commit 147e732c9ca7a4c289d4f6386f1277650e11f15b) --- docs.sh | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docs.sh b/docs.sh index f26c1bcdca..d8d02669a1 100644 --- a/docs.sh +++ b/docs.sh @@ -1,13 +1,18 @@ +#!/bin/bash +set -e + +FRAMEWORK="net6.0" PLATFORM=$1 +ARCHITECTURE="${2:-x64}" if [ "$PLATFORM" = "Windows" ]; then - RUNTIME="win-x64" + RUNTIME="win-$ARCHITECTURE" elif [ "$PLATFORM" = "Linux" ]; then - RUNTIME="linux-x64" + RUNTIME="linux-$ARCHITECTURE" elif [ "$PLATFORM" = "Mac" ]; then - RUNTIME="osx-x64" + RUNTIME="osx-$ARCHITECTURE" else - echo "Platform must be provided as first arguement: Windows, Linux or Mac" + echo "Platform must be provided as first argument: Windows, Linux or Mac" exit 1 fi @@ -35,7 +40,7 @@ dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p dotnet new tool-manifest dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli -dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/net6.0/$RUNTIME/$application" v3 & +dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v3 & sleep 45 From b3dd571a926576678c397a7e87937b714ae2c257 Mon Sep 17 00:00:00 2001 From: Robin Dadswell <19610103+RobinDadswell@users.noreply.github.com> Date: Wed, 5 Feb 2025 15:03:32 +0000 Subject: [PATCH 201/579] New: Migrated StevenLu URL to new URL --- .../241_stevenlu_update_urlFixture.cs | 55 +++++++++++++++++++ .../Migration/241_stevenlu_update_url.cs | 55 +++++++++++++++++++ 2 files changed, 110 insertions(+) create mode 100644 src/NzbDrone.Core.Test/Datastore/Migration/241_stevenlu_update_urlFixture.cs create mode 100644 src/NzbDrone.Core/Datastore/Migration/241_stevenlu_update_url.cs diff --git a/src/NzbDrone.Core.Test/Datastore/Migration/241_stevenlu_update_urlFixture.cs b/src/NzbDrone.Core.Test/Datastore/Migration/241_stevenlu_update_urlFixture.cs new file mode 100644 index 0000000000..56365803df --- /dev/null +++ b/src/NzbDrone.Core.Test/Datastore/Migration/241_stevenlu_update_urlFixture.cs @@ -0,0 +1,55 @@ +using System.Linq; +using FluentAssertions; +using NUnit.Framework; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore; +using NzbDrone.Core.Datastore.Migration; +using NzbDrone.Core.Test.Framework; + +namespace NzbDrone.Core.Test.Datastore.Migration +{ + [TestFixture] + public class stevenlu_update_urlFixture : MigrationTest + { + [Test] + public void should_update_stevenlu_url() + { + var db = WithMigrationTestDb(c => + { + c.Insert.IntoTable("ImportLists").Row(new + { + Enabled = true, + EnableAuto = true, + Name = "StevenLu List", + QualityProfileId = 1, + MinimumAvailability = 1, + RootFolderPath = "/movies", + Monitor = 0, + SearchOnAdd = true, + Tags = "[]", + Implementation = "StevenLuImport", + ConfigContract = "StevenLuSettings", + Settings = new StevenLuSettings241 + { + Link = "https://s3.amazonaws.com/popular-movies/movies.json" + }.ToJson() + }); + }); + + var items = db.Query("SELECT \"Id\", \"Settings\" FROM \"ImportLists\""); + + items.Should().HaveCount(1); + items.First().Settings.Link.Should().Be("https://popular-movies-data.stevenlu.com/movies.json"); + } + } + + public class ImportListDefinition241 : ModelBase + { + public StevenLuSettings241 Settings { get; set; } + } + + public class StevenLuSettings241 + { + public string Link { get; set; } + } +} diff --git a/src/NzbDrone.Core/Datastore/Migration/241_stevenlu_update_url.cs b/src/NzbDrone.Core/Datastore/Migration/241_stevenlu_update_url.cs new file mode 100644 index 0000000000..2a003fcc51 --- /dev/null +++ b/src/NzbDrone.Core/Datastore/Migration/241_stevenlu_update_url.cs @@ -0,0 +1,55 @@ +using System.Collections.Generic; +using System.Data; +using Dapper; +using FluentMigrator; +using Newtonsoft.Json.Linq; +using NzbDrone.Common.Extensions; +using NzbDrone.Common.Serializer; +using NzbDrone.Core.Datastore.Migration.Framework; + +namespace NzbDrone.Core.Datastore.Migration +{ + [Migration(241)] + public class stevenlu_update_url : NzbDroneMigrationBase + { + protected override void MainDbUpgrade() + { + Execute.WithConnection(FixStevenLuListsLink); + } + + private void FixStevenLuListsLink(IDbConnection conn, IDbTransaction tran) + { + var updated = new List(); + + using (var getStevenLuListCmd = conn.CreateCommand()) + { + getStevenLuListCmd.Transaction = tran; + getStevenLuListCmd.CommandText = "SELECT \"Id\", \"Settings\" FROM \"ImportLists\" WHERE \"ConfigContract\" = 'StevenLuSettings'"; + + using var reader = getStevenLuListCmd.ExecuteReader(); + + while (reader.Read()) + { + var id = reader.GetInt32(0); + var settings = Json.Deserialize(reader.GetString(1)); + + var link = settings.Value("link"); + + if (link.IsNotNullOrWhiteSpace() && link.StartsWith("https://s3.amazonaws.com/popular-movies")) + { + settings["link"] = "https://popular-movies-data.stevenlu.com/movies.json"; + } + + updated.Add(new + { + Id = id, + Settings = settings.ToJson() + }); + } + } + + var updateSql = "UPDATE \"ImportLists\" SET \"Settings\" = @Settings WHERE \"Id\" = @Id"; + conn.Execute(updateSql, updated, transaction: tran); + } + } +} From c165118d4d38b1543a75a8f8e72e87340a289d24 Mon Sep 17 00:00:00 2001 From: Connor Gallopo Date: Fri, 7 Feb 2025 14:41:42 -0500 Subject: [PATCH 202/579] Update README.md Update Copyright Date --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ebde395ea0..1131ce4e50 100644 --- a/README.md +++ b/README.md @@ -87,4 +87,4 @@ This project is also supported by DigitalOcean ### License * [GNU GPL v3](http://www.gnu.org/licenses/gpl.html) -* Copyright 2010-2024 +* Copyright 2010-2025 From f8da7aae033d8f94229c38d9d354ddcee60c7cea Mon Sep 17 00:00:00 2001 From: Weblate Date: Wed, 5 Feb 2025 15:33:27 +0000 Subject: [PATCH 203/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Gallyam Biktashev Co-authored-by: Gionatan Spedicato Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: fordas Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ca.json | 3 +- src/NzbDrone.Core/Localization/Core/cs.json | 3 +- src/NzbDrone.Core/Localization/Core/de.json | 32 ++++++++++++++++++- src/NzbDrone.Core/Localization/Core/es.json | 3 +- src/NzbDrone.Core/Localization/Core/it.json | 7 +++- .../Localization/Core/pt_BR.json | 3 +- src/NzbDrone.Core/Localization/Core/ru.json | 3 +- src/NzbDrone.Core/Localization/Core/tr.json | 3 +- 8 files changed, 49 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 4219922eed..e49507e95b 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1425,5 +1425,6 @@ "DownloadClientFloodSettingsAddPaused": "Afegeix pausats", "NotificationsAppriseSettingsTags": "Etiquetes d'Apprise", "NotificationsSettingsWebhookHeaders": "Capçaleres", - "PreviouslyInstalled": "Instal·lat anteriorment" + "PreviouslyInstalled": "Instal·lat anteriorment", + "DownloadClientSettingsAddPaused": "Afegeix pausats" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 45e5db304e..1a4bd02cb0 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1294,5 +1294,6 @@ "CountVotes": "{votes} hlasy", "CustomFormatsSpecificationRegularExpression": "Běžný výraz", "AutoTaggingSpecificationGenre": "Žánr(y)", - "DeleteSelected": "Smazat vybrané" + "DeleteSelected": "Smazat vybrané", + "IndexerDownloadClientHealthCheckMessage": "Indexery s neplatnými klienty pro stahování: {indexerNames}." } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 2814e6e225..69ae60c404 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1863,5 +1863,35 @@ "MetadataSettingsMovieMetadataLanguage": "Sprache der Film-Metadaten", "MetadataSettingsMovieMetadataNfo": "Verwende movie.nfo", "MetadataSettingsMovieMetadataUrl": "URL der Film-Metadaten", - "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Sammlungsname in .nfo einbeziehen" + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Sammlungsname in .nfo einbeziehen", + "InteractiveSearchResultsFailedErrorMessage": "Die Suche ist fehlgeschlagen, da {message}. Versuche die Filminfos zu aktualisieren und überprüfe, ob die notwendigen Informationen vorhanden sind, bevor du erneut suchst.", + "WhySearchesCouldBeFailing": "Klicke hier, um herauszufinden, warum die Suchen fehlschlagen könnten", + "PopularityIndex": "Aktueller Beliebtheits-Index", + "SearchMoviesConfirmationMessageText": "Bist du sicher, dass du eine Suche für {count} Film(e) durchführen möchtest?", + "InteractiveImportNoMovie": "Film muss für jede ausgewählte Datei gewählt werden", + "InteractiveImportNoLanguage": "Die Sprache muss für jede ausgewählte Datei gewählt werden", + "InteractiveSearchModalHeaderTitle": "Interaktive Suche – {title}", + "MovieImportedTooltip": "Film erfolgreich heruntergeladen und vom Download-Client abgeholt", + "FailedToUpdateSettings": "Fehler beim Aktualisieren der Einstellungen", + "ShowRottenTomatoesRating": "Tomato-Bewertung anzeigen", + "MatchedToMovie": "Zu Film zugeordnet", + "ShowTmdbRating": "TMDb-Bewertung anzeigen", + "Popularity": "Beliebtheit", + "MovieFileMissingTooltip": "Filmdatei fehlt", + "MovieFolderImportedTooltip": "Film aus dem Filmordner importiert", + "MovieImported": "Film importiert", + "NoExtraFilesToManage": "Keine zusätzlichen Dateien zu verwalten.", + "NotificationsPlexValidationNoMovieLibraryFound": "Mindestens eine Filmsammlung ist erforderlich", + "MovieFileRenamedTooltip": "Filmdatei umbenannt", + "ManageFiles": "Dateien verwalten", + "ShowImdbRating": "IMDb-Bewertung anzeigen", + "ShowImdbRatingHelpText": "IMDb-Bewertung unter dem Poster anzeigen", + "ShowTmdbRatingHelpText": "TMDb-Bewertung unter dem Poster anzeigen", + "MovieFileRenamed": "Filmdatei umbenannt", + "NoMovieFilesToManage": "Keine Filmdateien zu verwalten.", + "NotificationsGotifySettingIncludeMoviePosterHelpText": "Film-Poster in Nachricht einbeziehen", + "NotificationsGotifySettingIncludeMoviePoster": "Film-Poster einbeziehen", + "OverrideGrabNoMovie": "Ein Film muss ausgewählt werden", + "ShowRottenTomatoesRatingHelpText": "Tomato-Bewertung unter dem Poster anzeigen", + "NotificationsTagsMovieHelpText": "Benachrichtigungen nur für Filme mit mindestens einem übereinstimmenden Tag senden" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 00244d558c..70957b62c8 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1890,5 +1890,6 @@ "AutoTaggingSpecificationMaximumRuntime": "Tiempo de ejecución máximo", "AutoTaggingSpecificationMinimumRuntime": "Tiempo de ejecución mínimo", "CustomFormatsSpecificationQualityModifier": "Modificador de calidad", - "Mixed": "Mezclado" + "Mixed": "Mezclado", + "MediaInfoFootNote2": "MediaInfo AudioLanguages excluye el inglés si es el único idioma. Usa MediaInfo AudioLanguagesAll para incluir solo el inglés" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index c9a93a6b75..bb1cb5473b 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1489,5 +1489,10 @@ "CustomFormatsSpecificationMinimumYear": "Anno Minimo", "CustomFormatsSpecificationResolution": "Risoluzione", "CustomFormatsSpecificationSource": "Fonte", - "Mixed": "Fissato" + "Mixed": "Fissato", + "AutoRedownloadFailedFromInteractiveSearchHelpText": "Cerca automaticamente e tenta di scaricare una versione diversa quando il rilascio non riuscito è stato acquisito dalla ricerca interattiva", + "AutoTaggingLoadError": "Impossibile caricare auto tagging", + "AnnouncedMovieAvailabilityDescription": "I film sono considerati disponibili non appena vengono aggiunti a {appName}.", + "AutoRedownloadFailedFromInteractiveSearch": "Riesecuzione del download non riuscita dalla ricerca interattiva", + "AutoTaggingRequiredHelpText": "Questa condizione {implementationName} deve corrispondere perché si applichi la regola di auto tagging. Altrimenti è sufficiente una singola corrispondenza {implementationName}." } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index d9cfc9472d..0f8dacde02 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1893,5 +1893,6 @@ "ReleasePush": "Impulsionar Lançamento", "ReleaseSource": "Fonte do Lançamento", "UserInvokedSearch": "Pesquisa Invocada pelo Usuário", - "Mixed": "Misturado" + "Mixed": "Misturado", + "MediaInfoFootNote2": "O MediaInfo Audiolanguages exclui o inglês se for o único idioma. Use MediaInfo AudiolanguagesAll para incluir apenas o inglês" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 67978b8684..13439f179c 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1809,5 +1809,6 @@ "CustomFormatsSpecificationResolution": "Разрешение", "CustomFormatsSpecificationSource": "Исходный код", "CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного", - "Mixed": "Смешанный" + "Mixed": "Смешанный", + "MediaInfoFootNote2": "MediaInfo AudioLanguages не добавляет английский язык, если это единственный доступный язык. Используйте MediaInfo AudioLanguagesAll для добавления английского языка в таких случаях" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 70086b8049..2b282830c1 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1893,5 +1893,6 @@ "ReleaseSource": "Yayın Kaynağı", "UserInvokedSearch": "Kullanıcı Tarafından Çağrılan Arama", "ReleasePush": "Yayın İtimi", - "Mixed": "Karışık" + "Mixed": "Karışık", + "MediaInfoFootNote2": "MediaInfo AudioLanguages, tek dil İngilizce ise hariç tutar. MediaInfo AudioLanguagesAll'ı yalnızca İngilizce'yi dahil etmek için kullanın" } From 884abc03688044d021e5a5a6cefc78bf16695b82 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 9 Feb 2025 17:50:50 +0200 Subject: [PATCH 204/579] Bump version to 5.19.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index c62cbab8cf..062e5e075e 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.19.0' + majorVersion: '5.19.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From d375b5ffbe03f6939372f59b4e69ae9dcf5c5940 Mon Sep 17 00:00:00 2001 From: epmt7w3ugk Date: Tue, 7 Jan 2025 14:47:13 +0100 Subject: [PATCH 205/579] Fixed: Parse GER/DE releases as German language Fix parsing for German language to correctly detect "GER" and "DE" Update test for GER/DE language parsing. --- .../ParserTests/LanguageParserFixture.cs | 6 ++++++ src/NzbDrone.Core/Parser/LanguageParser.cs | 8 +++++++- src/NzbDrone.Core/Parser/Parser.cs | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index ec3c2ce890..c7bb13a641 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -87,7 +87,13 @@ public void should_parse_language_spanish(string postTitle) } [TestCase("Movie.Title.1994.German.1080p.XviD-LOL")] + [TestCase("Movie.Title.2016.GERMAN.DUBBED.WS.WEBRiP.XviD.REPACK-TVP")] + [TestCase("Movie Title 2016 - Kampfhaehne - mkv - by Videomann")] [TestCase("Movie.Title.2016.Ger.Dub.AAC.1080p.WebDL.x264-TKP21")] + [TestCase("Movie.Title.2016.Ger.AAC.1080p.WebDL.x264-TKP21")] + [TestCase("Movie.Title.2016.Hun/Ger/Ita.AAC.1080p.WebDL.x264-TKP21")] + [TestCase("Movie.Title.2016.1080p.10Bit.HEVC.WEBRip.HIN-ENG-GER.DD5.1.H.265")] + [TestCase("Movie.Title.2016.HU-IT-DE.AAC.1080p.WebDL.x264")] public void should_parse_language_german(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index f710e9b15a..fd4ebe9ca3 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -16,7 +16,7 @@ public static class LanguageParser private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(LanguageParser)); private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_|^)(?\b(?:ita|italian)\b)| - (?german\b|videomann|ger[. ]dub)| + (?german\b|videomann|ger[. ]dub|\bger\b)| (?flemish)| (?bgaudio)| (?rodubbed)| @@ -44,6 +44,7 @@ public static class LanguageParser (?\bPL\b)| (?\bBG\b)| (?\bSK\b)| + (?\bDE\b)| (?\b(? ParseLanguages(string title) { languages.Add(Language.Spanish); } + + if (match.Groups["german"].Captures.Any()) + { + languages.Add(Language.German); + } } var matches = LanguageRegex.Matches(title); diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index e943feb6bb..d77f85c087 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -142,7 +142,7 @@ public static class Parser private static readonly Regex CleanQualityBracketsRegex = new Regex(@"\[[a-z0-9 ._-]+\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", + private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex InvalidReleaseGroupRegex = new Regex(@"^([se]\d+|[0-9a-f]{8})$", RegexOptions.IgnoreCase | RegexOptions.Compiled); From a3b1512552a8a5bc0c0d399d961ccbf0dba97749 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 13 Feb 2025 17:31:39 +0200 Subject: [PATCH 206/579] Fixed: Parsing some titles with FRE as French and ITA as Italian --- src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs | 4 ++++ src/NzbDrone.Core/Parser/Parser.cs | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index c7bb13a641..059542f99a 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -52,6 +52,8 @@ public void should_parse_subtitle_language_english(string fileName) [TestCase("Movie Title : Other Title 2010 x264.720p.Blu-ray Rip HD.VOSTFR.VFF. ONLY")] [TestCase("Movie Title 2019 HEVC.2160p.Blu-ray 4K.VOSTFR.VFF. JATO")] [TestCase("Movie.Title.1956.MULTi.VF.Bluray.1080p.REMUX.AC3.x264")] + [TestCase("Movie.Title.2016.ENG-ITA-FRE.AAC.1080p.WebDL.x264")] + [TestCase("Movie Title 2016 (BDrip 1080p ENG-ITA-FRE) Multisub x264")] public void should_parse_language_french(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); @@ -102,6 +104,8 @@ public void should_parse_language_german(string postTitle) } [TestCase("Movie.Title.1994.Italian.1080p.XviD-LOL")] + [TestCase("Movie.Title.2016.ENG-FRE-ITA.AAC.1080p.WebDL.x264")] + [TestCase("Movie Title 2016 (BDrip 1080p ENG-FRE-ITA) Multisub x264")] public void should_parse_language_italian(string postTitle) { var result = Parser.Parser.ParseMovieTitle(postTitle, true); diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index d77f85c087..3badfc6977 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -142,7 +142,7 @@ public static class Parser private static readonly Regex CleanQualityBracketsRegex = new Regex(@"\[[a-z0-9 ._-]+\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", + private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex InvalidReleaseGroupRegex = new Regex(@"^([se]\d+|[0-9a-f]{8})$", RegexOptions.IgnoreCase | RegexOptions.Compiled); From 8e10eecface61ce227864b2bb507748a73274300 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 15 Feb 2025 13:22:04 +0200 Subject: [PATCH 207/579] Fixed: Close Metadata settings modal on saving --- .../Metadata/Metadata/EditMetadataModalContent.tsx | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx index 997a4c39cc..78f2d40043 100644 --- a/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx +++ b/frontend/src/Settings/Metadata/Metadata/EditMetadataModalContent.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useMemo } from 'react'; +import React, { useCallback, useEffect, useMemo } from 'react'; import { useDispatch, useSelector } from 'react-redux'; import AppState from 'App/State/AppState'; import Alert from 'Components/Alert'; @@ -13,6 +13,7 @@ import ModalBody from 'Components/Modal/ModalBody'; import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; +import usePrevious from 'Helpers/Hooks/usePrevious'; import { inputTypes } from 'Helpers/Props'; import { saveMetadata, @@ -41,6 +42,8 @@ function EditMetadataModalContent({ (state: AppState) => state.settings.metadata ); + const wasSaving = usePrevious(isSaving); + const { settings, ...otherSettings } = useMemo(() => { const item = items.find((item) => item.id === id)!; @@ -69,6 +72,12 @@ function EditMetadataModalContent({ dispatch(saveMetadata({ id })); }, [id, dispatch]); + useEffect(() => { + if (wasSaving && !isSaving && !saveError) { + onModalClose(); + } + }, [isSaving, wasSaving, saveError, onModalClose]); + return ( From 3fbccc6af3369db96efc95b9399ed22885c7ddde Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Feb 2025 12:19:04 +0200 Subject: [PATCH 208/579] Bump version to 5.19.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 062e5e075e..869edf1592 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.19.1' + majorVersion: '5.19.2' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 525ed6568797ce8eb9821957c67b1d90eb8a6a7e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Feb 2025 11:50:48 +0200 Subject: [PATCH 209/579] Fix download links for FileList when passkey contains spaces --- src/NzbDrone.Core/Indexers/FileList/FileListParser.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs b/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs index 1b4bbbae7c..57a651cbec 100644 --- a/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs +++ b/src/NzbDrone.Core/Indexers/FileList/FileListParser.cs @@ -85,7 +85,7 @@ private string GetDownloadUrl(string torrentId) var url = new HttpUri(_settings.BaseUrl) .CombinePath("/download.php") .AddQueryParam("id", torrentId) - .AddQueryParam("passkey", _settings.Passkey); + .AddQueryParam("passkey", _settings.Passkey.Trim()); return url.FullUri; } From bb8a0dda631cd1b084b7cb165457a6224608935e Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 16 Feb 2025 20:58:04 +0200 Subject: [PATCH 210/579] Fixed: Processing existing movie files via Manage Files --- frontend/src/Movie/Details/MovieDetails.js | 10 ++-- .../MovieImport/Manual/ManualImportItem.cs | 3 +- .../MovieImport/Manual/ManualImportService.cs | 54 +++++++++++++++++++ .../ManualImport/ManualImportController.cs | 5 ++ .../ManualImport/ManualImportResource.cs | 4 +- 5 files changed, 71 insertions(+), 5 deletions(-) diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 4ba7dda043..d03f7e9c8b 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -21,7 +21,7 @@ import TmdbRating from 'Components/TmdbRating'; import Popover from 'Components/Tooltip/Popover'; import Tooltip from 'Components/Tooltip/Tooltip'; import TraktRating from 'Components/TraktRating'; -import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props'; +import { icons, kinds, sizes, sortDirections, tooltipPositions } from 'Helpers/Props'; import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; @@ -753,11 +753,15 @@ class MovieDetails extends Component { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs index af6bf94d1d..f43ceafc82 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportItem.cs @@ -13,6 +13,8 @@ public class ManualImportItem public string FolderName { get; set; } public string Name { get; set; } public long Size { get; set; } + public Movie Movie { get; set; } + public int? MovieFileId { get; set; } public QualityModel Quality { get; set; } public List Languages { get; set; } public string ReleaseGroup { get; set; } @@ -21,7 +23,6 @@ public class ManualImportItem public int CustomFormatScore { get; set; } public int IndexerFlags { get; set; } public IEnumerable Rejections { get; set; } - public Movie Movie { get; set; } public ManualImportItem() { diff --git a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs index cfb96548e5..f0e5beed94 100644 --- a/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs +++ b/src/NzbDrone.Core/MediaFiles/MovieImport/Manual/ManualImportService.cs @@ -22,6 +22,7 @@ namespace NzbDrone.Core.MediaFiles.MovieImport.Manual { public interface IManualImportService { + List GetMediaFiles(int movieId); List GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles); ManualImportItem ReprocessItem(string path, string downloadId, int movieId, string releaseGroup, QualityModel quality, List languages, int indexerFlags); } @@ -37,6 +38,7 @@ public class ManualImportService : IExecute, IManualImportS private readonly IAggregationService _aggregationService; private readonly ITrackedDownloadService _trackedDownloadService; private readonly IDownloadedMovieImportService _downloadedMovieImportService; + private readonly IMediaFileService _mediaFileService; private readonly ICustomFormatCalculationService _formatCalculator; private readonly IEventAggregator _eventAggregator; private readonly Logger _logger; @@ -50,6 +52,7 @@ public ManualImportService(IDiskProvider diskProvider, IImportApprovedMovie importApprovedMovie, ITrackedDownloadService trackedDownloadService, IDownloadedMovieImportService downloadedMovieImportService, + IMediaFileService mediaFileService, ICustomFormatCalculationService formatCalculator, IEventAggregator eventAggregator, Logger logger) @@ -63,11 +66,41 @@ public ManualImportService(IDiskProvider diskProvider, _importApprovedMovie = importApprovedMovie; _trackedDownloadService = trackedDownloadService; _downloadedMovieImportService = downloadedMovieImportService; + _mediaFileService = mediaFileService; _formatCalculator = formatCalculator; _eventAggregator = eventAggregator; _logger = logger; } + public List GetMediaFiles(int movieId) + { + var movie = _movieService.GetMovie(movieId); + var directoryInfo = new DirectoryInfo(movie.Path); + var movieFiles = _mediaFileService.GetFilesByMovie(movieId); + + var items = movieFiles.Select(movieFile => MapItem(movieFile, movie, directoryInfo.Name)).ToList(); + + var mediaFiles = _diskScanService.FilterPaths(movie.Path, _diskScanService.GetVideoFiles(movie.Path)).ToList(); + var unmappedFiles = MediaFileService.FilterExistingFiles(mediaFiles, movieFiles, movie); + + items.AddRange(unmappedFiles.Select(file => + new ManualImportItem + { + Path = Path.Combine(movie.Path, file), + FolderName = directoryInfo.Name, + RelativePath = movie.Path.GetRelativePath(file), + Name = Path.GetFileNameWithoutExtension(file), + Movie = movie, + ReleaseGroup = string.Empty, + Quality = new QualityModel(Quality.Unknown), + Languages = new List { Language.Unknown }, + Size = _diskProvider.GetFileSize(file), + Rejections = Enumerable.Empty() + })); + + return items; + } + public List GetMediaFiles(string path, string downloadId, int? movieId, bool filterExistingFiles) { if (downloadId.IsNotNullOrWhiteSpace()) @@ -348,6 +381,27 @@ private ManualImportItem MapItem(ImportDecision decision, string rootFolder, str return item; } + private ManualImportItem MapItem(MovieFile movieFile, Movie movie, string folderName) + { + var item = new ManualImportItem(); + + item.Path = Path.Combine(movie.Path, movieFile.RelativePath); + item.FolderName = folderName; + item.RelativePath = movieFile.RelativePath; + item.Name = Path.GetFileNameWithoutExtension(movieFile.Path); + item.Movie = movie; + item.ReleaseGroup = movieFile.ReleaseGroup; + item.Quality = movieFile.Quality; + item.Languages = movieFile.Languages; + item.IndexerFlags = (int)movieFile.IndexerFlags; + item.Size = _diskProvider.GetFileSize(item.Path); + item.Rejections = Enumerable.Empty(); + item.MovieFileId = movieFile.Id; + item.CustomFormats = _formatCalculator.ParseCustomFormat(movieFile, movie); + + return item; + } + public void Execute(ManualImportCommand message) { _logger.ProgressTrace("Manually importing {0} files using mode {1}", message.Files.Count, message.ImportMode); diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs index 8c1f3ba38a..4df77e9b8a 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportController.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportController.cs @@ -25,6 +25,11 @@ public ManualImportController(IManualImportService manualImportService) [Produces("application/json")] public List GetMediaFiles(string folder, string downloadId, int? movieId, bool filterExistingFiles = true) { + if (movieId.HasValue) + { + return _manualImportService.GetMediaFiles(movieId.Value).ToResource().Select(AddQualityWeight).ToList(); + } + return _manualImportService.GetMediaFiles(folder, downloadId, movieId, filterExistingFiles).ToResource().Select(AddQualityWeight).ToList(); } diff --git a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs index deae5dad71..d947477148 100644 --- a/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs +++ b/src/Radarr.Api.V3/ManualImport/ManualImportResource.cs @@ -20,9 +20,10 @@ public class ManualImportResource : RestResource public string Name { get; set; } public long Size { get; set; } public MovieResource Movie { get; set; } + public int? MovieFileId { get; set; } + public string ReleaseGroup { get; set; } public QualityModel Quality { get; set; } public List Languages { get; set; } - public string ReleaseGroup { get; set; } public int QualityWeight { get; set; } public string DownloadId { get; set; } public List CustomFormats { get; set; } @@ -52,6 +53,7 @@ public static ManualImportResource ToResource(this ManualImportItem model) Name = model.Name, Size = model.Size, Movie = model.Movie.ToResource(0), + MovieFileId = model.MovieFileId, ReleaseGroup = model.ReleaseGroup, Quality = model.Quality, Languages = model.Languages, From 6e80113987bb981902d22ed187c9bece66d7b60a Mon Sep 17 00:00:00 2001 From: Servarr Date: Sun, 16 Feb 2025 19:42:39 +0000 Subject: [PATCH 211/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 1dc5face03..1633152c23 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -10334,6 +10334,15 @@ "movie": { "$ref": "#/components/schemas/MovieResource" }, + "movieFileId": { + "type": "integer", + "format": "int32", + "nullable": true + }, + "releaseGroup": { + "type": "string", + "nullable": true + }, "quality": { "$ref": "#/components/schemas/QualityModel" }, @@ -10344,10 +10353,6 @@ }, "nullable": true }, - "releaseGroup": { - "type": "string", - "nullable": true - }, "qualityWeight": { "type": "integer", "format": "int32" From 7189d7b15c0dec923310cbf5329ac705af5e5b1f Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 15 Feb 2025 11:37:36 +0000 Subject: [PATCH 212/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: haru4a Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/fi.json | 7 ++++--- src/NzbDrone.Core/Localization/Core/ru.json | 3 ++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index cf17435a00..95b351ce39 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -322,7 +322,7 @@ "MovieTitleToExcludeHelpText": "Ohitettavan elokuvan nimi (voi olla miktä tahansa merkityksellistä).", "MovieYear": "Elokuvan vuosi", "TestAllClients": "Koesta latauspalvelut", - "TestAllIndexers": "Tietolähteiden testaus", + "TestAllIndexers": "Koesta pavelut", "TestAllLists": "Koesta listat", "AddRemotePathMapping": "Lisää etäsijainnin kohdistus", "Apply": "Käytä", @@ -1727,7 +1727,7 @@ "UrlBaseHelpText": "Käänteisen välityspalvelimen tukea varten. Oletusarvo on tyhjä.", "IndexerSettingsMultiLanguageRelease": "Useat kielet", "IndexerSettingsSeedRatio": "Jakosuhde", - "IndexerSettingsSeedRatioHelpText": "Suhde, joka torrentin tulee saavuttaa ennen sen pysäytystä. Käytä latauspalvelun oletusta jättämällä tyhjäksi. Suhteen tulisi olla ainakin 1.0 ja noudattaa tietolähteen sääntöjä.", + "IndexerSettingsSeedRatioHelpText": "Suhde, joka torrentin tulee saavuttaa ennen sen pysäytystä. Käytä latauspalvelun oletusta jättämällä tyhjäksi. Suhteen tulisi olla ainakin 1.0 ja noudattaa hakupalvelun sääntöjä.", "IndexerSettingsSeedTime": "Jakoaika", "IndexerSettingsSeedTimeHelpText": "Aika, joka torrentia tulee jakaa ennen sen pysäytystä. Käytä latauspalvelun oletusta jättämällä tyhjäksi.", "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Vaihtoehtoinen sijainti, johon valmistuneet lataukset siirretään. Käytä Delugen oletusta jättämällä tyhjäksi.", @@ -1893,5 +1893,6 @@ "ReleaseSource": "Julkaisulähde", "UserInvokedSearch": "Käyttäjä herätti haun", "ReleasePush": "Julkaisun työntö", - "Mixed": "Sekoitettu" + "Mixed": "Sekoitettu", + "MediaInfoFootNote2": "MediaInfo AudioLanguages ei huomioi englantia sen ollessa ainoa kieli. MediaInfo AudioLanguagesAll sisällyttää vain englanninkielen sisältävät kohteet." } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 13439f179c..06e51fef1b 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1810,5 +1810,6 @@ "CustomFormatsSpecificationSource": "Исходный код", "CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного", "Mixed": "Смешанный", - "MediaInfoFootNote2": "MediaInfo AudioLanguages не добавляет английский язык, если это единственный доступный язык. Используйте MediaInfo AudioLanguagesAll для добавления английского языка в таких случаях" + "MediaInfoFootNote2": "MediaInfo AudioLanguages не добавляет английский язык, если это единственный доступный язык. Используйте MediaInfo AudioLanguagesAll для добавления английского языка в таких случаях", + "AutoTaggingSpecificationMinimumRuntime": "Минимальное время выполнения" } From 36d4e9e6cdcf2de58270dd1d8db174ed492af609 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 18 Feb 2025 03:45:26 +0200 Subject: [PATCH 213/579] New: Movie Requested filter for interactive search --- frontend/src/Store/Actions/releaseActions.js | 6 ++++++ src/NzbDrone.Core/Localization/Core/en.json | 1 + src/NzbDrone.Core/Parser/Model/RemoteMovie.cs | 1 + src/NzbDrone.Core/Parser/ParsingService.cs | 5 +++++ src/Radarr.Api.V3/Indexers/ReleaseController.cs | 1 + src/Radarr.Api.V3/Indexers/ReleaseResource.cs | 2 ++ 6 files changed, 16 insertions(+) diff --git a/frontend/src/Store/Actions/releaseActions.js b/frontend/src/Store/Actions/releaseActions.js index 6c74752b7d..02a69d778d 100644 --- a/frontend/src/Store/Actions/releaseActions.js +++ b/frontend/src/Store/Actions/releaseActions.js @@ -210,6 +210,12 @@ export const defaultState = { name: 'rejectionCount', label: () => translate('RejectionCount'), type: filterBuilderTypes.NUMBER + }, + { + name: 'movieRequested', + label: () => translate('MovieRequested'), + type: filterBuilderTypes.EXACT, + valueType: filterBuilderValueTypes.BOOL } ], selectedFilterKey: 'all' diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index f8b4309437..becd8996d3 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -1045,6 +1045,7 @@ "MovieMissingFromDisk": "Movie missing from disk", "MovieNaming": "Movie Naming", "MovieOnly": "Movie Only", + "MovieRequested": "Movie Requested", "MovieSearchResultsLoadError": "Unable to load results for this movie search. Try again later", "MovieTitle": "Movie Title", "MovieTitleToExcludeHelpText": "The title of the movie to exclude (can be anything meaningful)", diff --git a/src/NzbDrone.Core/Parser/Model/RemoteMovie.cs b/src/NzbDrone.Core/Parser/Model/RemoteMovie.cs index d969ab14dc..f33d31d9bd 100644 --- a/src/NzbDrone.Core/Parser/Model/RemoteMovie.cs +++ b/src/NzbDrone.Core/Parser/Model/RemoteMovie.cs @@ -14,6 +14,7 @@ public class RemoteMovie public int CustomFormatScore { get; set; } public MovieMatchType MovieMatchType { get; set; } public Movie Movie { get; set; } + public bool MovieRequested { get; set; } public bool DownloadAllowed { get; set; } public TorrentSeedConfiguration SeedConfiguration { get; set; } public List Languages { get; set; } diff --git a/src/NzbDrone.Core/Parser/ParsingService.cs b/src/NzbDrone.Core/Parser/ParsingService.cs index 18da76b92f..cd406d50c7 100644 --- a/src/NzbDrone.Core/Parser/ParsingService.cs +++ b/src/NzbDrone.Core/Parser/ParsingService.cs @@ -116,6 +116,11 @@ public RemoteMovie Map(ParsedMovieInfo parsedMovieInfo, string imdbId, int tmdbI remoteMovie.Languages = parsedMovieInfo.Languages; + if (searchCriteria != null) + { + remoteMovie.MovieRequested = remoteMovie.Movie?.Id == searchCriteria.Movie?.Id; + } + return remoteMovie; } diff --git a/src/Radarr.Api.V3/Indexers/ReleaseController.cs b/src/Radarr.Api.V3/Indexers/ReleaseController.cs index 3ef26ae4f5..3130b2d4f0 100644 --- a/src/Radarr.Api.V3/Indexers/ReleaseController.cs +++ b/src/Radarr.Api.V3/Indexers/ReleaseController.cs @@ -85,6 +85,7 @@ public async Task DownloadRelease([FromBody] ReleaseResource release) { Release = remoteMovie.Release, ParsedMovieInfo = remoteMovie.ParsedMovieInfo.JsonClone(), + MovieRequested = remoteMovie.MovieRequested, DownloadAllowed = remoteMovie.DownloadAllowed, SeedConfiguration = remoteMovie.SeedConfiguration, CustomFormats = remoteMovie.CustomFormats, diff --git a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs index d77897a6f5..f6b2219f0f 100644 --- a/src/Radarr.Api.V3/Indexers/ReleaseResource.cs +++ b/src/Radarr.Api.V3/Indexers/ReleaseResource.cs @@ -44,6 +44,7 @@ public class ReleaseResource : RestResource public string CommentUrl { get; set; } public string DownloadUrl { get; set; } public string InfoUrl { get; set; } + public bool MovieRequested { get; set; } public bool DownloadAllowed { get; set; } public int ReleaseWeight { get; set; } public string Edition { get; set; } @@ -110,6 +111,7 @@ public static ReleaseResource ToResource(this DownloadDecision model) CommentUrl = releaseInfo.CommentUrl, DownloadUrl = releaseInfo.DownloadUrl, InfoUrl = releaseInfo.InfoUrl, + MovieRequested = remoteMovie.MovieRequested, DownloadAllowed = remoteMovie.DownloadAllowed, Edition = parsedMovieInfo.Edition, From 66d96e21dab2ec6824e8fe2654ceadb9a64bec10 Mon Sep 17 00:00:00 2001 From: Stevie Robinson Date: Wed, 19 Feb 2025 04:23:43 +0100 Subject: [PATCH 214/579] Fixed: Fallback to Instance Name for Discord notifications (cherry picked from commit b99e06acc0a3ecae2857d9225b35424c82c67a2b) --- .../Notifications/Discord/Discord.cs | 23 +++++++++++-------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Core/Notifications/Discord/Discord.cs b/src/NzbDrone.Core/Notifications/Discord/Discord.cs index ec2fd9c3e6..ed4409f435 100644 --- a/src/NzbDrone.Core/Notifications/Discord/Discord.cs +++ b/src/NzbDrone.Core/Notifications/Discord/Discord.cs @@ -4,6 +4,7 @@ using System.Linq; using FluentValidation.Results; using NzbDrone.Common.Extensions; +using NzbDrone.Core.Configuration; using NzbDrone.Core.Localization; using NzbDrone.Core.MediaCover; using NzbDrone.Core.MediaFiles; @@ -19,12 +20,14 @@ public class Discord : NotificationBase { private readonly IDiscordProxy _proxy; private readonly ITagRepository _tagRepository; + private readonly IConfigFileProvider _configFileProvider; private readonly ILocalizationService _localizationService; - public Discord(IDiscordProxy proxy, ITagRepository tagRepository, ILocalizationService localizationService) + public Discord(IDiscordProxy proxy, ITagRepository tagRepository, IConfigFileProvider configFileProvider, ILocalizationService localizationService) { _proxy = proxy; _tagRepository = tagRepository; + _configFileProvider = configFileProvider; _localizationService = localizationService; } @@ -37,7 +40,7 @@ public override void OnGrab(GrabMessage message) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = $"https://www.themoviedb.org/movie/{message.Movie.MovieMetadata.Value.TmdbId}", @@ -141,7 +144,7 @@ public override void OnDownload(DownloadMessage message) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = $"https://www.themoviedb.org/movie/{message.Movie.MovieMetadata.Value.TmdbId}", @@ -256,7 +259,7 @@ public override void OnMovieAdded(Movie movie) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = $"https://www.themoviedb.org/movie/{movie.MovieMetadata.Value.TmdbId}", @@ -313,7 +316,7 @@ public override void OnMovieDelete(MovieDeleteMessage deleteMessage) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = $"https://www.themoviedb.org/movie/{movie.MovieMetadata.Value.TmdbId}", @@ -354,7 +357,7 @@ public override void OnMovieFileDelete(MovieFileDeleteMessage deleteMessage) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = $"https://www.themoviedb.org/movie/{movie.MovieMetadata.Value.TmdbId}", @@ -380,7 +383,7 @@ public override void OnHealthIssue(HealthCheck.HealthCheck healthCheck) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Title = healthCheck.Source.Name, @@ -400,7 +403,7 @@ public override void OnHealthRestored(HealthCheck.HealthCheck previousCheck) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Title = "Health Issue Resolved: " + previousCheck.Source.Name, @@ -420,7 +423,7 @@ public override void OnApplicationUpdate(ApplicationUpdateMessage updateMessage) { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Title = APPLICATION_UPDATE_TITLE, @@ -454,7 +457,7 @@ public override void OnManualInteractionRequired(ManualInteractionRequiredMessag { Author = new DiscordAuthor { - Name = Settings.Author.IsNullOrWhiteSpace() ? Environment.MachineName : Settings.Author, + Name = Settings.Author.IsNullOrWhiteSpace() ? _configFileProvider.InstanceName : Settings.Author, IconUrl = "https://raw.githubusercontent.com/Radarr/Radarr/develop/Logo/256.png" }, Url = movie?.MovieMetadata.Value.TmdbId > 0 ? $"https://www.themoviedb.org/movie/{movie.MovieMetadata.Value.TmdbId}" : null, From 35c22a4ffa15f62f18661a70cd2ea172669ba3b4 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 16 Feb 2025 19:48:49 -0800 Subject: [PATCH 215/579] Fixed: Only show Additional Parameters on Trakt Popular list (cherry picked from commit b122ee967009d53432f3d1dd196132487f3999e1) --- .../Trakt/Popular/TraktPopularSettings.cs | 13 ++++++++----- .../ImportLists/Trakt/TraktSettingsBase.cs | 8 ++------ src/NzbDrone.Core/Localization/Core/en.json | 15 +++++++++++++++ 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs index 7c40539f71..8db66429fd 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularSettings.cs @@ -45,21 +45,24 @@ public TraktPopularSettings() Years = ""; } - [FieldDefinition(1, Label = "List Type", Type = FieldType.Select, SelectOptions = typeof(TraktPopularListType), HelpText = "Type of list you're seeking to import from")] + [FieldDefinition(1, Label = "ImportListsTraktSettingsListType", Type = FieldType.Select, SelectOptions = typeof(TraktPopularListType), HelpText = "ImportListsTraktSettingsListTypeHelpText")] public int TraktListType { get; set; } - [FieldDefinition(2, Label = "Rating", HelpText = "Filter movies by rating range (0-100)")] + [FieldDefinition(2, Label = "ImportListsTraktSettingsRating", HelpText = "ImportListsTraktSettingsRatingMovieHelpText")] public string Rating { get; set; } - [FieldDefinition(3, Label = "Certification", HelpText = "Filter movies by a certification (NR,G,PG,PG-13,R,NC-17), (Comma Separated)")] + [FieldDefinition(3, Label = "ImportListsTraktSettingsCertification", HelpText = "ImportListsTraktSettingsCertificationMovieHelpText")] public string Certification { get; set; } - [FieldDefinition(4, Label = "Genres", HelpText = "Filter movies by Trakt Genre Slug (Comma Separated) Only for Popular Lists")] + [FieldDefinition(4, Label = "ImportListsTraktSettingsGenres", HelpText = "ImportListsTraktSettingsGenresMovieHelpText")] public string Genres { get; set; } - [FieldDefinition(5, Label = "Years", HelpText = "Filter movies by year or year range")] + [FieldDefinition(5, Label = "ImportListsTraktSettingsYears", HelpText = "ImportListsTraktSettingsYearsMovieHelpText")] public string Years { get; set; } + [FieldDefinition(6, Label = "ImportListsTraktSettingsAdditionalParameters", HelpText = "ImportListsTraktSettingsAdditionalParametersHelpText", Advanced = true)] + public string TraktAdditionalParameters { get; set; } + public override NzbDroneValidationResult Validate() { return new NzbDroneValidationResult(Validator.Validate(this)); diff --git a/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs b/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs index c9d9bc4670..50cc2d7bd1 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/TraktSettingsBase.cs @@ -46,7 +46,6 @@ public TraktSettingsBase() } public string Link => "https://api.trakt.tv"; - public virtual string Scope => ""; [FieldDefinition(0, Label = "Access Token", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AccessToken { get; set; } @@ -60,13 +59,10 @@ public TraktSettingsBase() [FieldDefinition(0, Label = "Auth User", Type = FieldType.Textbox, Hidden = HiddenType.Hidden)] public string AuthUser { get; set; } - [FieldDefinition(5, Label = "Limit", HelpText = "Limit the number of movies to get")] + [FieldDefinition(98, Label = "ImportListsTraktSettingsLimit", HelpText = "ImportListsTraktSettingsLimitMovieHelpText")] public int Limit { get; set; } - [FieldDefinition(6, Label = "Additional Parameters", HelpText = "Additional Trakt API parameters", Advanced = true)] - public string TraktAdditionalParameters { get; set; } - - [FieldDefinition(99, Label = "Authenticate with Trakt", Type = FieldType.OAuth)] + [FieldDefinition(99, Label = "ImportListsTraktSettingsAuthenticateWithTrakt", Type = FieldType.OAuth)] public string SignIn { get; set; } public override NzbDroneValidationResult Validate() diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index becd8996d3..27eb57fd16 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -767,6 +767,21 @@ "ImportLists": "Import Lists", "ImportListsLoadError": "Unable to load Import Lists", "ImportListsSettingsSummary": "Import from another {appName} instance or Trakt lists and manage list exclusions", + "ImportListsTraktSettingsAdditionalParameters": "Additional Parameters", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Additional Trakt API parameters", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Authenticate with Trakt", + "ImportListsTraktSettingsCertification": "Certification", + "ImportListsTraktSettingsCertificationMovieHelpText": "Filter movies by a certification (NR,G,PG,PG-13,R,NC-17) (Comma Separated)", + "ImportListsTraktSettingsGenres": "Genres", + "ImportListsTraktSettingsGenresMovieHelpText": "Filter movies by Trakt Genre Slug (Comma Separated) Only for Popular Lists", + "ImportListsTraktSettingsLimit": "Limit", + "ImportListsTraktSettingsLimitMovieHelpText": "Limit the number of movies to get", + "ImportListsTraktSettingsListType": "List Type", + "ImportListsTraktSettingsListTypeHelpText": "Type of list you're seeking to import from", + "ImportListsTraktSettingsRating": "Rating", + "ImportListsTraktSettingsRatingMovieHelpText": "Filter movies by rating range (0-100)", + "ImportListsTraktSettingsYears": "Years", + "ImportListsTraktSettingsYearsMovieHelpText": "Filter movies by year or year range", "ImportMechanismHealthCheckMessage": "Enable Completed Download Handling", "ImportMovies": "Import Movies", "ImportNotForDownloads": "Do not use for importing downloads from your download client, this is only for existing organized libraries, not unsorted files.", From efa2913dbc72fc1baadd534c1eabdf479958d117 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 19 Feb 2025 15:28:05 +0200 Subject: [PATCH 216/579] Translate Trakt popular list types --- .../Trakt/Popular/TraktPopularListType.cs | 26 +++++++++---------- src/NzbDrone.Core/Localization/Core/en.json | 12 +++++++++ 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularListType.cs b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularListType.cs index 7d47014355..aea2f88252 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularListType.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/Popular/TraktPopularListType.cs @@ -1,33 +1,33 @@ -using System.Runtime.Serialization; +using NzbDrone.Core.Annotations; namespace NzbDrone.Core.ImportLists.Trakt.Popular { public enum TraktPopularListType { - [EnumMember(Value = "Trending Movies")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTrendingMovies")] Trending = 0, - [EnumMember(Value = "Popular Movies")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypePopularMovies")] Popular = 1, - [EnumMember(Value = "Top Anticipated Movies")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies")] Anticipated = 2, - [EnumMember(Value = "Top Box Office Movies")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies")] BoxOffice = 3, - [EnumMember(Value = "Top Watched Movies By Week")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek")] TopWatchedByWeek = 4, - [EnumMember(Value = "Top Watched Movies By Month")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth")] TopWatchedByMonth = 5, - [EnumMember(Value = "Top Watched Movies By Year")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear")] TopWatchedByYear = 6, - [EnumMember(Value = "Top Watched Movies Of All Time")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime")] TopWatchedByAllTime = 7, - [EnumMember(Value = "Recommended Movies By Week")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek")] RecommendedByWeek = 8, - [EnumMember(Value = "Recommended Movies By Month")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth")] RecommendedByMonth = 9, - [EnumMember(Value = "Recommended Movies By Year")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear")] RecommendedByYear = 10, - [EnumMember(Value = "Recommended Movies Of All Time")] + [FieldOption(Label = "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime")] RecommendedByAllTime = 11 } } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 27eb57fd16..2f6c3c2901 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -778,6 +778,18 @@ "ImportListsTraktSettingsLimitMovieHelpText": "Limit the number of movies to get", "ImportListsTraktSettingsListType": "List Type", "ImportListsTraktSettingsListTypeHelpText": "Type of list you're seeking to import from", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Popular Movies", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Recommended Movies By Month", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Recommended Movies By Week", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Recommended Movies By Year", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Recommended Movies By All Time", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Top Anticipated Movies", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Top Box Office Movies", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Top Watched Movies By Month", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Top Watched Movies By Week", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Top Watched Movies By Year", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Top Watched Movies Of All Time", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trending Movies", "ImportListsTraktSettingsRating": "Rating", "ImportListsTraktSettingsRatingMovieHelpText": "Filter movies by rating range (0-100)", "ImportListsTraktSettingsYears": "Years", From c6526c34e97e40bf3a5ccaa62f0db6649c6b89e0 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 16 Feb 2025 19:15:27 -0800 Subject: [PATCH 217/579] Cleanse console log messages (cherry picked from commit 609e964794e17343f63e1ecff3fef323e3d284ff) --- .../Instrumentation/CleansingClefLogLayout.cs | 21 +++++++++++++ .../CleansingConsoleLogLayout.cs | 26 ++++++++++++++++ ...neFileTarget.cs => CleansingFileTarget.cs} | 2 +- .../Instrumentation/NzbDroneLogger.cs | 30 +++++++++++-------- .../Instrumentation/ReconfigureLogging.cs | 8 ++--- 5 files changed, 68 insertions(+), 19 deletions(-) create mode 100644 src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs create mode 100644 src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs rename src/NzbDrone.Common/Instrumentation/{NzbDroneFileTarget.cs => CleansingFileTarget.cs} (87%) diff --git a/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs b/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs new file mode 100644 index 0000000000..f110b96ac9 --- /dev/null +++ b/src/NzbDrone.Common/Instrumentation/CleansingClefLogLayout.cs @@ -0,0 +1,21 @@ +using System.Text; +using NLog; +using NLog.Layouts.ClefJsonLayout; +using NzbDrone.Common.EnvironmentInfo; + +namespace NzbDrone.Common.Instrumentation; + +public class CleansingClefLogLayout : CompactJsonLayout +{ + protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) + { + base.RenderFormattedMessage(logEvent, target); + + if (RuntimeInfo.IsProduction) + { + var result = CleanseLogMessage.Cleanse(target.ToString()); + target.Clear(); + target.Append(result); + } + } +} diff --git a/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs b/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs new file mode 100644 index 0000000000..f894a4df55 --- /dev/null +++ b/src/NzbDrone.Common/Instrumentation/CleansingConsoleLogLayout.cs @@ -0,0 +1,26 @@ +using System.Text; +using NLog; +using NLog.Layouts; +using NzbDrone.Common.EnvironmentInfo; + +namespace NzbDrone.Common.Instrumentation; + +public class CleansingConsoleLogLayout : SimpleLayout +{ + public CleansingConsoleLogLayout(string format) + : base(format) + { + } + + protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) + { + base.RenderFormattedMessage(logEvent, target); + + if (RuntimeInfo.IsProduction) + { + var result = CleanseLogMessage.Cleanse(target.ToString()); + target.Clear(); + target.Append(result); + } + } +} diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs b/src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs similarity index 87% rename from src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs rename to src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs index 84658cf749..f74d1fca4f 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneFileTarget.cs +++ b/src/NzbDrone.Common/Instrumentation/CleansingFileTarget.cs @@ -4,7 +4,7 @@ namespace NzbDrone.Common.Instrumentation { - public class NzbDroneFileTarget : FileTarget + public class CleansingFileTarget : FileTarget { protected override void RenderFormattedMessage(LogEventInfo logEvent, StringBuilder target) { diff --git a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs index dce90afbf5..69b791a4de 100644 --- a/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs +++ b/src/NzbDrone.Common/Instrumentation/NzbDroneLogger.cs @@ -3,7 +3,6 @@ using System.IO; using NLog; using NLog.Config; -using NLog.Layouts.ClefJsonLayout; using NLog.Targets; using NzbDrone.Common.EnvironmentInfo; using NzbDrone.Common.Extensions; @@ -13,9 +12,11 @@ namespace NzbDrone.Common.Instrumentation { public static class NzbDroneLogger { - private const string FILE_LOG_LAYOUT = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; - public const string ConsoleLogLayout = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; - public static CompactJsonLayout ClefLogLayout = new CompactJsonLayout(); + private const string FileLogLayout = @"${date:format=yyyy-MM-dd HH\:mm\:ss.f}|${level}|${logger}|${message}${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; + private const string ConsoleFormat = "[${level}] ${logger}: ${message} ${onexception:inner=${newline}${newline}[v${assembly-version}] ${exception:format=ToString}${newline}${exception:format=Data}${newline}}"; + + private static readonly CleansingConsoleLogLayout CleansingConsoleLayout = new (ConsoleFormat); + private static readonly CleansingClefLogLayout ClefLogLayout = new (); private static bool _isConfigured; @@ -119,11 +120,7 @@ private static void RegisterConsole() ? formatEnumValue : ConsoleLogFormat.Standard; - coloredConsoleTarget.Layout = logFormat switch - { - ConsoleLogFormat.Clef => ClefLogLayout, - _ => ConsoleLogLayout - }; + ConfigureConsoleLayout(coloredConsoleTarget, logFormat); var loggingRule = new LoggingRule("*", level, coloredConsoleTarget); @@ -140,7 +137,7 @@ private static void RegisterAppFile(IAppFolderInfo appFolderInfo) private static void RegisterAppFile(IAppFolderInfo appFolderInfo, string name, string fileName, int maxArchiveFiles, LogLevel minLogLevel) { - var fileTarget = new NzbDroneFileTarget(); + var fileTarget = new CleansingFileTarget(); fileTarget.Name = name; fileTarget.FileName = Path.Combine(appFolderInfo.GetLogFolder(), fileName); @@ -153,7 +150,7 @@ private static void RegisterAppFile(IAppFolderInfo appFolderInfo, string name, s fileTarget.MaxArchiveFiles = maxArchiveFiles; fileTarget.EnableFileDelete = true; fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling; - fileTarget.Layout = FILE_LOG_LAYOUT; + fileTarget.Layout = FileLogLayout; var loggingRule = new LoggingRule("*", minLogLevel, fileTarget); @@ -172,7 +169,7 @@ private static void RegisterUpdateFile(IAppFolderInfo appFolderInfo) fileTarget.ConcurrentWrites = false; fileTarget.ConcurrentWriteAttemptDelay = 50; fileTarget.ConcurrentWriteAttempts = 100; - fileTarget.Layout = FILE_LOG_LAYOUT; + fileTarget.Layout = FileLogLayout; var loggingRule = new LoggingRule("*", LogLevel.Trace, fileTarget); @@ -217,6 +214,15 @@ public static Logger GetLogger(object obj) { return GetLogger(obj.GetType()); } + + public static void ConfigureConsoleLayout(ColoredConsoleTarget target, ConsoleLogFormat format) + { + target.Layout = format switch + { + ConsoleLogFormat.Clef => NzbDroneLogger.ClefLogLayout, + _ => NzbDroneLogger.CleansingConsoleLayout + }; + } } public enum ConsoleLogFormat diff --git a/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs b/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs index 1310255fd9..d49bb06d76 100644 --- a/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs +++ b/src/NzbDrone.Core/Instrumentation/ReconfigureLogging.cs @@ -95,7 +95,7 @@ private void SetMinimumLogLevel(LoggingRule rule, LogLevel minimumLogLevel) private void ReconfigureFile() { - foreach (var target in LogManager.Configuration.AllTargets.OfType()) + foreach (var target in LogManager.Configuration.AllTargets.OfType()) { target.MaxArchiveFiles = _configFileProvider.LogRotate; target.ArchiveAboveSize = _configFileProvider.LogSizeLimit.Megabytes(); @@ -120,11 +120,7 @@ private void ReconfigureConsole() { var format = _configFileProvider.ConsoleLogFormat; - consoleTarget.Layout = format switch - { - ConsoleLogFormat.Clef => NzbDroneLogger.ClefLogLayout, - _ => NzbDroneLogger.ConsoleLogLayout - }; + NzbDroneLogger.ConfigureConsoleLayout(consoleTarget, format); } } From 72244362feedf632d2173339177908aaa2cb65d8 Mon Sep 17 00:00:00 2001 From: Servarr Date: Wed, 19 Feb 2025 13:53:55 +0000 Subject: [PATCH 218/579] Automated API Docs update --- src/Radarr.Api.V3/openapi.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Radarr.Api.V3/openapi.json b/src/Radarr.Api.V3/openapi.json index 1633152c23..165c5b7d35 100644 --- a/src/Radarr.Api.V3/openapi.json +++ b/src/Radarr.Api.V3/openapi.json @@ -12074,6 +12074,9 @@ "type": "string", "nullable": true }, + "movieRequested": { + "type": "boolean" + }, "downloadAllowed": { "type": "boolean" }, From 0925769377e79dca436de2763d2f902b6e90f0c4 Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 22 Feb 2025 16:33:45 +0000 Subject: [PATCH 219/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Al3xPdx007 Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Oskari Lavinto Co-authored-by: Pablo Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: fordas Co-authored-by: pelnoph Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/ar.json | 5 ++- src/NzbDrone.Core/Localization/Core/bg.json | 5 ++- src/NzbDrone.Core/Localization/Core/ca.json | 5 ++- src/NzbDrone.Core/Localization/Core/cs.json | 6 ++- src/NzbDrone.Core/Localization/Core/da.json | 5 ++- src/NzbDrone.Core/Localization/Core/de.json | 12 +++++- src/NzbDrone.Core/Localization/Core/el.json | 5 ++- src/NzbDrone.Core/Localization/Core/es.json | 32 +++++++++++++++- src/NzbDrone.Core/Localization/Core/fi.json | 38 ++++++++++++++++--- src/NzbDrone.Core/Localization/Core/fr.json | 15 +++++++- src/NzbDrone.Core/Localization/Core/he.json | 5 ++- src/NzbDrone.Core/Localization/Core/hi.json | 5 ++- src/NzbDrone.Core/Localization/Core/hr.json | 5 ++- src/NzbDrone.Core/Localization/Core/hu.json | 8 +++- src/NzbDrone.Core/Localization/Core/is.json | 5 ++- src/NzbDrone.Core/Localization/Core/it.json | 9 ++++- src/NzbDrone.Core/Localization/Core/ja.json | 5 ++- src/NzbDrone.Core/Localization/Core/ko.json | 5 ++- .../Localization/Core/nb_NO.json | 4 +- src/NzbDrone.Core/Localization/Core/nl.json | 5 ++- src/NzbDrone.Core/Localization/Core/pl.json | 5 ++- src/NzbDrone.Core/Localization/Core/pt.json | 5 ++- .../Localization/Core/pt_BR.json | 32 +++++++++++++++- src/NzbDrone.Core/Localization/Core/ro.json | 11 +++++- src/NzbDrone.Core/Localization/Core/ru.json | 14 ++++++- src/NzbDrone.Core/Localization/Core/sk.json | 4 +- src/NzbDrone.Core/Localization/Core/sv.json | 5 ++- src/NzbDrone.Core/Localization/Core/th.json | 5 ++- src/NzbDrone.Core/Localization/Core/tr.json | 30 ++++++++++++++- src/NzbDrone.Core/Localization/Core/uk.json | 5 ++- src/NzbDrone.Core/Localization/Core/vi.json | 5 ++- .../Localization/Core/zh_CN.json | 7 +++- .../Localization/Core/zh_TW.json | 3 +- 33 files changed, 277 insertions(+), 38 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 4bb0030108..3b2f1d19f7 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1084,5 +1084,8 @@ "CustomFormatsSpecificationLanguage": "لغة", "CustomFormatsSpecificationMaximumSize": "أكبر مقاس", "CustomFormatsSpecificationSource": "مصدر", - "Mixed": "ثابت" + "Mixed": "ثابت", + "ImportListsTraktSettingsCertification": "شهادة", + "ImportListsTraktSettingsGenres": "الأنواع", + "ImportListsTraktSettingsRating": "التقييمات" } diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index a0723827a4..440f130858 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -1195,5 +1195,8 @@ "Delay": "Забавяне", "Label": "Етикет", "DownloadClientSettingsAddPaused": "Добави на пауза", - "Theme": "Тема" + "Theme": "Тема", + "ImportListsTraktSettingsCertification": "Сертифициране", + "ImportListsTraktSettingsGenres": "Жанрове", + "ImportListsTraktSettingsRating": "Оценки" } diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index e49507e95b..a3d297c3f3 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -1426,5 +1426,8 @@ "NotificationsAppriseSettingsTags": "Etiquetes d'Apprise", "NotificationsSettingsWebhookHeaders": "Capçaleres", "PreviouslyInstalled": "Instal·lat anteriorment", - "DownloadClientSettingsAddPaused": "Afegeix pausats" + "DownloadClientSettingsAddPaused": "Afegeix pausats", + "ImportListsTraktSettingsCertification": "Certificació", + "ImportListsTraktSettingsRating": "Valoració", + "ImportListsTraktSettingsGenres": "Gèneres" } diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 1a4bd02cb0..5db05932f7 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1295,5 +1295,9 @@ "CustomFormatsSpecificationRegularExpression": "Běžný výraz", "AutoTaggingSpecificationGenre": "Žánr(y)", "DeleteSelected": "Smazat vybrané", - "IndexerDownloadClientHealthCheckMessage": "Indexery s neplatnými klienty pro stahování: {indexerNames}." + "IndexerDownloadClientHealthCheckMessage": "Indexery s neplatnými klienty pro stahování: {indexerNames}.", + "ImportListsTraktSettingsAdditionalParameters": "Dodatečné parametry", + "ImportListsTraktSettingsRating": "Hodnocení", + "ImportListsTraktSettingsCertification": "Osvědčení", + "ImportListsTraktSettingsGenres": "Žánry" } diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 0c440d9cd1..ad11842ece 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -1106,5 +1106,8 @@ "CustomFormatsSpecificationMaximumSize": "Maksimal størrelse", "CustomFormatsSpecificationResolution": "Opløsning", "CustomFormatsSpecificationSource": "Kilde", - "Mixed": "Fast" + "Mixed": "Fast", + "ImportListsTraktSettingsCertification": "Certifikation", + "ImportListsTraktSettingsGenres": "Genrer", + "ImportListsTraktSettingsRating": "Bedømmelse" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 69ae60c404..974e8157b1 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1893,5 +1893,15 @@ "NotificationsGotifySettingIncludeMoviePoster": "Film-Poster einbeziehen", "OverrideGrabNoMovie": "Ein Film muss ausgewählt werden", "ShowRottenTomatoesRatingHelpText": "Tomato-Bewertung unter dem Poster anzeigen", - "NotificationsTagsMovieHelpText": "Benachrichtigungen nur für Filme mit mindestens einem übereinstimmenden Tag senden" + "NotificationsTagsMovieHelpText": "Benachrichtigungen nur für Filme mit mindestens einem übereinstimmenden Tag senden", + "ImportListsTraktSettingsAdditionalParameters": "Zusätzliche Parameter", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Zusätzliche Trakt-API-Parameter", + "ImportListsTraktSettingsGenres": "Genres", + "ImportListsTraktSettingsListType": "Listentyp", + "ImportListsTraktSettingsListTypeHelpText": "Typ der Liste, von der du importieren möchtest", + "ImportListsTraktSettingsRating": "Bewertung", + "ImportListsTraktSettingsYears": "Jahre", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Mit Trakt authentifizieren", + "ImportListsTraktSettingsCertification": "Zertifizierung", + "ImportListsTraktSettingsLimit": "Limit" } diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 60ea0eb0d3..9999afe3c2 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -1242,5 +1242,8 @@ "CustomFormatsSpecificationLanguage": "Γλώσσα", "CustomFormatsSpecificationMaximumSize": "Μέγιστο μέγεθος", "CustomFormatsSpecificationSource": "Πηγή", - "Mixed": "Σταθερός" + "Mixed": "Σταθερός", + "ImportListsTraktSettingsCertification": "Πιστοποιητικό", + "ImportListsTraktSettingsGenres": "Είδη", + "ImportListsTraktSettingsRating": "Ακροαματικότητα" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 70957b62c8..248b69b28e 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1891,5 +1891,35 @@ "AutoTaggingSpecificationMinimumRuntime": "Tiempo de ejecución mínimo", "CustomFormatsSpecificationQualityModifier": "Modificador de calidad", "Mixed": "Mezclado", - "MediaInfoFootNote2": "MediaInfo AudioLanguages excluye el inglés si es el único idioma. Usa MediaInfo AudioLanguagesAll para incluir solo el inglés" + "MediaInfoFootNote2": "MediaInfo AudioLanguages excluye el inglés si es el único idioma. Usa MediaInfo AudioLanguagesAll para incluir solo el inglés", + "UserInvokedSearch": "Búsqueda invocada por usuario", + "ImportListsTraktSettingsAdditionalParameters": "Parámetros adicionales", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Parámetros adicionales de la API de Trakt", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Autenticar con Trakt", + "ImportListsTraktSettingsCertification": "Certificación", + "ImportListsTraktSettingsListType": "Tipo de lista", + "ImportListsTraktSettingsRating": "Valoración", + "ImportListsTraktSettingsYears": "Años", + "ImportListsTraktSettingsGenres": "Géneros", + "ImportListsTraktSettingsLimit": "Limitar", + "ImportListsTraktSettingsListTypeHelpText": "Tipo de lista de la que deseas importar", + "ImportListsTraktSettingsCertificationMovieHelpText": "Filtrar películas por certificación (NR,G,PG-13,R,NC-17) (Separados por comas)", + "ImportListsTraktSettingsGenresMovieHelpText": "Filtrar películas por etiquetas de género de Trakt (separadas por coma) solo para listas populares", + "ImportListsTraktSettingsLimitMovieHelpText": "Limitar el número de películas a obtener", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Películas populares", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Películas recomendadas por mes", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Películas recomendadas por semana", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Películas recomendadas por año", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Películas recomendadas de todos los tiempos", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Películas más esperadas", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Películas más taquilleras", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Películas más vistas por mes", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Películas más vistas por semana", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Películas más vistas por año", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Películas más vistas de todos los tiempos", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Películas en tendencia", + "ImportListsTraktSettingsRatingMovieHelpText": "Filtrar películas por rango de calificación (0-100)", + "ImportListsTraktSettingsYearsMovieHelpText": "Filtras películas por año o rango de años", + "MovieRequested": "Películas solicitadas", + "ReleasePush": "Lanzamiento" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 95b351ce39..1d600cbd90 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -93,7 +93,7 @@ "Branch": "Haara", "BuiltIn": "Sisäänrakennettu", "CalendarOptions": "Kalenterin asetukset", - "Certification": "Varmennus", + "Certification": "Ikäluokitus", "ChangeFileDate": "Muuta tiedoston päiväys", "AddIndexer": "Lisää hakupalvelu", "CheckForFinishedDownloadsInterval": "Valmistuneiden latausten takistusväli", @@ -1155,8 +1155,8 @@ "RemoveQueueItem": "Poistetaan – {sourceTitle}", "TablePageSizeMaximum": "Sivukohtainen kohdemäärä ei voi olla suurempi kuin {maximumValue}.", "TablePageSizeMinimum": "Sivukohtaisen kohdemäärän on oltava vähintään {minimumValue}.", - "ApplyTagsHelpTextHowToApplyDownloadClients": "Tunnisteiden käyttö valituille latauspalveluille", - "ApplyTagsHelpTextHowToApplyImportLists": "Tunnisteiden käyttö valituille tuontilistoille", + "ApplyTagsHelpTextHowToApplyDownloadClients": "Tunnisteiden käyttö valituille latauspalveluille:", + "ApplyTagsHelpTextHowToApplyImportLists": "Tunnisteiden käyttö valituille tuontilistoille:", "SelectFolderModalTitle": "{modalTitle} – Valitse kansio", "OverrideGrabModalTitle": "Ohitetaan ja kaapataan – {title}", "OverrideAndAddToDownloadQueue": "Ohita ja lisää latausjonoon", @@ -1165,7 +1165,7 @@ "DeleteRootFolderMessageText": "Haluatko varmasti poistaa juurikansion \"{path}\"?", "DisabledForLocalAddresses": "Ei käytössä paikallisissa osoitteissa", "NoDownloadClientsFound": "Latauspalveluita ei löytynyt", - "ManageFiles": "Tiedostojen hallinta", + "ManageFiles": "Hallitse tiedostoja", "OrganizeLoadError": "Virhe ladattaessa esikatseluita", "OrganizeModalHeader": "Järjestele ja uudelleennimeä", "RemoveQueueItemConfirmation": "Haluatko varmasti poistaa kohteen \"{sourceTitle}\" jonosta?", @@ -1894,5 +1894,33 @@ "UserInvokedSearch": "Käyttäjä herätti haun", "ReleasePush": "Julkaisun työntö", "Mixed": "Sekoitettu", - "MediaInfoFootNote2": "MediaInfo AudioLanguages ei huomioi englantia sen ollessa ainoa kieli. MediaInfo AudioLanguagesAll sisällyttää vain englanninkielen sisältävät kohteet." + "MediaInfoFootNote2": "MediaInfo AudioLanguages ei huomioi englantia sen ollessa ainoa kieli. MediaInfo AudioLanguagesAll sisällyttää vain englanninkielen sisältävät kohteet.", + "MovieRequested": "Elokuvaa pyydetty", + "ImportListsTraktSettingsAdditionalParameters": "Muut parametrit", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Muut Trakt-rajapinnan parametrit.", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Tunnistaudu Traktilla", + "ImportListsTraktSettingsCertification": "Ikäluokitus", + "ImportListsTraktSettingsGenres": "Lajityypit", + "ImportListsTraktSettingsLimit": "Rajoitus", + "ImportListsTraktSettingsListType": "Listan tyyppi", + "ImportListsTraktSettingsListTypeHelpText": "Tuotavan listan tyyppi.", + "ImportListsTraktSettingsRating": "Arvio", + "ImportListsTraktSettingsYears": "Vuodet", + "ImportListsTraktSettingsCertificationMovieHelpText": "Suodata elokuvia ikäluokitusten perusteella (NR,G,PG,PG-13,R,NC-17) (pilkuin eroteltuna).", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Kaikkien aikojen elokuvasuositukset", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Kuukausikohtaiset elokuvasuositukset", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Viikkokohtaiset elokuvasuositukset", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Vuosikohtaiset elokuvasuositukset", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Suositut elokuvat", + "ImportListsTraktSettingsLimitMovieHelpText": "Rajoita noudettavien elokuvien määrää.", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Odotetuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Viikottain katsotuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Kuukausittain katsotuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Vuosittain katsotuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Teattereissa katsotuimmat elokuvat", + "ImportListsTraktSettingsYearsMovieHelpText": "Suodata elokuvia vuoden tai vuosivälin perusteella.", + "ImportListsTraktSettingsRatingMovieHelpText": "Suodata elokuvia arvioden perusteella (alue 0–100).", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Kaikkien aikojen katsotuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trendaavat elokuvat", + "ImportListsTraktSettingsGenresMovieHelpText": "Suodata elokuvia Trakt-lajityyppien slug-arvojen perusteella (pilkuin eroteltuna). Koskee vain suosituimpia listoja." } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 2df6c96ae0..f6b056b505 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1890,5 +1890,18 @@ "NotificationsGotifySettingsPreferredMetadataLink": "Lien de métadonnées préféré", "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Lien de métadonnées pour les clients qui ne prennent en charge qu'un seul lien", "ManageFormats": "Gérer les formats", - "Mixed": "Mixte" + "Mixed": "Mixte", + "MediaInfoFootNote2": "MediaInfo AudioLanguages exclut l'anglais s'il s'agit de la seule langue. Utilisez MediaInfo AudioLanguagesAll pour inclure uniquement l'anglais", + "UserInvokedSearch": "Recherche invoquée par l'utilisateur", + "MovieRequested": "Film demandé", + "ImportListsTraktSettingsRating": "Evaluation", + "ImportListsTraktSettingsYears": "Années", + "ImportListsTraktSettingsAdditionalParameters": "Paramètres supplémentaires", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Paramètres supplémentaires de l'API Trakt", + "ImportListsTraktSettingsAuthenticateWithTrakt": "S'authentifier avec Trakt", + "ImportListsTraktSettingsCertification": "Certification", + "ImportListsTraktSettingsGenres": "Genres", + "ImportListsTraktSettingsLimit": "Limite", + "ImportListsTraktSettingsListType": "Type de liste", + "ImportListsTraktSettingsListTypeHelpText": "Type de liste à partir de laquelle vous cherchez à importer" } diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 0deca2cd23..154318879f 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -1127,5 +1127,8 @@ "CustomFormatsSpecificationSource": "מָקוֹר", "AutoTaggingSpecificationRootFolder": "תיקיית שורש", "AutoTaggingSpecificationStatus": "סטָטוּס", - "Mixed": "תוקן" + "Mixed": "תוקן", + "ImportListsTraktSettingsCertification": "תעודה", + "ImportListsTraktSettingsGenres": "ז'אנרים", + "ImportListsTraktSettingsRating": "דירוגים" } diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index f6b080cc9b..0555d4e0cb 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -1079,5 +1079,8 @@ "CustomFormatsSpecificationLanguage": "भाषा: हिन्दी", "CustomFormatsSpecificationMaximumSize": "अधिकतम आकार", "CustomFormatsSpecificationSource": "स्रोत", - "Mixed": "फिक्स्ड" + "Mixed": "फिक्स्ड", + "ImportListsTraktSettingsCertification": "प्रमाणीकरण", + "ImportListsTraktSettingsGenres": "शैलियां", + "ImportListsTraktSettingsRating": "रेटिंग्स" } diff --git a/src/NzbDrone.Core/Localization/Core/hr.json b/src/NzbDrone.Core/Localization/Core/hr.json index ec31c6dbef..6bc0fecd82 100644 --- a/src/NzbDrone.Core/Localization/Core/hr.json +++ b/src/NzbDrone.Core/Localization/Core/hr.json @@ -373,5 +373,8 @@ "AutoTaggingSpecificationRootFolder": "Korijenska Mapa", "CustomFormatsSpecificationLanguage": "jezik", "CustomFormatsSpecificationResolution": "Razlučivost", - "CustomFormatsSpecificationSource": "Izvor" + "CustomFormatsSpecificationSource": "Izvor", + "ImportListsTraktSettingsRating": "Ocjena", + "ImportListsTraktSettingsCertification": "Certifikacija", + "ImportListsTraktSettingsGenres": "Žanr" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 1bf62edf12..6538c90f51 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1465,5 +1465,11 @@ "CustomFormatsSpecificationMinimumYear": "Minimum Év", "CustomFormatsSpecificationResolution": "Felbontás", "CustomFormatsSpecificationSource": "Forrás", - "Mixed": "Mixed" + "Mixed": "Mixed", + "ImportListsTraktSettingsCertification": "Tanúsítvány", + "ImportListsTraktSettingsGenres": "Műfajok", + "ImportListsTraktSettingsListType": "Lista típus", + "ImportListsTraktSettingsListTypeHelpText": "Az importálni kívánt lista típusa", + "ImportListsTraktSettingsRating": "Értékelés", + "ImportListsTraktSettingsYears": "Évek" } diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index e50082e567..4c591ae050 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -1081,5 +1081,8 @@ "CustomFormatsSpecificationMaximumSize": "Hámarksstærð", "CustomFormatsSpecificationSource": "Heimild", "AutoTaggingSpecificationQualityProfile": "Gæðaprófíll", - "Mixed": "Fastur" + "Mixed": "Fastur", + "ImportListsTraktSettingsCertification": "Vottun", + "ImportListsTraktSettingsGenres": "Tegundir", + "ImportListsTraktSettingsRating": "Einkunnir" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index bb1cb5473b..8a532aa193 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1494,5 +1494,12 @@ "AutoTaggingLoadError": "Impossibile caricare auto tagging", "AnnouncedMovieAvailabilityDescription": "I film sono considerati disponibili non appena vengono aggiunti a {appName}.", "AutoRedownloadFailedFromInteractiveSearch": "Riesecuzione del download non riuscita dalla ricerca interattiva", - "AutoTaggingRequiredHelpText": "Questa condizione {implementationName} deve corrispondere perché si applichi la regola di auto tagging. Altrimenti è sufficiente una singola corrispondenza {implementationName}." + "AutoTaggingRequiredHelpText": "Questa condizione {implementationName} deve corrispondere perché si applichi la regola di auto tagging. Altrimenti è sufficiente una singola corrispondenza {implementationName}.", + "ImportListsTraktSettingsAdditionalParameters": "Parametri Addizionali", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Autentica con Trakt", + "ImportListsTraktSettingsRating": "Valutazione", + "ImportListsTraktSettingsCertification": "Certificazione", + "ImportListsTraktSettingsGenres": "Generi", + "ImportListsTraktSettingsLimit": "Limite", + "ImportListsTraktSettingsListType": "Tipo Lista" } diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 17a15116ba..64f3646734 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -1081,5 +1081,8 @@ "CustomFormatsSpecificationMaximumSize": "最大サイズ", "CustomFormatsSpecificationSource": "ソース", "CustomFormatsSpecificationLanguage": "言語", - "Mixed": "修繕" + "Mixed": "修繕", + "ImportListsTraktSettingsCertification": "認証", + "ImportListsTraktSettingsGenres": "ジャンル", + "ImportListsTraktSettingsRating": "評価" } diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 7affe795bf..24903dfe61 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1893,5 +1893,8 @@ "RemoveCompletedDownloads": "완료된 다운로드 제거", "RemoveTagsAutomaticallyHelpText": "조건이 충족되지 않으면 태그를 자동으로 제거", "DownloadClientQbittorrentSettingsSequentialOrder": "순차적 순서", - "Mixed": "결정된" + "Mixed": "결정된", + "ImportListsTraktSettingsCertification": "인증", + "ImportListsTraktSettingsGenres": "장르", + "ImportListsTraktSettingsRating": "등급" } diff --git a/src/NzbDrone.Core/Localization/Core/nb_NO.json b/src/NzbDrone.Core/Localization/Core/nb_NO.json index a0653c59c6..035d90d45b 100644 --- a/src/NzbDrone.Core/Localization/Core/nb_NO.json +++ b/src/NzbDrone.Core/Localization/Core/nb_NO.json @@ -332,5 +332,7 @@ "AddImportList": "Ny Importliste", "AddNewRestriction": "Legg til ny begrensning", "AddDownloadClientImplementation": "Ny Nedlastingsklient - {implementationName}", - "AddImportListImplementation": "Legg til importliste - {implementationName}" + "AddImportListImplementation": "Legg til importliste - {implementationName}", + "ImportListsTraktSettingsCertification": "Sertifisering", + "ImportListsTraktSettingsRating": "Vurdering" } diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index c28683c81e..fde307f78c 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -1254,5 +1254,8 @@ "CustomFormatsSpecificationResolution": "Resolutie", "CustomFormatsSpecificationSource": "Bron", "CustomFormatsSpecificationLanguage": "Taal", - "Mixed": "Opgelost" + "Mixed": "Opgelost", + "ImportListsTraktSettingsCertification": "Certificatie", + "ImportListsTraktSettingsRating": "Score", + "ImportListsTraktSettingsGenres": "Genres" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 742a50c4e6..d88c4e5263 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1196,5 +1196,8 @@ "CustomFormatsSpecificationMaximumSize": "Największy rozmiar", "CustomFormatsSpecificationResolution": "Rozdzielczość", "CustomFormatsSpecificationSource": "Źródło", - "Mixed": "Naprawiony" + "Mixed": "Naprawiony", + "ImportListsTraktSettingsRating": "Ocena", + "ImportListsTraktSettingsCertification": "Certyfikacja", + "ImportListsTraktSettingsGenres": "Gatunki" } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index aba2d9fabd..87827f51ca 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1275,5 +1275,8 @@ "CustomFormatsSpecificationMaximumSize": "Tamanho máximo", "CustomFormatsSpecificationResolution": "Resolução", "CustomFormatsSpecificationSource": "Origem", - "Mixed": "Corrigido" + "Mixed": "Corrigido", + "ImportListsTraktSettingsCertification": "Certificação", + "ImportListsTraktSettingsGenres": "Gêneros", + "ImportListsTraktSettingsRating": "Classificação" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 0f8dacde02..7ee37ffe9b 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -338,7 +338,7 @@ "ApplyTagsHelpTextHowToApplyMovies": "Como aplicar etiquetas aos filmes selecionados", "ApplyTags": "Aplicar etiquetas", "Apply": "Aplicar", - "AppDataLocationHealthCheckMessage": "Não será possível atualizar para evitar a exclusão de AppData na atualização", + "AppDataLocationHealthCheckMessage": "Não será possível atualizar para evitar a exclusão de AppData na Atualização", "AppDataDirectory": "Diretório AppData", "ApiKey": "Chave da API", "Announced": "Anunciado", @@ -1894,5 +1894,33 @@ "ReleaseSource": "Fonte do Lançamento", "UserInvokedSearch": "Pesquisa Invocada pelo Usuário", "Mixed": "Misturado", - "MediaInfoFootNote2": "O MediaInfo Audiolanguages exclui o inglês se for o único idioma. Use MediaInfo AudiolanguagesAll para incluir apenas o inglês" + "MediaInfoFootNote2": "O MediaInfo Audiolanguages exclui o inglês se for o único idioma. Use MediaInfo AudiolanguagesAll para incluir apenas o inglês", + "MovieRequested": "Filme Solicitado", + "ImportListsTraktSettingsAdditionalParameters": "Parâmetros adicionais", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Parâmetros adicionais da API do Trakt", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Autenticar com Trakt", + "ImportListsTraktSettingsCertification": "Certificação", + "ImportListsTraktSettingsGenres": "Gêneros", + "ImportListsTraktSettingsLimit": "Limite", + "ImportListsTraktSettingsListType": "Tipo de lista", + "ImportListsTraktSettingsRating": "Avaliação", + "ImportListsTraktSettingsYears": "Anos", + "ImportListsTraktSettingsListTypeHelpText": "Tipo de lista da qual você deseja importar", + "ImportListsTraktSettingsCertificationMovieHelpText": "Filtrar os filmes de uma certificação (NR, G, PG, PG-13, R, NC-17) (Separados com Vírgula)", + "ImportListsTraktSettingsGenresMovieHelpText": "Filtrar filmes de Gênero Trakt Slug (Separado com Vírgula) Apenas para Listas Populares", + "ImportListsTraktSettingsLimitMovieHelpText": "Limitar o número de filmes para obter", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Filmes Populares", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Filmes Recomendados Por Mês", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Filmes Recomendados Por Semana", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Filmes Recomendados Por Ano", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Filmes Recomendados de Todos os Tempos", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Filmes Mais Esperados", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Filmes de Maiores Bilheterias", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Filmes Mais Assistidos por Mês", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Filmes Mais Assistidos Por Semana", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Filmes Mais Assistidos Por Ano", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Filmes Mais Assistidos de Todos os Tempos", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Filmes em Alta", + "ImportListsTraktSettingsRatingMovieHelpText": "Filtrar filmes por faixa de avaliação (0-100)", + "ImportListsTraktSettingsYearsMovieHelpText": "Filtrar filmes por ano ou faixa de ano" } diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index a3ec0b1efd..053237e6d5 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -1160,5 +1160,14 @@ "CustomFormatsSpecificationMaximumSize": "Dimensiune maximă", "CustomFormatsSpecificationSource": "Sursă", "AutoTaggingSpecificationOriginalLanguage": "Limbă", - "Mixed": "Fix" + "Mixed": "Fix", + "AddCondition": "Adăugați Conditie", + "AddAutoTag": "Adăugați Tagare Automata", + "AddImportList": "Adăugați Lista de Import", + "AnnouncedMovieAvailabilityDescription": "Filmele sunt considerate disponibile imediat ce sunt adăugate in {appName}.", + "Any": "Oricare", + "ApiKeyValidationHealthCheckMessage": "Te rugăm să actualizezi cheia API astfel încât să aibă cel puțin {length} caractere. Poți face acest lucru din setări sau din fișierul de configurare", + "ImportListsTraktSettingsCertification": "Certificare", + "ImportListsTraktSettingsGenres": "Genuri", + "ImportListsTraktSettingsRating": "Recenzii" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 06e51fef1b..640cb09bce 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1811,5 +1811,17 @@ "CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного", "Mixed": "Смешанный", "MediaInfoFootNote2": "MediaInfo AudioLanguages не добавляет английский язык, если это единственный доступный язык. Используйте MediaInfo AudioLanguagesAll для добавления английского языка в таких случаях", - "AutoTaggingSpecificationMinimumRuntime": "Минимальное время выполнения" + "AutoTaggingSpecificationMinimumRuntime": "Минимальное время выполнения", + "EditSelectedCustomFormats": "Изменить выбранные пользовательские форматы", + "DeleteSelected": "Удалить выбранные", + "ImportListsTraktSettingsAdditionalParameters": "Дополнительные параметры", + "ImportListsTraktSettingsCertification": "Возрастной рейтинг", + "ImportListsTraktSettingsGenres": "Жанры", + "ImportListsTraktSettingsLimit": "Лимит", + "ImportListsTraktSettingsListType": "Тип списка", + "ImportListsTraktSettingsListTypeHelpText": "Тип списка, из которого вы хотите импортировать", + "ImportListsTraktSettingsRating": "Рейтинг", + "ImportListsTraktSettingsYears": "Годы", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Дополнительные параметры Trakt API", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Аутентификация с помощью Trakt" } diff --git a/src/NzbDrone.Core/Localization/Core/sk.json b/src/NzbDrone.Core/Localization/Core/sk.json index 55b4b58ec3..a7d541c9b3 100644 --- a/src/NzbDrone.Core/Localization/Core/sk.json +++ b/src/NzbDrone.Core/Localization/Core/sk.json @@ -304,5 +304,7 @@ "AutoTaggingSpecificationQualityProfile": "Profil kvality", "AutoTaggingSpecificationRootFolder": "Koreňový priečinok", "CustomFormatsSpecificationResolution": "Rozlíšenie", - "CustomFormatsSpecificationLanguage": "jazyk" + "CustomFormatsSpecificationLanguage": "jazyk", + "ImportListsTraktSettingsRating": "Hodnotenie", + "ImportListsTraktSettingsCertification": "Certifikácia" } diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 2c0a295bcf..07bb14e90e 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -1108,5 +1108,8 @@ "CustomFormatsSpecificationMaximumSize": "Maximal storlek", "CustomFormatsSpecificationSource": "Källa", "AutoTaggingSpecificationOriginalLanguage": "Språk", - "Mixed": "Fast" + "Mixed": "Fast", + "ImportListsTraktSettingsGenres": "Genrer", + "ImportListsTraktSettingsCertification": "Certifikation", + "ImportListsTraktSettingsRating": "Betyg" } diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index be8d234eef..af6e6cf809 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -1079,5 +1079,8 @@ "CustomFormatsSpecificationLanguage": "ภาษา", "CustomFormatsSpecificationMaximumSize": "ขนาดสูงสุด", "CustomFormatsSpecificationSource": "ที่มา", - "Mixed": "แก้ไขแล้ว" + "Mixed": "แก้ไขแล้ว", + "ImportListsTraktSettingsCertification": "การรับรอง", + "ImportListsTraktSettingsGenres": "ประเภท", + "ImportListsTraktSettingsRating": "การให้คะแนน" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 2b282830c1..b5bd15e729 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1894,5 +1894,33 @@ "UserInvokedSearch": "Kullanıcı Tarafından Çağrılan Arama", "ReleasePush": "Yayın İtimi", "Mixed": "Karışık", - "MediaInfoFootNote2": "MediaInfo AudioLanguages, tek dil İngilizce ise hariç tutar. MediaInfo AudioLanguagesAll'ı yalnızca İngilizce'yi dahil etmek için kullanın" + "MediaInfoFootNote2": "MediaInfo AudioLanguages, tek dil İngilizce ise hariç tutar. MediaInfo AudioLanguagesAll'ı yalnızca İngilizce'yi dahil etmek için kullanın", + "MovieRequested": "Film Talep Edildi", + "ImportListsTraktSettingsAdditionalParameters": "Ek Parametreler", + "ImportListsTraktSettingsAdditionalParametersHelpText": "Ek Trakt API parametreleri", + "ImportListsTraktSettingsAuthenticateWithTrakt": "Trakt ile kimlik doğrulama", + "ImportListsTraktSettingsRating": "Puan", + "ImportListsTraktSettingsCertification": "Sertifika", + "ImportListsTraktSettingsGenres": "Türler", + "ImportListsTraktSettingsLimit": "Sınır", + "ImportListsTraktSettingsListType": "Liste Türü", + "ImportListsTraktSettingsListTypeHelpText": "İçe aktarmak istediğiniz listenin türü", + "ImportListsTraktSettingsYears": "Yıl", + "ImportListsTraktSettingsCertificationMovieHelpText": "Filmleri sertifikaya göre filtrele (NR,G,PG,PG-13,R,NC-17) (Virgülle Ayrılmış)", + "ImportListsTraktSettingsGenresMovieHelpText": "Filmleri Trakt Türüne Göre Filtrele (Virgülle Ayrılmış) Yalnızca Popüler Listeler İçin", + "ImportListsTraktSettingsLimitMovieHelpText": "Edinilecek film sayısını sınırla", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Popüler Filmler", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Aylara Göre Önerilen Filmler", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Haftaya Göre Önerilen Filmler", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Yıla Göre Önerilen Filmler", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Tüm Zamanlarda Önerilen Filmler", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "En Çok Beklenen Filmler", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "En İyi Gişe Filmleri", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Haftaya Göre En Çok İzlenen Filmler", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Yıla Göre En Çok İzlenen Filmler", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Tüm Zamanlarda En Çok İzlenen Filmler", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trend Filmler", + "ImportListsTraktSettingsRatingMovieHelpText": "Filmleri derecelendirme aralığına göre filtrele (0-100)", + "ImportListsTraktSettingsYearsMovieHelpText": "Filmleri yıla veya yıl aralığına göre filtrele", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Aylara Göre En Çok İzlenen Filmler" } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 56af611822..8c3967899b 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -1309,5 +1309,8 @@ "CustomFormatsSpecificationResolution": "Роздільна здатність", "CustomFormatsSpecificationSource": "Джерело", "AutoTaggingSpecificationOriginalLanguage": "Мова", - "Mixed": "Виправлено" + "Mixed": "Виправлено", + "ImportListsTraktSettingsRating": "Рейтинг", + "ImportListsTraktSettingsCertification": "Віковий рейтинг", + "ImportListsTraktSettingsGenres": "Жанри" } diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 2636be8b81..922345710b 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -1120,5 +1120,8 @@ "CustomFormatsSpecificationLanguage": "Ngôn ngữ", "CustomFormatsSpecificationMaximumSize": "Kích thước tối đa", "CustomFormatsSpecificationSource": "Nguồn", - "Mixed": "đã sửa" + "Mixed": "đã sửa", + "ImportListsTraktSettingsCertification": "Chứng chỉ", + "ImportListsTraktSettingsGenres": "Thể loại", + "ImportListsTraktSettingsRating": "Xếp hạng" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 695f0565ad..f09ba82571 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1884,5 +1884,10 @@ "CustomFormatsSpecificationSource": "代码", "AutoTaggingSpecificationGenre": "类型", "AutoTaggingSpecificationMaximumYear": "最大年份", - "Mixed": "混合" + "Mixed": "混合", + "ImportListsTraktSettingsAdditionalParameters": "附加参数", + "ImportListsTraktSettingsAuthenticateWithTrakt": "使用 Trakt 进行认证", + "ImportListsTraktSettingsCertification": "分级", + "ImportListsTraktSettingsGenres": "类型", + "ImportListsTraktSettingsRating": "评分" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_TW.json b/src/NzbDrone.Core/Localization/Core/zh_TW.json index 08b5496887..a051770ca7 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_TW.json +++ b/src/NzbDrone.Core/Localization/Core/zh_TW.json @@ -287,5 +287,6 @@ "AutoTaggingSpecificationQualityProfile": "品質設定檔", "AutoTaggingSpecificationRootFolder": "根目錄資料夾", "CustomFormatsSpecificationLanguage": "語言", - "CustomFormatsSpecificationResolution": "解析度" + "CustomFormatsSpecificationResolution": "解析度", + "ImportListsTraktSettingsRating": "評分" } From b7a46bedb036f6e57a2f2d043ddcbd1659fea82d Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 22 Feb 2025 21:28:33 +0200 Subject: [PATCH 220/579] Fixed: Avoid checking for free space if other specifications fail first --- .../DecisionEngine/Specifications/FreeSpaceSpecification.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs b/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs index 2067615d27..44d2b43581 100644 --- a/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs +++ b/src/NzbDrone.Core/DecisionEngine/Specifications/FreeSpaceSpecification.cs @@ -21,7 +21,7 @@ public FreeSpaceSpecification(IConfigService configService, IDiskProvider diskPr _logger = logger; } - public SpecificationPriority Priority => SpecificationPriority.Default; + public SpecificationPriority Priority => SpecificationPriority.Disk; public RejectionType Type => RejectionType.Permanent; public DownloadSpecDecision IsSatisfiedBy(RemoteMovie subject, SearchCriteriaBase searchCriteria) From 7de7e83c5bd136bf5fdbf78746e734f07969ab81 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 23 Feb 2025 00:03:48 +0200 Subject: [PATCH 221/579] New: Add Blu-ray link to movie details --- frontend/src/Movie/Details/MovieDetailsLinks.tsx | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/frontend/src/Movie/Details/MovieDetailsLinks.tsx b/frontend/src/Movie/Details/MovieDetailsLinks.tsx index 03d9f1baf5..c433789e04 100644 --- a/frontend/src/Movie/Details/MovieDetailsLinks.tsx +++ b/frontend/src/Movie/Details/MovieDetailsLinks.tsx @@ -92,6 +92,19 @@ function MovieDetailsLinks(props: MovieDetailsLinksProps) { MDBList + + + + ) : null} From 553645a07c4f70b45b0b0f5533f1feab2b719d42 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 23 Feb 2025 12:14:28 +0200 Subject: [PATCH 222/579] Bump version to 5.19.2 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 869edf1592..97127d918b 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.19.2' + majorVersion: '5.19.3' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From 554e15d438512e50e7fc22bd68d45d7b4610fb7f Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 22 Feb 2025 15:20:39 +0200 Subject: [PATCH 223/579] New: Watch list sorting and rate limit for Trakt Import Lists --- .../ImportLists/Trakt/User/TraktUserImport.cs | 5 +-- .../Trakt/User/TraktUserListType.cs | 8 ++-- .../Trakt/User/TraktUserRequestGenerator.cs | 37 +++++++++++++------ .../Trakt/User/TraktUserSettings.cs | 16 +++++++- src/NzbDrone.Core/Localization/Core/en.json | 6 +++ .../Notifications/Trakt/TraktProxy.cs | 25 +++++++++---- 6 files changed, 69 insertions(+), 28 deletions(-) diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserImport.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserImport.cs index 6f8198cd7a..dd100f331a 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserImport.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserImport.cs @@ -25,10 +25,7 @@ public TraktUserImport(IImportListRepository importListRepository, public override IImportListRequestGenerator GetRequestGenerator() { - return new TraktUserRequestGenerator(_traktProxy) - { - Settings = Settings - }; + return new TraktUserRequestGenerator(_traktProxy, Settings); } } } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserListType.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserListType.cs index b90508d145..a42eaf01a1 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserListType.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserListType.cs @@ -1,14 +1,14 @@ -using System.Runtime.Serialization; +using NzbDrone.Core.Annotations; namespace NzbDrone.Core.ImportLists.Trakt.User { public enum TraktUserListType { - [EnumMember(Value = "User Watch List")] + [FieldOption(Label = "ImportListsTraktSettingsUserListTypeWatch")] UserWatchList = 0, - [EnumMember(Value = "User Watched List")] + [FieldOption(Label = "ImportListsTraktSettingsUserListTypeWatched")] UserWatchedList = 1, - [EnumMember(Value = "User Collection List")] + [FieldOption(Label = "ImportListsTraktSettingsUserListTypeCollection")] UserCollectionList = 2 } } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs index f68ef6813d..eb545870ca 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserRequestGenerator.cs @@ -1,6 +1,6 @@ using System.Collections.Generic; -using System.Net.Http; using NzbDrone.Common.Extensions; +using NzbDrone.Common.Http; using NzbDrone.Core.Notifications.Trakt; namespace NzbDrone.Core.ImportLists.Trakt.User @@ -8,11 +8,12 @@ namespace NzbDrone.Core.ImportLists.Trakt.User public class TraktUserRequestGenerator : IImportListRequestGenerator { private readonly ITraktProxy _traktProxy; - public TraktUserSettings Settings { get; set; } + private readonly TraktUserSettings _settings; - public TraktUserRequestGenerator(ITraktProxy traktProxy) + public TraktUserRequestGenerator(ITraktProxy traktProxy, TraktUserSettings settings) { _traktProxy = traktProxy; + _settings = settings; } public virtual ImportListPageableRequestChain GetMovies() @@ -26,25 +27,39 @@ public virtual ImportListPageableRequestChain GetMovies() private IEnumerable GetMoviesRequest() { - var link = string.Empty; - var userName = Settings.Username.IsNotNullOrWhiteSpace() ? Settings.Username.Trim() : Settings.AuthUser.Trim(); + var requestBuilder = new HttpRequestBuilder(_settings.Link.Trim()); - switch (Settings.TraktListType) + switch (_settings.TraktListType) { case (int)TraktUserListType.UserWatchList: - link += $"users/{userName}/watchlist/movies?limit={Settings.Limit}"; + var watchSorting = _settings.TraktWatchSorting switch + { + (int)TraktUserWatchSorting.Added => "added", + (int)TraktUserWatchSorting.Title => "title", + (int)TraktUserWatchSorting.Released => "released", + _ => "rank" + }; + + requestBuilder + .Resource("/users/{userName}/watchlist/movies/{sorting}") + .SetSegment("sorting", watchSorting); break; case (int)TraktUserListType.UserWatchedList: - link += $"users/{userName}/watched/movies?limit={Settings.Limit}"; + requestBuilder.Resource("/users/{userName}/watched/movies"); break; case (int)TraktUserListType.UserCollectionList: - link += $"users/{userName}/collection/movies?limit={Settings.Limit}"; + requestBuilder.Resource("/users/{userName}/collection/movies"); break; } - var request = new ImportListRequest(_traktProxy.BuildRequest(link, HttpMethod.Get, Settings.AccessToken)); + var userName = _settings.Username.IsNotNullOrWhiteSpace() ? _settings.Username.Trim() : _settings.AuthUser.Trim(); - yield return request; + requestBuilder + .SetSegment("userName", userName) + .WithRateLimit(4) + .AddQueryParam("limit", _settings.Limit.ToString()); + + yield return new ImportListRequest(_traktProxy.BuildRequest(requestBuilder.Build(), _settings.AccessToken)); } } } diff --git a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs index c5575b6022..6b7869266c 100644 --- a/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs +++ b/src/NzbDrone.Core/ImportLists/Trakt/User/TraktUserSettings.cs @@ -20,12 +20,16 @@ public class TraktUserSettings : TraktSettingsBase public TraktUserSettings() { TraktListType = (int)TraktUserListType.UserWatchList; + TraktWatchSorting = (int)TraktUserWatchSorting.Rank; } - [FieldDefinition(1, Label = "List Type", Type = FieldType.Select, SelectOptions = typeof(TraktUserListType), HelpText = "Type of list you're seeking to import from")] + [FieldDefinition(1, Label = "List Type", Type = FieldType.Select, SelectOptions = typeof(TraktUserListType), HelpText = "ImportListsTraktSettingsListTypeHelpText")] public int TraktListType { get; set; } - [FieldDefinition(2, Label = "Username", HelpText = "Username for the List to import from (empty to use Auth User)")] + [FieldDefinition(2, Label = "ImportListsTraktSettingsWatchListSorting", Type = FieldType.Select, SelectOptions = typeof(TraktUserWatchSorting), HelpText = "ImportListsTraktSettingsWatchListSortingHelpText")] + public int TraktWatchSorting { get; set; } + + [FieldDefinition(3, Label = "Username", HelpText = "ImportListsTraktSettingsUserListUsernameHelpText")] public string Username { get; set; } public override NzbDroneValidationResult Validate() @@ -33,4 +37,12 @@ public override NzbDroneValidationResult Validate() return new NzbDroneValidationResult(Validator.Validate(this)); } } + + public enum TraktUserWatchSorting + { + Rank = 0, + Added = 1, + Title = 2, + Released = 3 + } } diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 2f6c3c2901..feaa288e9a 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -792,6 +792,12 @@ "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trending Movies", "ImportListsTraktSettingsRating": "Rating", "ImportListsTraktSettingsRatingMovieHelpText": "Filter movies by rating range (0-100)", + "ImportListsTraktSettingsUserListTypeCollection": "User Collection List", + "ImportListsTraktSettingsUserListTypeWatch": "User Watch List", + "ImportListsTraktSettingsUserListTypeWatched": "User Watched List", + "ImportListsTraktSettingsUserListUsernameHelpText": "Username for the List to import from (leave empty to use Auth User)", + "ImportListsTraktSettingsWatchListSorting": "Watch List Sorting", + "ImportListsTraktSettingsWatchListSortingHelpText": "If List Type is Watch, select the order to sort the list", "ImportListsTraktSettingsYears": "Years", "ImportListsTraktSettingsYearsMovieHelpText": "Filter movies by year or year range", "ImportMechanismHealthCheckMessage": "Enable Completed Download Handling", diff --git a/src/NzbDrone.Core/Notifications/Trakt/TraktProxy.cs b/src/NzbDrone.Core/Notifications/Trakt/TraktProxy.cs index c45ff16079..2e2c0b30f1 100644 --- a/src/NzbDrone.Core/Notifications/Trakt/TraktProxy.cs +++ b/src/NzbDrone.Core/Notifications/Trakt/TraktProxy.cs @@ -1,6 +1,5 @@ using System; using System.Net.Http; -using NLog; using NzbDrone.Common.Extensions; using NzbDrone.Common.Http; using NzbDrone.Common.Serializer; @@ -16,6 +15,7 @@ public interface ITraktProxy void AddToCollection(TraktCollectMoviesResource payload, string accessToken); void RemoveFromCollection(TraktCollectMoviesResource payload, string accessToken); HttpRequest BuildRequest(string resource, HttpMethod method, string accessToken); + HttpRequest BuildRequest(HttpRequest request, string accessToken); } public class TraktProxy : ITraktProxy @@ -27,12 +27,12 @@ public class TraktProxy : ITraktProxy private const string ClientId = "64508a8bf370cee550dde4806469922fd7cd70afb2d5690e3ee7f75ae784b70e"; private readonly IHttpClient _httpClient; - private readonly Logger _logger; - public TraktProxy(IHttpClient httpClient, Logger logger) + private static TimeSpan DefaultRateLimit => TimeSpan.FromSeconds(2); + + public TraktProxy(IHttpClient httpClient) { _httpClient = httpClient; - _logger = logger; } public void AddToCollection(TraktCollectMoviesResource payload, string accessToken) @@ -87,16 +87,27 @@ public HttpRequest BuildRequest(string resource, HttpMethod method, string acces { var request = new HttpRequestBuilder(URL).Resource(resource).Build(); - request.RateLimit = TimeSpan.FromSeconds(2); - request.Headers.Accept = HttpAccept.Json.Value; + request.RateLimit = DefaultRateLimit; request.Method = method; + return BuildRequest(request, accessToken); + } + + public HttpRequest BuildRequest(HttpRequest request, string accessToken) + { + if (request.RateLimit < DefaultRateLimit) + { + request.RateLimit = DefaultRateLimit; + } + + request.Headers.Accept = HttpAccept.Json.Value; + request.Headers.Add("trakt-api-version", "2"); request.Headers.Add("trakt-api-key", ClientId); if (accessToken.IsNotNullOrWhiteSpace()) { - request.Headers.Add("Authorization", "Bearer " + accessToken); + request.Headers.Add("Authorization", $"Bearer {accessToken}"); } return request; From edec432244933a2143c5d13c71de7eb210434e7b Mon Sep 17 00:00:00 2001 From: Weblate Date: Mon, 24 Feb 2025 17:27:09 +0000 Subject: [PATCH 224/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/cs.json | 9 ++++++++- src/NzbDrone.Core/Localization/Core/de.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/es.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/fi.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/fr.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/hu.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/pt_BR.json | 10 ++++++++-- src/NzbDrone.Core/Localization/Core/ru.json | 7 ++++++- src/NzbDrone.Core/Localization/Core/tr.json | 8 +++++++- 9 files changed, 59 insertions(+), 10 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 5db05932f7..6c59e0c749 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -1299,5 +1299,12 @@ "ImportListsTraktSettingsAdditionalParameters": "Dodatečné parametry", "ImportListsTraktSettingsRating": "Hodnocení", "ImportListsTraktSettingsCertification": "Osvědčení", - "ImportListsTraktSettingsGenres": "Žánry" + "ImportListsTraktSettingsGenres": "Žánry", + "DownloadClientDelugeValidationLabelPluginInactive": "Plugin pro štítky není aktivován", + "DownloadClientDelugeTorrentStateError": "Deluge hlásí chybu", + "DownloadClientDelugeSettingsDirectoryCompleted": "Adresář kam přesunout po dokončení", + "DownloadClientDelugeSettingsDirectoryHelpText": "Nepovinné - umístění stahovaných souborů, pokud ponecháte prázné, použije se výchozí umístění Deluge", + "DownloadClientDelugeSettingsDirectoryCompletedHelpText": "Nepovinné - umístění kam přesunout dokončená stahování, pokud ponecháte prázné, použije se výchozí umístění Deluge", + "DownloadClientDelugeValidationLabelPluginInactiveDetail": "Pro použití kategorií je nutné mít v {clientName} aktivovaný plugin pro štítky.", + "DownloadClientDownloadStationProviderMessage": "Pokud je ve vašem účtu DSM zapnuto dvoufázové ověření, {appName} se nebude moci připojit k Download station" } diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 974e8157b1..6878351d9b 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1903,5 +1903,10 @@ "ImportListsTraktSettingsYears": "Jahre", "ImportListsTraktSettingsAuthenticateWithTrakt": "Mit Trakt authentifizieren", "ImportListsTraktSettingsCertification": "Zertifizierung", - "ImportListsTraktSettingsLimit": "Limit" + "ImportListsTraktSettingsLimit": "Limit", + "ImportListsTraktSettingsUserListTypeCollection": "Benutzer-Sammlungs-Liste", + "ImportListsTraktSettingsUserListTypeWatch": "Benutzer-Watch-Liste", + "ImportListsTraktSettingsUserListTypeWatched": "Benutzer-Gesehene-Liste", + "ImportListsTraktSettingsWatchListSorting": "Sortierung der Gesehenen Liste", + "ImportListsTraktSettingsUserListUsernameHelpText": "Benutzername für die Liste, von der du importieren möchtest (leer lassen, um den Authentifizierten Benutzer zu verwenden)" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 248b69b28e..419fd86424 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1921,5 +1921,10 @@ "ImportListsTraktSettingsRatingMovieHelpText": "Filtrar películas por rango de calificación (0-100)", "ImportListsTraktSettingsYearsMovieHelpText": "Filtras películas por año o rango de años", "MovieRequested": "Películas solicitadas", - "ReleasePush": "Lanzamiento" + "ReleasePush": "Lanzamiento", + "ImportListsTraktSettingsUserListTypeCollection": "Lista de colecciones de usuario", + "ImportListsTraktSettingsUserListTypeWatch": "Lista de seguimiento de usuario", + "ImportListsTraktSettingsUserListTypeWatched": "Lista de vistos de usuario", + "ImportListsTraktSettingsUserListUsernameHelpText": "Usuario para la lista de la que importar (dejar vacío para usar Autenticación de usuario)", + "ImportListsTraktSettingsWatchListSorting": "Ordenar la lista de vistos" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 1d600cbd90..02365aab2c 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1922,5 +1922,10 @@ "ImportListsTraktSettingsRatingMovieHelpText": "Suodata elokuvia arvioden perusteella (alue 0–100).", "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Kaikkien aikojen katsotuimmat elokuvat", "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trendaavat elokuvat", - "ImportListsTraktSettingsGenresMovieHelpText": "Suodata elokuvia Trakt-lajityyppien slug-arvojen perusteella (pilkuin eroteltuna). Koskee vain suosituimpia listoja." + "ImportListsTraktSettingsGenresMovieHelpText": "Suodata elokuvia Trakt-lajityyppien slug-arvojen perusteella (pilkuin eroteltuna). Koskee vain suosituimpia listoja.", + "ImportListsTraktSettingsUserListTypeCollection": "Käyttäjän kokoelmat", + "ImportListsTraktSettingsUserListTypeWatch": "Käyttäjän katselulista", + "ImportListsTraktSettingsUserListTypeWatched": "Käyttäjän katseltujen lista", + "ImportListsTraktSettingsUserListUsernameHelpText": "Listan tuontiin käytettävä käyttäjänimi. Käytä tunnistautunutta käyttäjää jättämällä tyhjäksi.", + "ImportListsTraktSettingsWatchListSorting": "Katselulistan järjestys" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index f6b056b505..20e0a753b1 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1903,5 +1903,10 @@ "ImportListsTraktSettingsGenres": "Genres", "ImportListsTraktSettingsLimit": "Limite", "ImportListsTraktSettingsListType": "Type de liste", - "ImportListsTraktSettingsListTypeHelpText": "Type de liste à partir de laquelle vous cherchez à importer" + "ImportListsTraktSettingsListTypeHelpText": "Type de liste à partir de laquelle vous cherchez à importer", + "ImportListsTraktSettingsUserListTypeCollection": "Liste des collections d'utilisateurs", + "ImportListsTraktSettingsUserListUsernameHelpText": "Nom d'utilisateur pour la liste à importer (laisser vide pour utiliser Auth User)", + "ImportListsTraktSettingsWatchListSorting": "Tri de la liste de surveillance", + "ImportListsTraktSettingsUserListTypeWatch": "Liste de surveillance des utilisateurs", + "ImportListsTraktSettingsUserListTypeWatched": "Liste des utilisateurs surveillés" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 6538c90f51..95e4b2aafe 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1471,5 +1471,10 @@ "ImportListsTraktSettingsListType": "Lista típus", "ImportListsTraktSettingsListTypeHelpText": "Az importálni kívánt lista típusa", "ImportListsTraktSettingsRating": "Értékelés", - "ImportListsTraktSettingsYears": "Évek" + "ImportListsTraktSettingsYears": "Évek", + "ImportListsTraktSettingsUserListTypeCollection": "Felhasználói gyűjtőlista", + "ImportListsTraktSettingsUserListTypeWatch": "Felhasználói figyelőlista", + "ImportListsTraktSettingsUserListTypeWatched": "Felhasználói figyelt lista", + "ImportListsTraktSettingsUserListUsernameHelpText": "Felhasználónév az importálandó listához (hagyja üresen az Auth User használatához)", + "ImportListsTraktSettingsWatchListSorting": "Figyelőlista rendezése" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 7ee37ffe9b..cecd81c1b6 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1518,7 +1518,7 @@ "NotificationsEmailSettingsUseEncryptionHelpText": "Se preferir usar criptografia se configurado no servidor, usar sempre criptografia via SSL (somente porta 465) ou StartTLS (qualquer outra porta) ou nunca usar criptografia", "ChangeCategoryMultipleHint": "Altera os downloads para a \"Categoria pós-importação' do cliente de download", "BlackholeFolderHelpText": "Pasta na qual o {appName} armazenará o arquivo {extension}", - "BlackholeWatchFolder": "Pasta de monitoramento", + "BlackholeWatchFolder": "Pasta de Monitoramento", "BlackholeWatchFolderHelpText": "Pasta da qual o {appName} deve importar os downloads concluídos", "Category": "Categoria", "Destination": "Destino", @@ -1922,5 +1922,11 @@ "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Filmes Mais Assistidos de Todos os Tempos", "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Filmes em Alta", "ImportListsTraktSettingsRatingMovieHelpText": "Filtrar filmes por faixa de avaliação (0-100)", - "ImportListsTraktSettingsYearsMovieHelpText": "Filtrar filmes por ano ou faixa de ano" + "ImportListsTraktSettingsYearsMovieHelpText": "Filtrar filmes por ano ou faixa de ano", + "ImportListsTraktSettingsWatchListSortingHelpText": "Se o Tipo de Lista estiver Monitorar, selecione o pedido para classificar a lista", + "ImportListsTraktSettingsUserListTypeCollection": "Lista de coleção do usuário", + "ImportListsTraktSettingsUserListTypeWatch": "Lista para Assistir do Usuário", + "ImportListsTraktSettingsUserListTypeWatched": "Lista de Assistidos do Usuário", + "ImportListsTraktSettingsUserListUsernameHelpText": "Nome de usuário da lista a importar (deixe em branco para usar o Usuário autenticado)", + "ImportListsTraktSettingsWatchListSorting": "Classificação da Lista para Assistir" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 640cb09bce..2cc51d13c6 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1823,5 +1823,10 @@ "ImportListsTraktSettingsRating": "Рейтинг", "ImportListsTraktSettingsYears": "Годы", "ImportListsTraktSettingsAdditionalParametersHelpText": "Дополнительные параметры Trakt API", - "ImportListsTraktSettingsAuthenticateWithTrakt": "Аутентификация с помощью Trakt" + "ImportListsTraktSettingsAuthenticateWithTrakt": "Аутентификация с помощью Trakt", + "ImportListsTraktSettingsUserListTypeCollection": "Список коллекций пользователей", + "ImportListsTraktSettingsUserListTypeWatch": "Список наблюдения пользователя", + "ImportListsTraktSettingsUserListTypeWatched": "Список просмотренного пользователем", + "ImportListsTraktSettingsUserListUsernameHelpText": "Имя пользователя для импорта списка (оставьте пустым, чтобы использовать пользователя с аутентификацией)", + "ImportListsTraktSettingsWatchListSorting": "Сортировка списка просмотра" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index b5bd15e729..26b4690fbc 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1922,5 +1922,11 @@ "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trend Filmler", "ImportListsTraktSettingsRatingMovieHelpText": "Filmleri derecelendirme aralığına göre filtrele (0-100)", "ImportListsTraktSettingsYearsMovieHelpText": "Filmleri yıla veya yıl aralığına göre filtrele", - "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Aylara Göre En Çok İzlenen Filmler" + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Aylara Göre En Çok İzlenen Filmler", + "ImportListsTraktSettingsUserListTypeCollection": "Kullanıcı Koleksiyon Listesi", + "ImportListsTraktSettingsUserListTypeWatch": "Kullanıcı İzleme Listesi", + "ImportListsTraktSettingsUserListTypeWatched": "Kullanıcının İzlediği Liste", + "ImportListsTraktSettingsUserListUsernameHelpText": "İçe aktarılacak Liste için Kullanıcı Adı (Yetkili Kullanıcı için boş bırakın)", + "ImportListsTraktSettingsWatchListSorting": "İzleme Listesi Sıralaması", + "ImportListsTraktSettingsWatchListSortingHelpText": "Liste Türü İzleme ise, listeyi sıralama sırasını seçin" } From 36c66deb4b345880e64949132227d8483fc71e7c Mon Sep 17 00:00:00 2001 From: Bogdan Date: Mon, 24 Feb 2025 20:04:31 +0200 Subject: [PATCH 225/579] Recommend against using uTorrent --- src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs | 3 +++ src/NzbDrone.Core/Localization/Core/en.json | 1 + 2 files changed, 4 insertions(+) diff --git a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs index e57d55ebe0..446067cd33 100644 --- a/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs +++ b/src/NzbDrone.Core/Download/Clients/uTorrent/UTorrent.cs @@ -14,6 +14,7 @@ using NzbDrone.Core.MediaFiles.TorrentInfo; using NzbDrone.Core.Parser.Model; using NzbDrone.Core.RemotePathMappings; +using NzbDrone.Core.ThingiProvider; using NzbDrone.Core.Validation; namespace NzbDrone.Core.Download.Clients.UTorrent @@ -104,6 +105,8 @@ protected override string AddFromTorrentFile(RemoteMovie remoteMovie, string has public override string Name => "uTorrent"; + public override ProviderMessage Message => new (_localizationService.GetLocalizedString("DownloadClientUTorrentProviderMessage"), ProviderMessageType.Warning); + public override IEnumerable GetItems() { var torrents = GetTorrents(); diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index feaa288e9a..d2c29ed270 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -537,6 +537,7 @@ "DownloadClientStatusCheckSingleClientMessage": "Download clients unavailable due to failures: {downloadClientNames}", "DownloadClientTransmissionSettingsDirectoryHelpText": "Optional location to put downloads in, leave blank to use the default Transmission location", "DownloadClientTransmissionSettingsUrlBaseHelpText": "Adds a prefix to the {clientName} rpc url, eg {url}, defaults to '{defaultUrl}'", + "DownloadClientUTorrentProviderMessage": "Because uTorrent is known for cryptoware, malware and ads we'd suggest switching to a better client like qBittorrent, Deluge or ruTorrent.", "DownloadClientUTorrentTorrentStateError": "uTorrent is reporting an error", "DownloadClientUnavailable": "Download Client Unavailable", "DownloadClientValidationApiKeyIncorrect": "API Key Incorrect", From 66332a110a0f5c6e577f7a1789bad792fb1fe851 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Feb 2025 19:50:48 +0200 Subject: [PATCH 226/579] Bump version to 5.20.0 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 97127d918b..5243a66c9f 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.19.3' + majorVersion: '5.20.0' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From e8bbe0ee9f3da9d00ff9edc3060dd7501f33d290 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Tue, 25 Feb 2025 19:51:19 +0200 Subject: [PATCH 227/579] Bump Polly to 8.5.2 --- src/NzbDrone.Core/Radarr.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index d60cd3a483..a5ae1fd538 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -10,7 +10,7 @@ - + From 2aca6c6e1db9517409f54edab0834c06c899b444 Mon Sep 17 00:00:00 2001 From: Chaz Harris <16189570+Shadowalker125@users.noreply.github.com> Date: Sat, 15 Feb 2025 03:47:22 -0600 Subject: [PATCH 228/579] Bump devcontainer nodejs version to 20 (cherry picked from commit d8222c066c04d5219a21a6e7f9f3571a67e8dcca) --- .devcontainer/devcontainer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index d16b780d70..16e1da3455 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -6,7 +6,7 @@ "features": { "ghcr.io/devcontainers/features/node:1": { "nodeGypDependencies": true, - "version": "16", + "version": "20", "nvmVersion": "latest" } }, From 5959d4e51a0b62865171aeed8780daa7449ef36b Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 26 Feb 2025 03:59:22 +0200 Subject: [PATCH 229/579] Fixed: Instance name must contain application name --- .../Configuration/ConfigFileProvider.cs | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs index bb64875d78..d732334d80 100644 --- a/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs +++ b/src/NzbDrone.Core/Configuration/ConfigFileProvider.cs @@ -264,7 +264,21 @@ public string UrlBase } public string UiFolder => BuildInfo.IsDebug ? Path.Combine("..", "UI") : "UI"; - public string InstanceName => _appOptions.InstanceName ?? GetValue("InstanceName", BuildInfo.AppName); + + public string InstanceName + { + get + { + var instanceName = _appOptions.InstanceName ?? GetValue("InstanceName", BuildInfo.AppName); + + if (instanceName.Contains(BuildInfo.AppName, StringComparison.OrdinalIgnoreCase)) + { + return instanceName; + } + + return BuildInfo.AppName; + } + } public bool UpdateAutomatically => _updateOptions.Automatically ?? GetValueBoolean("UpdateAutomatically", OsInfo.IsWindows, false); From 576d404e7020fe3284fb3c7607737489123d6b40 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Thu, 27 Feb 2025 13:04:43 +0200 Subject: [PATCH 230/579] Fixed: Replace diacritics in Clean Title naming tokens --- .../OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs | 5 ++--- src/NzbDrone.Core/Organizer/FileNameBuilder.cs | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs index 9a07913439..3938e9af5d 100644 --- a/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs +++ b/src/NzbDrone.Core.Test/OrganizerTests/FileNameBuilderTests/CleanTitleFixture.cs @@ -45,7 +45,7 @@ public void Setup() } [TestCase("Florence + the Machine", "Florence + the Machine")] - [TestCase("Beyoncé X10", "Beyoncé X10")] + [TestCase("Beyoncé X10", "Beyonce X10")] [TestCase("Girlfriends' Guide to Divorce", "Girlfriends Guide to Divorce")] [TestCase("Rule #23: Never Lie to the Kids", "Rule #23 Never Lie to the Kids")] [TestCase("Anne Hathaway/Florence + The Machine", "Anne Hathaway Florence + The Machine")] @@ -70,8 +70,7 @@ public void Setup() [TestCase("Won`t Get Fooled Again", "Wont Get Fooled Again")] [TestCase("Don’t Blink", "Dont Blink")] [TestCase("The ` Legend of Kings", "The Legend of Kings")] - - // [TestCase("", "")] + [TestCase("Joker: Folie à deux", "Joker Folie a deux")] public void should_get_expected_title_back(string title, string expected) { _series.Title = title; diff --git a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs index 1e865b543d..48ae88bebb 100644 --- a/src/NzbDrone.Core/Organizer/FileNameBuilder.cs +++ b/src/NzbDrone.Core/Organizer/FileNameBuilder.cs @@ -220,7 +220,7 @@ public static string CleanTitle(string title) title = ScenifyReplaceChars.Replace(title, " "); title = ScenifyRemoveChars.Replace(title, string.Empty); - return title; + return title.RemoveDiacritics(); } public static string TitleThe(string title) From cfba047d80b568c419a07e8c4fd4210c3961a2bc Mon Sep 17 00:00:00 2001 From: Bogdan Date: Wed, 26 Feb 2025 00:24:51 +0200 Subject: [PATCH 231/579] Fixed: Parsing some titles with FRA as French --- .../ParserTests/LanguageParserFixture.cs | 2 ++ src/NzbDrone.Core/Parser/LanguageParser.cs | 14 +++++++------- src/NzbDrone.Core/Parser/Parser.cs | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs index 059542f99a..afa29523df 100644 --- a/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs +++ b/src/NzbDrone.Core.Test/ParserTests/LanguageParserFixture.cs @@ -52,6 +52,8 @@ public void should_parse_subtitle_language_english(string fileName) [TestCase("Movie Title : Other Title 2010 x264.720p.Blu-ray Rip HD.VOSTFR.VFF. ONLY")] [TestCase("Movie Title 2019 HEVC.2160p.Blu-ray 4K.VOSTFR.VFF. JATO")] [TestCase("Movie.Title.1956.MULTi.VF.Bluray.1080p.REMUX.AC3.x264")] + [TestCase("Movie.Title.2016.ENG-ITA-FRA.AAC.1080p.WebDL.x264")] + [TestCase("Movie Title 2016 (BDrip 1080p ENG-ITA-FRA) Multisub x264")] [TestCase("Movie.Title.2016.ENG-ITA-FRE.AAC.1080p.WebDL.x264")] [TestCase("Movie Title 2016 (BDrip 1080p ENG-ITA-FRE) Multisub x264")] public void should_parse_language_french(string postTitle) diff --git a/src/NzbDrone.Core/Parser/LanguageParser.cs b/src/NzbDrone.Core/Parser/LanguageParser.cs index fd4ebe9ca3..006ffea990 100644 --- a/src/NzbDrone.Core/Parser/LanguageParser.cs +++ b/src/NzbDrone.Core/Parser/LanguageParser.cs @@ -15,7 +15,8 @@ public static class LanguageParser { private static readonly Logger Logger = NzbDroneLogger.GetLogger(typeof(LanguageParser)); - private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_|^)(?\b(?:ita|italian)\b)| + private static readonly Regex LanguageRegex = new Regex(@"(?:\W|_|^)(?\beng\b)| + (?\b(?:ita|italian)\b)| (?german\b|videomann|ger[. ]dub|\bger\b)| (?flemish)| (?bgaudio)| @@ -24,7 +25,6 @@ public static class LanguageParser (?greek)| (?\b(?:FR|VO|VF|VFF|VFQ|VFI|VF2|TRUEFRENCH|FRENCH|FRE|FRA)\b)| (?\b(?:rus|ru)\b)| - (?\beng\b)| (?\b(?:HUNDUB|HUN)\b)| (?\b(?:HebDub|HebDubbed)\b)| (?\b(?:PL\W?DUB|DUB\W?PL|LEK\W?PL|PL\W?LEK)\b)| @@ -297,6 +297,11 @@ public static List ParseLanguages(string title) foreach (Match match in matches) { + if (match.Groups["english"].Success) + { + languages.Add(Language.English); + } + if (match.Groups["italian"].Captures.Any()) { languages.Add(Language.Italian); @@ -327,11 +332,6 @@ public static List ParseLanguages(string title) languages.Add(Language.Russian); } - if (match.Groups["english"].Success) - { - languages.Add(Language.English); - } - if (match.Groups["bulgarian"].Success) { languages.Add(Language.Bulgarian); diff --git a/src/NzbDrone.Core/Parser/Parser.cs b/src/NzbDrone.Core/Parser/Parser.cs index 3badfc6977..c9f4668d29 100644 --- a/src/NzbDrone.Core/Parser/Parser.cs +++ b/src/NzbDrone.Core/Parser/Parser.cs @@ -142,7 +142,7 @@ public static class Parser private static readonly Regex CleanQualityBracketsRegex = new Regex(@"\[[a-z0-9 ._-]+\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); - private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", + private static readonly Regex ReleaseGroupRegex = new Regex(@"-(?[a-z0-9]+(?-[a-z0-9]+)?(?!.+?(?:480p|576p|720p|1080p|2160p)))(?\d+)|(?tt\d{7,8}))(?:\k)?)(?:\b|[-._ ]|$)|[-._ ]\[(?[a-z0-9]+)\]$", RegexOptions.IgnoreCase | RegexOptions.Compiled); private static readonly Regex InvalidReleaseGroupRegex = new Regex(@"^([se]\d+|[0-9a-f]{8})$", RegexOptions.IgnoreCase | RegexOptions.Compiled); From 22b5739967eba72b99e074b97b3a2420b5da0570 Mon Sep 17 00:00:00 2001 From: Weblate Date: Tue, 4 Mar 2025 04:33:27 +0000 Subject: [PATCH 232/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Eduardo045 Co-authored-by: Gallyam Biktashev Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Oskari Lavinto Co-authored-by: Volodymyr Co-authored-by: Weblate Co-authored-by: corwin007x Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 4 +- src/NzbDrone.Core/Localization/Core/pt.json | 3 +- .../Localization/Core/pt_BR.json | 3 +- src/NzbDrone.Core/Localization/Core/ru.json | 194 +++++++++++++----- src/NzbDrone.Core/Localization/Core/tr.json | 5 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- 7 files changed, 159 insertions(+), 54 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 6c59e0c749..5922d51392 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -372,7 +372,7 @@ "BypassProxyForLocalAddresses": "Obcházení proxy serveru pro místní adresy", "MovieIsUnmonitored": "Film není sledován", "Movies": "Filmy", - "MoviesSelectedInterp": "{0} Vybrané filmy", + "MoviesSelectedInterp": "{count} Vybraných Filmů", "MovieTitle": "Název filmu", "MovieTitleToExcludeHelpText": "Název filmu, který se má vyloučit (může mít cokoli smysluplného)", "MovieYear": "Filmový rok", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 02365aab2c..15bc47af66 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1927,5 +1927,7 @@ "ImportListsTraktSettingsUserListTypeWatch": "Käyttäjän katselulista", "ImportListsTraktSettingsUserListTypeWatched": "Käyttäjän katseltujen lista", "ImportListsTraktSettingsUserListUsernameHelpText": "Listan tuontiin käytettävä käyttäjänimi. Käytä tunnistautunutta käyttäjää jättämällä tyhjäksi.", - "ImportListsTraktSettingsWatchListSorting": "Katselulistan järjestys" + "ImportListsTraktSettingsWatchListSorting": "Katselulistan järjestys", + "DownloadClientUTorrentProviderMessage": "Koska uTorrent on tunnettu crypto-, haitta- and mainossisällöstä ja sovelluksista, suosittelemme esimerkiksi qBittorrentin, Delugen ja ruTorrentin kaltaisia parempia sovelluksia.", + "ImportListsTraktSettingsWatchListSortingHelpText": "Jos lista on katslutyyppinen, valitse sen järjestystapa." } diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 87827f51ca..5106914c58 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -1278,5 +1278,6 @@ "Mixed": "Corrigido", "ImportListsTraktSettingsCertification": "Certificação", "ImportListsTraktSettingsGenres": "Gêneros", - "ImportListsTraktSettingsRating": "Classificação" + "ImportListsTraktSettingsRating": "Classificação", + "AutoTaggingSpecificationGenre": "Gênero(s)" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index cecd81c1b6..5cad35f503 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1928,5 +1928,6 @@ "ImportListsTraktSettingsUserListTypeWatch": "Lista para Assistir do Usuário", "ImportListsTraktSettingsUserListTypeWatched": "Lista de Assistidos do Usuário", "ImportListsTraktSettingsUserListUsernameHelpText": "Nome de usuário da lista a importar (deixe em branco para usar o Usuário autenticado)", - "ImportListsTraktSettingsWatchListSorting": "Classificação da Lista para Assistir" + "ImportListsTraktSettingsWatchListSorting": "Classificação da Lista para Assistir", + "DownloadClientUTorrentProviderMessage": "Como o uTorrent é conhecido por CryptoWare, malware e anúncios, sugerimos mudar para um cliente melhor como Qbittorrent, Deluge ou ruTorrent." } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 2cc51d13c6..8768d6750c 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -359,7 +359,7 @@ "ReleaseBranchCheckOfficialBranchMessage": "Ветвь {0} не является действительной релизной ветвью {appName}, вы не будете получать обновления", "RelativePath": "Относительный путь", "RejectionCount": "Количество отказов", - "RegularExpressionsCanBeTested": "Регулярные выражения можно проверить.", + "RegularExpressionsCanBeTested": "Регулярные выражения можно проверить [тут]({url}).", "RefreshMovie": "Обновить фильм", "RefreshLists": "Обновить листы", "RefreshInformationAndScanDisk": "Обновить информацию и просканировать диск", @@ -565,7 +565,7 @@ "Max": "Максимально", "MassMovieSearch": "Массовый поиск фильмов", "LookingForReleaseProfiles1": "Ищите профили релизов? Попробуйте", - "ImportExtraFilesMovieHelpText": "Импортировать совпадающие экстра файлы (субтитры, nfo, и т.д.) после импорта фильма", + "ImportExtraFilesMovieHelpText": "Импортировать подходящие экстра файлы (субтитры, nfo, и т.д.) после импорта фильма", "ImportedTo": "Импортировано в", "Imported": "Импортировано", "HardlinkCopyFiles": "Жесткая ссылка/Копирование файлов", @@ -947,7 +947,7 @@ "SqliteVersionCheckUpgradeRequiredMessage": "Установленная в настоящее время версия SQLite {0} больше не поддерживается. Обновите SQLite как минимум до версии {1}.", "ShowCinemaRelease": "Дата выхода шоу в кинотеатре", "ShowReleaseDate": "Показать дату выпуска", - "ShowReleaseDateHelpText": "Показать дату выпуска под плакатом", + "ShowReleaseDateHelpText": "Показывает дату выпуска под постером. Дата вычисляется по настройке минимальной доступности", "OnMovieDelete": "При удалении фильма", "OnMovieFileDelete": "При удалении файла фильма", "OnMovieFileDeleteForUpgrade": "При удалении файла фильма для обновления", @@ -1231,56 +1231,56 @@ "AddAutoTagError": "Не удалось добавить новый авто тег, пожалуйста повторите попытку.", "AddDelayProfileError": "Не удалось добавить новый профиль задержки. Повторите попытку.", "AutoRedownloadFailed": "Повторная загрузка не удалась", - "DelayingDownloadUntil": "Приостановить скачивание до {date} в {time}", + "DelayingDownloadUntil": "Скачивание приостановлено до {date} в {time}", "AutoTaggingSpecificationTag": "Тэг", - "Directory": "Каталог", + "Directory": "Папка", "IncludeHealthWarnings": "Включить предупреждения о здоровье", "DeletedReasonUpgrade": "Файл был удален чтобы импортировать обновление", "HistoryLoadError": "Не удалось загрузить историю", "QueueLoadError": "Не удалось загрузить очередь", - "GrabId": "Захватить ID", + "GrabId": "ID загрузки", "OrganizeLoadError": "Ошибка при загрузке предпросмотра", - "OrganizeNothingToRename": "Успешно! Моя работа завершена, файлов для переименования нет.", + "OrganizeNothingToRename": "Успех! Моя работа завершена, файлов для переименования нет.", "RetryingDownloadOn": "Повторная попытка загрузки {date} в {time}", "TablePageSizeHelpText": "Количество элементов, отображаемых на каждой странице", "TablePageSize": "Размер страницы", - "ConnectionLostReconnect": "{appName} попытается соединиться автоматически или нажмите кнопку ниже.", + "ConnectionLostReconnect": "{appName} попытается соединиться автоматически, либо нажмите кнопку ниже.", "ConnectionLostToBackend": "{appName} потерял связь с сервером и его необходимо перезагрузить, чтобы восстановить работоспособность.", "BlocklistLoadError": "Не удалось загрузить черный список", "InteractiveSearchModalHeader": "Интерактивный поиск", "Lists": "Списки", "RemoveSelectedBlocklistMessageText": "Вы уверены, что хотите удалить выбранные элементы из черного списка?", - "RestartLater": "Перезапущу позднее", + "RestartLater": "Перезапущусь позднее", "FormatAgeHours": "часы", "FormatAgeMinutes": "минуты", "Yes": "Да", "NotificationsSimplepushSettingsEvent": "Событие", - "CustomFilter": "Настраиваемый фильтр", + "CustomFilter": "Пользовательский фильтр", "MustContainHelpText": "Релиз должен содержать хотя бы одно из этих условий (без учета регистра)", - "MustNotContainHelpText": "Релиз будет не принят, если он содержит один или несколько терминов (регистрозависимы)", + "MustNotContainHelpText": "Релиз не будет принят, если он содержит один или несколько терминов (регистрозависимы)", "No": "Нет", "Label": "Метка", "DelayProfileMovieTagsHelpText": "Применимо к фильмам с хотя бы одним подходящим тегом", "Release": "Релиз", "DeletedReasonMovieMissingFromDisk": "{appName} не смог найти файл на диске, поэтому файл был откреплён от фильма в базе данных", "MovieIsNotMonitored": "Фильм не отслеживается", - "MovieFileDeleted": "При удалении файла фильма", + "MovieFileDeleted": "Файл фильма удалён", "DeleteReleaseProfile": "Удалить профиль релиза", "DeleteReleaseProfileMessageText": "Вы действительно хотите удалить профиль релиза '{name}'?", "DownloadClientSettingsRecentPriority": "Недавний приоритет", - "ReleaseGroups": "Релиз группы", + "ReleaseGroups": "Релиз-группы", "ReleaseProfilesLoadError": "Невозможно загрузить профили релиза", "FormatAgeHour": "час", "FormatAgeMinute": "минута", - "AddRootFolderError": "Невозможно загрузить корневую папку", + "AddRootFolderError": "Не удалось добавить корневую папку", "IndexerSettingsMultiLanguageRelease": "Несколько языков", - "DeleteSpecification": "Удалить уведомление", - "DeleteSpecificationHelpText": "Вы уверены, что хотите удалить уведомление '{name}'?", - "MovieFileDeletedTooltip": "При удалении файла фильма", + "DeleteSpecification": "Удалить спецификацию", + "DeleteSpecificationHelpText": "Вы уверены, что хотите удалить спецификацию '{name}'?", + "MovieFileDeletedTooltip": "Файл фильма удалён", "DeleteMovieFolderCountConfirmation": "Вы уверены, что хотите удалить {count} выбранных индексатора?", - "DeleteMovieFolders": "Удалить папку фильма", - "DeleteMovieFoldersHelpText": "Удалить папку и её содержимое", - "DeleteSelectedMovies": "Удалить выбранные файлы фильма", + "DeleteMovieFolders": "Удалить папки фильма", + "DeleteMovieFoldersHelpText": "Удаляет папки фильма и все их содержимое", + "DeleteSelectedMovies": "Удалить выбранные фильмы", "AppUpdated": "{appName} обновлён", "AppUpdatedVersion": "{appName} обновлён до версии `{version}`, для получения последних изменений необходимо перезагрузить {appName}", "CustomFormatJson": "Настраиваемый формат JSON", @@ -1626,25 +1626,25 @@ "Any": "Любой", "NotificationsGotifySettingsAppToken": "Токен приложения", "NotificationsEmailSettingsServer": "Сервер", - "ReleaseGroupFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Release Group:30}`), так и с начала (например, `{Release Group:-30}`).`).", - "SearchForCutoffUnmetMoviesConfirmationCount": "Вы уверены, что хотите найти все {totalRecords}, не достигшие указанного качества эпизоды ?", + "ReleaseGroupFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Release Group:30}`), так и с начала (например, `{Release Group:-30}`).", + "SearchForCutoffUnmetMoviesConfirmationCount": "Вы уверены, что хотите найти все {totalRecords}, фильмы не достигшие максимального качества?", "ShowTags": "Показать теги", - "ShowTagsHelpText": "Показать теги под постером", + "ShowTagsHelpText": "Показывать теги под постером", "MovieFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Movie Title:30}`), так и с начала (например, `{Movie Title:-30}`).", - "DownloadClientSettingsRecentPriorityMovieHelpText": "Приоритет при выборе эпизодов, вышедших в эфир за последние 14 дней", - "MovieFolderFormatHelpText": "Используется при добавлении или перемещении новых сериалов через редактор", - "NotificationsTagsMovieHelpText": "Отправляйте уведомления только для сериалов, у которых есть хотя бы один соответствующий тег", - "ShowUnknownMovieItemsHelpText": "Показывать элементы без сериалов в очереди, это могут быть удаленные сериалы, фильмы или что-либо еще в категории {appName}", + "DownloadClientSettingsRecentPriorityMovieHelpText": "Приоритет при выборе фильмов, вышедших в эфир за последние 3 недели", + "MovieFolderFormatHelpText": "Используется при добавлении или перемещении фильмов через редактор", + "NotificationsTagsMovieHelpText": "Отправлять уведомления только для тех фильмов, у которых есть хотя бы один соответствующий тег", + "ShowUnknownMovieItemsHelpText": "Показывать элементы без фильмов в очереди. Это могут быть удаленные фильмы или что-либо еще в категории {appName}", "NotificationsJoinSettingsDeviceIds": "ID устройств", - "MovieImportedTooltip": "Эпизод успешно загружен и получен из загрузочного клиента", + "MovieImportedTooltip": "Фильм успешно загружен и получен из загрузочного клиента", "EditionFootNote": "При необходимости можно управлять обрезкой до максимального количества байтов, включая многоточие (`...`). Поддерживается обрезка как с конца (например, `{Edition Tags:30}`), так и с начала (например, `{Edition Tags:-30}`).", "NotificationsCustomScriptValidationFileDoesNotExist": "Файл не существует", "NotificationsGotifySettingsServerHelpText": "URL-адрес сервера Gotify, включая http(s):// и порт, если необходимо", "MovieGrabbedTooltip": "Эпизод получен из {indexer} и отправлен в {downloadClient}", - "NotificationsPlexValidationNoMovieLibraryFound": "Требуется хотя бы одна библиотека c сериалами", - "SearchForAllMissingMovies": "Искать все недостающие эпизоды", - "SearchForAllMissingMoviesConfirmationCount": "Вы уверены, что хотите найти все ({totalRecords}) недостающие эпизоды ?", - "SearchForCutoffUnmetMovies": "Искать все эпизоды не достигшие указанного качества", + "NotificationsPlexValidationNoMovieLibraryFound": "Требуется хотя бы одна библиотека c фильмами", + "SearchForAllMissingMovies": "Искать все недостающие фильмы", + "SearchForAllMissingMoviesConfirmationCount": "Вы уверены, что хотите найти все ({totalRecords}) недостающие фильмы?", + "SearchForCutoffUnmetMovies": "Искать все фильмы не достигшие максимального качества", "FormatShortTimeSpanSeconds": "{seconds} секунд(ы)", "FormatTimeSpanDays": "{days}d {time}", "InfoUrl": "URL-адрес информации", @@ -1750,28 +1750,28 @@ "Space": "Пробел", "TorrentBlackhole": "Blackhole торрент", "RestartRequiredToApplyChanges": "Для применения изменений {appName} требуется перезагрузка. Перезагрузить сейчас?", - "ReleaseProfileTagMovieHelpText": "Профили релиза будут применяться к сериалам, имеющим хотя бы один соответствующий тег. Оставьте поле пустым, чтобы применить ко всем", - "NotificationsGotifySettingIncludeMoviePoster": "Включая постер сериала", - "NotificationsGotifySettingIncludeMoviePosterHelpText": "Включить постер сериала в сообщение", - "DeleteSelectedImportListExclusionsMessageText": "Вы уверены, что хотите удалить это исключение из списка импорта?", + "ReleaseProfileTagMovieHelpText": "Профили релиза будут применяться к фильмам, имеющим хотя бы один соответствующий тег. Оставьте поле пустым, чтобы применить ко всем", + "NotificationsGotifySettingIncludeMoviePoster": "Добавить постер сериала", + "NotificationsGotifySettingIncludeMoviePosterHelpText": "Добавляет постер сериала в сообщение", + "DeleteSelectedImportListExclusionsMessageText": "Вы уверены, что хотите удалить выбранные исключения списка импорта?", "ProgressBarProgress": "Индикатор выполнения: {progress}%", - "DeleteSelectedCustomFormatsMessageText": "Вы уверены, что хотите удалить {count} выбранных списков импорта?", + "DeleteSelectedCustomFormatsMessageText": "Вы уверены, что хотите удалить {count} выбранных пользовательских форматов?", "DeleteSelectedCustomFormats": "Удалить пользовательский формат", "CountVotes": "{votes} голосов", "ReleaseDate": "Дата выпуска", "ShowDigitalRelease": "Показывать дату выхода цифрового релиза", - "ShowDigitalReleaseHelpText": "Показывать дату выхода фильма под изображением", + "ShowDigitalReleaseHelpText": "Показывать дату выхода фильма в цифре под изображением", "ShowPhysicalRelease": "Дата релиза на носителе", - "ShowPhysicalReleaseHelpText": "Показывать дату выхода фильма под изображением", + "ShowPhysicalReleaseHelpText": "Показывать дату выхода фильма на физическом носителе под изображением", "DayOfWeekAt": "{day} в {time}", - "TodayAt": "Сегодня в{time}", + "TodayAt": "Сегодня в {time}", "TomorrowAt": "Завтра в {time}", "YesterdayAt": "Вчера в {time}", "Logout": "Завершить сеанс", "Menu": "Меню", "LogSizeLimit": "Ограничение размера журнала", "LogSizeLimitHelpText": "Максимальный размер файла журнала в МБ перед архивированием. По умолчанию - 1 МБ.", - "ShowTraktRatingPosterHelpText": "Показать рейтинг Tomato под постером", + "ShowTraktRatingPosterHelpText": "Показывать рейтинг Tomato под постером", "SmartReplace": "Умная замена", "SmartReplaceHint": "Тире или пробел в зависимости от имени", "FolderNameTokens": "Токены имени файла", @@ -1797,7 +1797,7 @@ "AutoTaggingSpecificationMinimumYear": "Минимальный год", "AutoTaggingSpecificationOriginalLanguage": "Язык", "AutoTaggingSpecificationQualityProfile": "Профиль качества", - "AutoTaggingSpecificationRootFolder": "Корневой каталог", + "AutoTaggingSpecificationRootFolder": "Корневая папка", "AutoTaggingSpecificationStatus": "Статус", "CustomFormatsSpecificationLanguage": "Язык", "CustomFormatsSpecificationMaximumSize": "Максимальный размер", @@ -1807,7 +1807,7 @@ "CustomFormatsSpecificationMinimumSizeHelpText": "Релиз должен быть больше этого размера", "CustomFormatsSpecificationMinimumYear": "Минимальный год", "CustomFormatsSpecificationResolution": "Разрешение", - "CustomFormatsSpecificationSource": "Исходный код", + "CustomFormatsSpecificationSource": "Источник", "CustomFormatsSpecificationExceptLanguageHelpText": "Подходит, если есть любой язык кроме указанного", "Mixed": "Смешанный", "MediaInfoFootNote2": "MediaInfo AudioLanguages не добавляет английский язык, если это единственный доступный язык. Используйте MediaInfo AudioLanguagesAll для добавления английского языка в таких случаях", @@ -1824,9 +1824,109 @@ "ImportListsTraktSettingsYears": "Годы", "ImportListsTraktSettingsAdditionalParametersHelpText": "Дополнительные параметры Trakt API", "ImportListsTraktSettingsAuthenticateWithTrakt": "Аутентификация с помощью Trakt", - "ImportListsTraktSettingsUserListTypeCollection": "Список коллекций пользователей", - "ImportListsTraktSettingsUserListTypeWatch": "Список наблюдения пользователя", + "ImportListsTraktSettingsUserListTypeCollection": "Список коллекций пользователя", + "ImportListsTraktSettingsUserListTypeWatch": "Список \"Буду смотреть\" пользователя", "ImportListsTraktSettingsUserListTypeWatched": "Список просмотренного пользователем", - "ImportListsTraktSettingsUserListUsernameHelpText": "Имя пользователя для импорта списка (оставьте пустым, чтобы использовать пользователя с аутентификацией)", - "ImportListsTraktSettingsWatchListSorting": "Сортировка списка просмотра" + "ImportListsTraktSettingsUserListUsernameHelpText": "Имя пользователя для списка импорта (оставьте пустым, чтобы использовать текущего пользователя)", + "ImportListsTraktSettingsWatchListSorting": "Сортировка списка просмотра", + "DownloadFailedMovieTooltip": "Ошибка загрузки фильма", + "DownloadIgnoredMovieTooltip": "Загрузка фильма не отслеживается", + "OrganizeNamingPattern": "Шаблон именования: `{standardMovieFormat}`", + "ReleaseSource": "Источник релиза", + "ImportListsTraktSettingsCertificationMovieHelpText": "Фильтровать фильмы по возрастному рейтингу (NR,G,PG,PG-13,R,NC-17) ( разделитель - запятая)", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Рекомендованные фильмы за все время", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Наиболее просматриваемые фильмы по неделям", + "ImportListsTraktSettingsWatchListSortingHelpText": "Если тип списка - Буду смотреть, выбирает способ сортировки списка", + "InvalidMovieInfoLanguageLanguage": "Установлен некорректный язык информации о фильмах. Исправьте его и сохраните настройки", + "SearchMoviesConfirmationMessageText": "Вы уверены, что хотите запустить поиск {count} фильма(ов)?", + "InteractiveSearchModalHeaderTitle": "Интерактивный поиск - {title}", + "MetadataSettingsMovieMetadataNfo": "Использовать movie.nfo", + "NotificationsGotifySettingsMetadataLinksMovieHelpText": "Добавляет ссылки на метаданные фильма при отправке уведомлений", + "NotificationsGotifySettingsPreferredMetadataLink": "Предпочтительная ссылка на метаданные", + "MetadataKometaDeprecated": "Файлы Kometa больше не будут создаваться, поддержка будет полностью удалена в v6", + "NoMovieReleaseDatesAvailable": "Даты релиза для фильма не найдены на [TMDb]({url}).", + "QualityCutoffNotMet": "Максимальное качество не достигнуто", + "UserInvokedSearch": "Вызванный пользователем поиск", + "WhySearchesCouldBeFailing": "Нажмите здесь, чтобы найти причину ошибок писка", + "MovieMissingFromDisk": "Фильм отсутствует на диске", + "Disposition": "Расположение", + "NotificationsSettingsWebhookHeaders": "Заголовки", + "NotificationsTelegramSettingsIncludeInstanceName": "Добавлять имя сервера в заголовок", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "Добавляет имя текущего сервера Radarr в уведомления", + "NotificationsTelegramSettingsMetadataLinks": "Ссылки на метаданные", + "NotificationsTelegramSettingsMetadataLinksMovieHelpText": "Добавляет ссылки на метаданные фильма при отправке уведомлений", + "ReleasedMovieAvailabilityDescription": "Фильмы считаются доступными при появлении на Blu-Ray или в онлайн-кинотеатрах.", + "SkipFreeSpaceCheckHelpText": "Используете, когда {appName} не может верно определить свободное место в вашей корневой папке", + "TraktRating": "Рейтинг в Trakt", + "TraktVotes": "Голосов в Trakt", + "Trending": "Набирающие популярность", + "NoExtraFilesToManage": "Нет дополнительных файлов для управления.", + "Popular": "Популярные", + "ImportListsTraktSettingsGenresMovieHelpText": "Фильтровать фильмы по жанру в Trakt только для популярных списков (разделитель - запятая)", + "ImportListsTraktSettingsLimitMovieHelpText": "Ограничивает количество фильмов для получения", + "ImportListsTraktSettingsPopularListTypePopularMovies": "Популярные фильмы", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Рекомендованные фильмы по месяцам", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Набирающие популярность фильмы", + "ImportListsTraktSettingsRatingMovieHelpText": "Фильтрует фильмы по диапазону рейтинга (0-100)", + "IncludePopular": "Учитывать популярные", + "MetadataXmbcSettingsMovieMetadataUrlHelpText": "Добавлять ссылки на TMDb и IMDb в .nfo", + "MinimumCustomFormatScoreIncrement": "Минимальное увеличение оценки пользовательских форматов", + "MovieImported": "Фильм импортирован", + "MovieIsNotAvailable": "Фильм недоступен", + "MovieIsTrending": "Набирающий популярность фильм на TMDb", + "NewNonExcluded": "Новый не исключённый", + "NoBlocklistItems": "Нет заблокированных элементов", + "NoMovieFilesToManage": "Нет файлов фильма для управления.", + "NotificationsGotifySettingsMetadataLinks": "Ссылки на метаданные", + "NotificationsGotifySettingsPreferredMetadataLinkHelpText": "Ссылка на метаданные для клиентов с поддержкой единственной ссылки", + "OnExcludedList": "В списке исключений", + "Recommendation": "Рекомендация", + "SearchMoviesOnAdd": "Искать фильмы при добавлении", + "Warning": "Предупреждение", + "MetadataXmbcSettingsMovieMetadataCollectionNameHelpText": "Включает имя коллекции в .nfo", + "MetadataXmbcSettingsMovieMetadataHelpText": ".nfo с полными метаданными формами", + "MetadataXmbcSettingsMovieMetadataLanguageHelpText": "Включает выбранный язык в .nfo (если данные по языку доступны)", + "MovieDownloaded": "Фильм загружен", + "MovieIsPopular": "Популярный фильм на TMDb", + "AutoTaggingSpecificationMaximumRuntime": "Максимальное время исполнения", + "CustomFormatsSpecificationQualityModifier": "Модификатор качества", + "CutoffUnmetNoItems": "Нет элементов не достигших максимального качества", + "IncludePopularMoviesHelpText": "Добавляет популярные фильмы из TMDb", + "ShowTraktRating": "Показывать рейтинг в Trakt", + "MovieRequested": "Фильм запрошен", + "NoCustomFormatsFound": "Нет пользовательских форматов", + "DownloadClientUTorrentProviderMessage": "Мы советуем использовать клиенты вроде qBittorrent, Deluge или ruTorrent, т.к. uTorrent известен как программа-шифровальщик и в целом вредоносное ПО.", + "ExistsInLibrary": "Существует в библиотеке", + "Fallback": "Резервный", + "FavoriteFolderAdd": "Добавить избранную папку", + "FavoriteFolderRemove": "Удалить избранную папку", + "FavoriteFolders": "Избранные папки", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Рекомендованные фильмы по неделям", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Рекомендованные фильмы по годам", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Наиболее ожидаемые фильмы", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Фильмы с наибольшими кассовыми сборами", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Наиболее просматриваемые фильмы по месяцам", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Наиболее просматриваемые фильмы по годам", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Наиболее просматриваемые фильмы за все время", + "ImportListsTraktSettingsYearsMovieHelpText": "Фильтрует фильмы по году или диапазону лет", + "InCinemasMovieAvailabilityDescription": "Фильмы считаются доступными как только они выходят в кинотеатрах.", + "IncludeTrending": "Учитывать набирающие популярность", + "IncludeTrendingMoviesHelpText": "Добавляет набирающие популярность фильм на TMDb", + "LastSearched": "Искали недавно", + "ManageFiles": "Управлять файлами", + "ManageFormats": "Управлять форматами", + "ManageCustomFormats": "Управлять пользовательскими форматами", + "MetadataKometaDeprecatedSetting": "Устаревшее", + "MetadataSettingsMovieImages": "Изображения фильма", + "MetadataSettingsMovieMetadata": "Метаданные фильма", + "MetadataSettingsMovieMetadataCollectionName": "Имя коллекции фильма", + "MetadataSettingsMovieMetadataLanguage": "Язык метаданных фильма", + "MetadataSettingsMovieMetadataUrl": "URL метаданных фильма", + "MetadataXmbcSettingsMovieMetadataNfoHelpText": "Записывает метаданные в movie.nfo вместо стандартного <имя-фильма>.nfo", + "MinimumCustomFormatScoreIncrementHelpText": "Минимальное изменение оценки пользовательских форматов между существующим и новым релизом, чтобы {appName} считал это улучшением", + "MovieFileMissingTooltip": "Файл фильма отсутствует", + "MovieFileRenamed": "Файл фильма переименован", + "MovieFileRenamedTooltip": "Файл фильма переименован", + "MovieFolderImportedTooltip": "Фильм импортирован из папки фильма", + "Recommended": "Рекомендуемое" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 26b4690fbc..55be7f9401 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -756,7 +756,7 @@ "IconForCutoffUnmet": "Sınırlandırılmamış için Simge", "Ignored": "Yok sayıldı", "IgnoredAddresses": "Yoksayılan Adresler", - "IgnoreDeletedMovies": "Silinen Filmlerin takibini Kaldır", + "IgnoreDeletedMovies": "Silinen Filmlerin Takibini Kaldır", "IgnoredHelpText": "Bir veya daha fazla terim içeriyorsa izin reddedilecektir (büyük / küçük harfe duyarlı değildir)", "Images": "Görüntüler", "IMDb": "IMDb", @@ -1928,5 +1928,6 @@ "ImportListsTraktSettingsUserListTypeWatched": "Kullanıcının İzlediği Liste", "ImportListsTraktSettingsUserListUsernameHelpText": "İçe aktarılacak Liste için Kullanıcı Adı (Yetkili Kullanıcı için boş bırakın)", "ImportListsTraktSettingsWatchListSorting": "İzleme Listesi Sıralaması", - "ImportListsTraktSettingsWatchListSortingHelpText": "Liste Türü İzleme ise, listeyi sıralama sırasını seçin" + "ImportListsTraktSettingsWatchListSortingHelpText": "Liste Türü İzleme ise, listeyi sıralama sırasını seçin", + "DownloadClientUTorrentProviderMessage": "uTorrent, kripto yazılımlar, kötü amaçlı yazılımlar ve reklamlarla tanındığı için qBittorrent, Deluge veya ruTorrent gibi daha iyi bir istemciye geçmenizi öneririz." } diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 8c3967899b..eef5500054 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -105,7 +105,7 @@ "All": "Всі", "AllFiles": "Всі файли", "AllMoviesHiddenDueToFilter": "Всі фільми заховані відповідно до фільтра.", - "AllMoviesInPathHaveBeenImported": "Усі фільми з {0} імпортовано", + "AllMoviesInPathHaveBeenImported": "Усі фільми з {path} імпортовано", "AllowHardcodedSubs": "Дозволити вбудовані підписки", "AllowHardcodedSubsHelpText": "Виявлені вбудовані підписки будуть завантажені автоматично", "AllResultsHiddenFilter": "Всі результати приховані фільтром", From 95da7d7b47fdd3ee875431839e729f8c56f968cd Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 2 Mar 2025 21:24:29 +0200 Subject: [PATCH 233/579] Convert Interactive Search to TypeScript --- frontend/src/App/State/AppState.ts | 6 + .../src/App/State/MovieBlocklistAppState.ts | 6 + .../src/App/State/MovieHistoryAppState.ts | 6 + frontend/src/App/State/ReleasesAppState.ts | 10 + frontend/src/Components/Table/Column.ts | 2 + .../InteractiveSearch/InteractiveSearch.js | 240 ---------------- .../InteractiveSearch/InteractiveSearch.tsx | 263 ++++++++++++++++++ .../InteractiveSearchConnector.js | 109 -------- .../InteractiveSearchFilterModal.tsx | 55 ++++ .../InteractiveSearchFilterModalConnector.js | 29 -- .../InteractiveSearchPayload.ts | 7 + .../InteractiveSearchRow.tsx | 149 +++++----- .../InteractiveSearchRowConnector.js | 62 ----- .../InteractiveSearch/{Peers.js => Peers.tsx} | 27 +- .../Movie/Details/MovieDetailsConnector.js | 22 -- .../Search/MovieInteractiveSearchModal.tsx | 5 + .../MovieInteractiveSearchModalContent.tsx | 9 +- frontend/src/typings/Release.ts | 35 +++ src/NzbDrone.Core/Localization/Core/en.json | 3 + 19 files changed, 500 insertions(+), 545 deletions(-) create mode 100644 frontend/src/App/State/MovieBlocklistAppState.ts create mode 100644 frontend/src/App/State/MovieHistoryAppState.ts create mode 100644 frontend/src/App/State/ReleasesAppState.ts delete mode 100644 frontend/src/InteractiveSearch/InteractiveSearch.js create mode 100644 frontend/src/InteractiveSearch/InteractiveSearch.tsx delete mode 100644 frontend/src/InteractiveSearch/InteractiveSearchConnector.js create mode 100644 frontend/src/InteractiveSearch/InteractiveSearchFilterModal.tsx delete mode 100644 frontend/src/InteractiveSearch/InteractiveSearchFilterModalConnector.js create mode 100644 frontend/src/InteractiveSearch/InteractiveSearchPayload.ts delete mode 100644 frontend/src/InteractiveSearch/InteractiveSearchRowConnector.js rename frontend/src/InteractiveSearch/{Peers.js => Peers.tsx} (68%) create mode 100644 frontend/src/typings/Release.ts diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index f33fcc6920..82dcc9341b 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -3,13 +3,16 @@ import CalendarAppState from './CalendarAppState'; import CommandAppState from './CommandAppState'; import HistoryAppState from './HistoryAppState'; import InteractiveImportAppState from './InteractiveImportAppState'; +import MovieBlocklistAppState from './MovieBlocklistAppState'; import MovieCollectionAppState from './MovieCollectionAppState'; import MovieCreditAppState from './MovieCreditAppState'; import MovieFilesAppState from './MovieFilesAppState'; +import MovieHistoryAppState from './MovieHistoryAppState'; import MoviesAppState, { MovieIndexAppState } from './MoviesAppState'; import ParseAppState from './ParseAppState'; import PathsAppState from './PathsAppState'; import QueueAppState from './QueueAppState'; +import ReleasesAppState from './ReleasesAppState'; import RootFolderAppState from './RootFolderAppState'; import SettingsAppState from './SettingsAppState'; import SystemAppState from './SystemAppState'; @@ -66,14 +69,17 @@ interface AppState { commands: CommandAppState; history: HistoryAppState; interactiveImport: InteractiveImportAppState; + movieBlocklist: MovieBlocklistAppState; movieCollections: MovieCollectionAppState; movieCredits: MovieCreditAppState; movieFiles: MovieFilesAppState; + movieHistory: MovieHistoryAppState; movieIndex: MovieIndexAppState; movies: MoviesAppState; parse: ParseAppState; paths: PathsAppState; queue: QueueAppState; + releases: ReleasesAppState; rootFolders: RootFolderAppState; settings: SettingsAppState; system: SystemAppState; diff --git a/frontend/src/App/State/MovieBlocklistAppState.ts b/frontend/src/App/State/MovieBlocklistAppState.ts new file mode 100644 index 0000000000..1b3d25ab03 --- /dev/null +++ b/frontend/src/App/State/MovieBlocklistAppState.ts @@ -0,0 +1,6 @@ +import AppSectionState from 'App/State/AppSectionState'; +import Blocklist from 'typings/Blocklist'; + +type MovieBlocklistAppState = AppSectionState; + +export default MovieBlocklistAppState; diff --git a/frontend/src/App/State/MovieHistoryAppState.ts b/frontend/src/App/State/MovieHistoryAppState.ts new file mode 100644 index 0000000000..44a024cdf4 --- /dev/null +++ b/frontend/src/App/State/MovieHistoryAppState.ts @@ -0,0 +1,6 @@ +import AppSectionState from 'App/State/AppSectionState'; +import History from 'typings/History'; + +type MovieHistoryAppState = AppSectionState; + +export default MovieHistoryAppState; diff --git a/frontend/src/App/State/ReleasesAppState.ts b/frontend/src/App/State/ReleasesAppState.ts new file mode 100644 index 0000000000..350f6eac8e --- /dev/null +++ b/frontend/src/App/State/ReleasesAppState.ts @@ -0,0 +1,10 @@ +import AppSectionState, { + AppSectionFilterState, +} from 'App/State/AppSectionState'; +import Release from 'typings/Release'; + +interface ReleasesAppState + extends AppSectionState, + AppSectionFilterState {} + +export default ReleasesAppState; diff --git a/frontend/src/Components/Table/Column.ts b/frontend/src/Components/Table/Column.ts index 24674c3fc4..22d22e9636 100644 --- a/frontend/src/Components/Table/Column.ts +++ b/frontend/src/Components/Table/Column.ts @@ -1,4 +1,5 @@ import React from 'react'; +import { SortDirection } from 'Helpers/Props/sortDirections'; type PropertyFunction = () => T; @@ -9,6 +10,7 @@ interface Column { className?: string; columnLabel?: string; isSortable?: boolean; + fixedSortDirection?: SortDirection; isVisible: boolean; isModifiable?: boolean; } diff --git a/frontend/src/InteractiveSearch/InteractiveSearch.js b/frontend/src/InteractiveSearch/InteractiveSearch.js deleted file mode 100644 index 8c3f2c4107..0000000000 --- a/frontend/src/InteractiveSearch/InteractiveSearch.js +++ /dev/null @@ -1,240 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Fragment } from 'react'; -import Alert from 'Components/Alert'; -import Icon from 'Components/Icon'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import FilterMenu from 'Components/Menu/FilterMenu'; -import PageMenuButton from 'Components/Menu/PageMenuButton'; -import Table from 'Components/Table/Table'; -import TableBody from 'Components/Table/TableBody'; -import { align, icons, kinds, sortDirections } from 'Helpers/Props'; -import getErrorMessage from 'Utilities/Object/getErrorMessage'; -import translate from 'Utilities/String/translate'; -import InteractiveSearchFilterModalConnector from './InteractiveSearchFilterModalConnector'; -import InteractiveSearchRowConnector from './InteractiveSearchRowConnector'; -import styles from './InteractiveSearch.css'; - -const columns = [ - { - name: 'protocol', - label: () => translate('Source'), - isSortable: true, - isVisible: true - }, - { - name: 'age', - label: () => translate('Age'), - isSortable: true, - isVisible: true - }, - { - name: 'title', - label: () => translate('Title'), - isSortable: true, - isVisible: true - }, - { - name: 'indexer', - label: () => translate('Indexer'), - isSortable: true, - isVisible: true - }, - { - name: 'history', - label: () => translate('History'), - isSortable: true, - fixedSortDirection: sortDirections.ASCENDING, - isVisible: true - }, - { - name: 'size', - label: () => translate('Size'), - isSortable: true, - isVisible: true - }, - { - name: 'peers', - label: () => translate('Peers'), - isSortable: true, - isVisible: true - }, - { - name: 'languages', - label: () => translate('Language'), - isSortable: true, - isVisible: true - }, - { - name: 'qualityWeight', - label: () => translate('Quality'), - isSortable: true, - isVisible: true - }, - { - name: 'customFormatScore', - label: React.createElement(Icon, { - name: icons.SCORE, - title: () => translate('CustomFormatScore') - }), - isSortable: true, - isVisible: true - }, - { - name: 'indexerFlags', - label: React.createElement(Icon, { - name: icons.FLAG, - title: () => translate('IndexerFlags') - }), - isSortable: true, - isVisible: true - }, - { - name: 'rejections', - label: React.createElement(Icon, { - name: icons.DANGER, - title: () => translate('Rejections') - }), - isSortable: true, - fixedSortDirection: sortDirections.ASCENDING, - isVisible: true - }, - { - name: 'releaseWeight', - label: React.createElement(Icon, { name: icons.DOWNLOAD }), - isSortable: true, - fixedSortDirection: sortDirections.ASCENDING, - isVisible: true - } -]; - -function InteractiveSearch(props) { - const { - searchPayload, - isFetching, - isPopulated, - error, - totalReleasesCount, - items, - selectedFilterKey, - filters, - customFilters, - sortKey, - sortDirection, - longDateFormat, - timeFormat, - onSortPress, - onFilterSelect, - onGrabPress - } = props; - - const errorMessage = getErrorMessage(error); - const type = 'movies'; - - return ( -
-
- -
- - { - isFetching ? : null - } - - { - !isFetching && error ? - - { - errorMessage ? - - {translate('InteractiveSearchResultsFailedErrorMessage', { message: errorMessage.charAt(0).toLowerCase() + errorMessage.slice(1) })} - : - translate('MovieSearchResultsLoadError') - } - : - null - } - - { - !isFetching && isPopulated && !totalReleasesCount ? - - {translate('NoResultsFound')} - : - null - } - - { - !!totalReleasesCount && isPopulated && !items.length ? - - {translate('AllResultsHiddenFilter')} - : - null - } - - { - isPopulated && !!items.length ? -
- - { - items.map((item) => { - return ( - - ); - }) - } - -
: - null - } - - { - totalReleasesCount !== items.length && !!items.length ? - - {translate('SomeResultsHiddenFilter')} - : - null - } -
- ); -} - -InteractiveSearch.propTypes = { - searchPayload: PropTypes.object.isRequired, - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - totalReleasesCount: PropTypes.number.isRequired, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired, - filters: PropTypes.arrayOf(PropTypes.object).isRequired, - customFilters: PropTypes.arrayOf(PropTypes.object).isRequired, - sortKey: PropTypes.string, - sortDirection: PropTypes.string, - longDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onSortPress: PropTypes.func.isRequired, - onFilterSelect: PropTypes.func.isRequired, - onGrabPress: PropTypes.func.isRequired -}; - -export default InteractiveSearch; diff --git a/frontend/src/InteractiveSearch/InteractiveSearch.tsx b/frontend/src/InteractiveSearch/InteractiveSearch.tsx new file mode 100644 index 0000000000..068dc83c07 --- /dev/null +++ b/frontend/src/InteractiveSearch/InteractiveSearch.tsx @@ -0,0 +1,263 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import ClientSideCollectionAppState from 'App/State/ClientSideCollectionAppState'; +import ReleasesAppState from 'App/State/ReleasesAppState'; +import Alert from 'Components/Alert'; +import Icon from 'Components/Icon'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import FilterMenu from 'Components/Menu/FilterMenu'; +import PageMenuButton from 'Components/Menu/PageMenuButton'; +import Column from 'Components/Table/Column'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import { align, icons, kinds, sortDirections } from 'Helpers/Props'; +import { SortDirection } from 'Helpers/Props/sortDirections'; +import { fetchMovieBlocklist } from 'Store/Actions/movieBlocklistActions'; +import { fetchMovieHistory } from 'Store/Actions/movieHistoryActions'; +import { + fetchReleases, + grabRelease, + setReleasesFilter, + setReleasesSort, +} from 'Store/Actions/releaseActions'; +import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; +import getErrorMessage from 'Utilities/Object/getErrorMessage'; +import translate from 'Utilities/String/translate'; +import InteractiveSearchFilterModal from './InteractiveSearchFilterModal'; +import InteractiveSearchPayload from './InteractiveSearchPayload'; +import InteractiveSearchRow from './InteractiveSearchRow'; +import styles from './InteractiveSearch.css'; + +const columns: Column[] = [ + { + name: 'protocol', + label: () => translate('Source'), + isSortable: true, + isVisible: true, + }, + { + name: 'age', + label: () => translate('Age'), + isSortable: true, + isVisible: true, + }, + { + name: 'title', + label: () => translate('Title'), + isSortable: true, + isVisible: true, + }, + { + name: 'indexer', + label: () => translate('Indexer'), + isSortable: true, + isVisible: true, + }, + { + name: 'history', + label: () => translate('History'), + isSortable: true, + fixedSortDirection: sortDirections.ASCENDING, + isVisible: true, + }, + { + name: 'size', + label: () => translate('Size'), + isSortable: true, + isVisible: true, + }, + { + name: 'peers', + label: () => translate('Peers'), + isSortable: true, + isVisible: true, + }, + { + name: 'languages', + label: () => translate('Language'), + isSortable: true, + isVisible: true, + }, + { + name: 'qualityWeight', + label: () => translate('Quality'), + isSortable: true, + isVisible: true, + }, + { + name: 'customFormatScore', + label: React.createElement(Icon, { + name: icons.SCORE, + title: () => translate('CustomFormatScore'), + }), + isSortable: true, + isVisible: true, + }, + { + name: 'indexerFlags', + label: React.createElement(Icon, { + name: icons.FLAG, + title: () => translate('IndexerFlags'), + }), + isSortable: true, + isVisible: true, + }, + { + name: 'rejections', + label: React.createElement(Icon, { + name: icons.DANGER, + title: () => translate('Rejections'), + }), + isSortable: true, + fixedSortDirection: sortDirections.ASCENDING, + isVisible: true, + }, + { + name: 'releaseWeight', + label: React.createElement(Icon, { name: icons.DOWNLOAD }), + isSortable: true, + fixedSortDirection: sortDirections.ASCENDING, + isVisible: true, + }, +]; + +interface InteractiveSearchProps { + searchPayload: InteractiveSearchPayload; +} + +function InteractiveSearch({ searchPayload }: InteractiveSearchProps) { + const { + isFetching, + isPopulated, + error, + items, + totalItems, + selectedFilterKey, + filters, + customFilters, + sortKey, + sortDirection, + }: ReleasesAppState & ClientSideCollectionAppState = useSelector( + createClientSideCollectionSelector('releases') + ); + + const dispatch = useDispatch(); + + const handleFilterSelect = useCallback( + (selectedFilterKey: string | number) => { + dispatch(setReleasesFilter({ selectedFilterKey })); + }, + [dispatch] + ); + + const handleSortPress = useCallback( + (sortKey: string, sortDirection?: SortDirection) => { + dispatch(setReleasesSort({ sortKey, sortDirection })); + }, + [dispatch] + ); + + const handleGrabPress = useCallback( + (payload: object) => { + dispatch(grabRelease(payload)); + }, + [dispatch] + ); + + useEffect( + () => { + // Only fetch releases if they are not already being fetched and not yet populated. + + if (!isFetching && !isPopulated) { + dispatch(fetchReleases(searchPayload)); + + const { movieId } = searchPayload; + + if (movieId) { + dispatch(fetchMovieBlocklist({ movieId })); + dispatch(fetchMovieHistory({ movieId })); + } + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const errorMessage = getErrorMessage(error); + + return ( +
+
+ +
+ + {isFetching ? : null} + + {!isFetching && error ? ( + + {errorMessage ? ( + <> + {translate('InteractiveSearchResultsFailedErrorMessage', { + message: + errorMessage.charAt(0).toLowerCase() + errorMessage.slice(1), + })} + + ) : ( + translate('MovieSearchResultsLoadError') + )} + + ) : null} + + {!isFetching && isPopulated && !totalItems ? ( + + {translate('NoResultsFound')} + + ) : null} + + {!!totalItems && isPopulated && !items.length ? ( + + {translate('AllResultsHiddenFilter')} + + ) : null} + + {isPopulated && !!items.length ? ( + + + {items.map((item) => { + return ( + + ); + })} + +
+ ) : null} + + {totalItems !== items.length && !!items.length ? ( + + {translate('SomeResultsHiddenFilter')} + + ) : null} +
+ ); +} + +export default InteractiveSearch; diff --git a/frontend/src/InteractiveSearch/InteractiveSearchConnector.js b/frontend/src/InteractiveSearch/InteractiveSearchConnector.js deleted file mode 100644 index 946324647d..0000000000 --- a/frontend/src/InteractiveSearch/InteractiveSearchConnector.js +++ /dev/null @@ -1,109 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { clearMovieHistory, fetchMovieHistory } from 'Store/Actions/movieHistoryActions'; -import * as releaseActions from 'Store/Actions/releaseActions'; -import createClientSideCollectionSelector from 'Store/Selectors/createClientSideCollectionSelector'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import InteractiveSearch from './InteractiveSearch'; - -function createMapStateToProps(appState) { - return createSelector( - (state) => state.releases.items.length, - createClientSideCollectionSelector('releases'), - createUISettingsSelector(), - (totalReleasesCount, releases, uiSettings) => { - return { - totalReleasesCount, - longDateFormat: uiSettings.longDateFormat, - timeFormat: uiSettings.timeFormat, - ...releases - }; - } - ); -} - -function createMapDispatchToProps(dispatch, props) { - return { - dispatchFetchReleases(payload) { - dispatch(releaseActions.fetchReleases(payload)); - }, - - dispatchFetchMovieHistory({ movieId }) { - dispatch(fetchMovieHistory({ movieId })); - }, - - dispatchClearMovieHistory() { - dispatch(clearMovieHistory()); - }, - - onSortPress(sortKey, sortDirection) { - dispatch(releaseActions.setReleasesSort({ sortKey, sortDirection })); - }, - - onFilterSelect(selectedFilterKey) { - dispatch(releaseActions.setReleasesFilter({ selectedFilterKey })); - }, - - onGrabPress(payload) { - dispatch(releaseActions.grabRelease(payload)); - } - }; -} - -class InteractiveSearchConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - searchPayload, - isPopulated, - dispatchFetchReleases, - dispatchFetchMovieHistory - } = this.props; - - // If search results are not yet isPopulated fetch them, - // otherwise re-show the existing props. - if (!isPopulated) { - dispatchFetchReleases(searchPayload); - } - - dispatchFetchMovieHistory(searchPayload); - } - - componentWillUnmount() { - this.props.dispatchClearMovieHistory(); - } - - // - // Render - - render() { - const { - dispatchFetchReleases, - dispatchFetchMovieHistory, - dispatchClearMovieHistory, - ...otherProps - } = this.props; - - return ( - - - ); - } -} - -InteractiveSearchConnector.propTypes = { - searchPayload: PropTypes.object.isRequired, - isPopulated: PropTypes.bool.isRequired, - dispatchFetchReleases: PropTypes.func.isRequired, - dispatchFetchMovieHistory: PropTypes.func.isRequired, - dispatchClearMovieHistory: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, createMapDispatchToProps)(InteractiveSearchConnector); diff --git a/frontend/src/InteractiveSearch/InteractiveSearchFilterModal.tsx b/frontend/src/InteractiveSearch/InteractiveSearchFilterModal.tsx new file mode 100644 index 0000000000..358367074d --- /dev/null +++ b/frontend/src/InteractiveSearch/InteractiveSearchFilterModal.tsx @@ -0,0 +1,55 @@ +import React, { useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import FilterModal from 'Components/Filter/FilterModal'; +import { setReleasesFilter } from 'Store/Actions/releaseActions'; + +function createReleasesSelector() { + return createSelector( + (state: AppState) => state.releases.items, + (releases) => { + return releases; + } + ); +} + +function createFilterBuilderPropsSelector() { + return createSelector( + (state: AppState) => state.releases.filterBuilderProps, + (filterBuilderProps) => { + return filterBuilderProps; + } + ); +} + +interface InteractiveSearchFilterModalProps { + isOpen: boolean; +} + +export default function InteractiveSearchFilterModal({ + ...otherProps +}: InteractiveSearchFilterModalProps) { + const sectionItems = useSelector(createReleasesSelector()); + const filterBuilderProps = useSelector(createFilterBuilderPropsSelector()); + + const dispatch = useDispatch(); + + const dispatchSetFilter = useCallback( + (payload: unknown) => { + dispatch(setReleasesFilter(payload)); + }, + [dispatch] + ); + + return ( + + ); +} diff --git a/frontend/src/InteractiveSearch/InteractiveSearchFilterModalConnector.js b/frontend/src/InteractiveSearch/InteractiveSearchFilterModalConnector.js deleted file mode 100644 index c42fb30d15..0000000000 --- a/frontend/src/InteractiveSearch/InteractiveSearchFilterModalConnector.js +++ /dev/null @@ -1,29 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import FilterModal from 'Components/Filter/FilterModal'; -import { setReleasesFilter } from 'Store/Actions/releaseActions'; - -function createMapStateToProps() { - return createSelector( - (state) => state.releases.items, - (state) => state.releases.filterBuilderProps, - (sectionItems, filterBuilderProps) => { - return { - sectionItems, - filterBuilderProps, - customFilterType: 'releases' - }; - } - ); -} - -function createMapDispatchToProps(dispatch, props) { - return { - dispatchSetFilter(payload) { - const action = setReleasesFilter; - dispatch(action(payload)); - } - }; -} - -export default connect(createMapStateToProps, createMapDispatchToProps)(FilterModal); diff --git a/frontend/src/InteractiveSearch/InteractiveSearchPayload.ts b/frontend/src/InteractiveSearch/InteractiveSearchPayload.ts new file mode 100644 index 0000000000..493f1bc305 --- /dev/null +++ b/frontend/src/InteractiveSearch/InteractiveSearchPayload.ts @@ -0,0 +1,7 @@ +interface MovieSearchPayload { + movieId: number; +} + +type InteractiveSearchPayload = MovieSearchPayload; + +export default InteractiveSearchPayload; diff --git a/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx b/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx index c2bc0afb0a..c848b6e32f 100644 --- a/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx +++ b/frontend/src/InteractiveSearch/InteractiveSearchRow.tsx @@ -1,5 +1,8 @@ import React, { useCallback, useState } from 'react'; +import { useSelector } from 'react-redux'; +import { createSelector } from 'reselect'; import ProtocolLabel from 'Activity/Queue/ProtocolLabel'; +import AppState from 'App/State/AppState'; import Icon from 'Components/Icon'; import Link from 'Components/Link/Link'; import SpinnerIconButton from 'Components/Link/SpinnerIconButton'; @@ -8,21 +11,18 @@ import TableRowCell from 'Components/Table/Cells/TableRowCell'; import TableRow from 'Components/Table/TableRow'; import Popover from 'Components/Tooltip/Popover'; import Tooltip from 'Components/Tooltip/Tooltip'; -import type DownloadProtocol from 'DownloadClient/DownloadProtocol'; import { icons, kinds, tooltipPositions } from 'Helpers/Props'; -import Language from 'Language/Language'; import MovieFormats from 'Movie/MovieFormats'; import MovieLanguages from 'Movie/MovieLanguages'; import MovieQuality from 'Movie/MovieQuality'; -import { QualityModel } from 'Quality/Quality'; -import CustomFormat from 'typings/CustomFormat'; -import MovieBlocklist from 'typings/MovieBlocklist'; -import MovieHistory from 'typings/MovieHistory'; +import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; +import Release from 'typings/Release'; import formatDateTime from 'Utilities/Date/formatDateTime'; import formatAge from 'Utilities/Number/formatAge'; import formatBytes from 'Utilities/Number/formatBytes'; import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; import translate from 'Utilities/String/translate'; +import InteractiveSearchPayload from './InteractiveSearchPayload'; import OverrideMatchModal from './OverrideMatch/OverrideMatchModal'; import Peers from './Peers'; import styles from './InteractiveSearchRow.css'; @@ -71,37 +71,42 @@ function getDownloadTooltip( return translate('AddToDownloadQueue'); } -interface InteractiveSearchRowProps { - guid: string; - protocol: DownloadProtocol; - age: number; - ageHours: number; - ageMinutes: number; - publishDate: string; - title: string; - infoUrl: string; - indexerId: number; - indexer: string; - size: number; - seeders?: number; - leechers?: number; - quality: QualityModel; - languages: Language[]; - customFormats: CustomFormat[]; - customFormatScore: number; - mappedMovieId?: number; - indexerFlags: string[]; - rejections: string[]; - downloadAllowed: boolean; - isGrabbing: boolean; - isGrabbed: boolean; - grabError?: string; - historyFailedData?: MovieHistory; - historyGrabbedData?: MovieHistory; - blocklistData?: MovieBlocklist; - longDateFormat: string; - timeFormat: string; - searchPayload: object; +function releaseHistorySelector({ guid }: Release) { + return createSelector( + (state: AppState) => state.movieHistory.items, + (state: AppState) => state.movieBlocklist.items, + (movieHistory, movieBlocklist) => { + let historyFailedData = null; + let blocklistedData = null; + + const historyGrabbedData = movieHistory.find( + ({ eventType, data }) => + eventType === 'grabbed' && 'guid' in data && data.guid === guid + ); + + if (historyGrabbedData) { + historyFailedData = movieHistory.find( + ({ eventType, sourceTitle }) => + eventType === 'downloadFailed' && + sourceTitle === historyGrabbedData.sourceTitle + ); + + blocklistedData = movieBlocklist.find( + (item) => item.sourceTitle === historyGrabbedData.sourceTitle + ); + } + + return { + historyGrabbedData, + historyFailedData, + blocklistedData, + }; + } + ); +} + +interface InteractiveSearchRowProps extends Release { + searchPayload: InteractiveSearchPayload; onGrabPress(...args: unknown[]): void; } @@ -130,16 +135,18 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) { downloadAllowed, isGrabbing = false, isGrabbed = false, - longDateFormat, - timeFormat, grabError, - historyGrabbedData = {} as MovieHistory, - historyFailedData = {} as MovieHistory, - blocklistData = {} as MovieBlocklist, searchPayload, onGrabPress, } = props; + const { longDateFormat, timeFormat } = useSelector( + createUISettingsSelector() + ); + + const { historyGrabbedData, historyFailedData, blocklistedData } = + useSelector(releaseHistorySelector(props)); + const [isConfirmGrabModalOpen, setIsConfirmGrabModalOpen] = useState(false); const [isOverrideModalOpen, setIsOverrideModalOpen] = useState(false); @@ -211,44 +218,52 @@ function InteractiveSearchRow(props: InteractiveSearchRowProps) { {historyGrabbedData?.date && !historyFailedData?.date ? ( - } + tooltip={translate('GrabbedAt', { + date: formatDateTime( + historyGrabbedData.date, + longDateFormat, + timeFormat, + { includeSeconds: true } + ), + })} + kind={kinds.INVERSE} + position={tooltipPositions.LEFT} /> ) : null} {historyFailedData?.date ? ( - } + tooltip={translate('FailedAt', { + date: formatDateTime( + historyFailedData.date, + longDateFormat, + timeFormat, + { includeSeconds: true } + ), + })} + kind={kinds.INVERSE} + position={tooltipPositions.LEFT} /> ) : null} - {blocklistData?.date ? ( + {blocklistedData?.date ? ( ) : null} diff --git a/frontend/src/InteractiveSearch/InteractiveSearchRowConnector.js b/frontend/src/InteractiveSearch/InteractiveSearchRowConnector.js deleted file mode 100644 index 22ebccd3d5..0000000000 --- a/frontend/src/InteractiveSearch/InteractiveSearchRowConnector.js +++ /dev/null @@ -1,62 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import InteractiveSearchRow from './InteractiveSearchRow'; - -function createMapStateToProps() { - return createSelector( - (state, { guid }) => guid, - (state) => state.movieHistory.items, - (state) => state.movieBlocklist.items, - (guid, movieHistory, movieBlocklist) => { - - let blocklistData = {}; - let historyFailedData = {}; - - const historyGrabbedData = movieHistory.find((movie) => movie.eventType === 'grabbed' && movie.data.guid === guid); - if (historyGrabbedData) { - historyFailedData = movieHistory.find((movie) => movie.eventType === 'downloadFailed' && movie.sourceTitle === historyGrabbedData.sourceTitle); - blocklistData = movieBlocklist.find((item) => item.sourceTitle === historyGrabbedData.sourceTitle); - } - - return { - historyGrabbedData, - historyFailedData, - blocklistData - }; - } - ); -} - -class InteractiveSearchRowConnector extends Component { - - // - // Render - - render() { - const { - historyGrabbedData, - historyFailedData, - blocklistData, - ...otherProps - } = this.props; - - return ( - - ); - } -} - -InteractiveSearchRowConnector.propTypes = { - historyGrabbedData: PropTypes.object, - historyFailedData: PropTypes.object, - blocklistData: PropTypes.object -}; - -export default connect(createMapStateToProps)(InteractiveSearchRowConnector); diff --git a/frontend/src/InteractiveSearch/Peers.js b/frontend/src/InteractiveSearch/Peers.tsx similarity index 68% rename from frontend/src/InteractiveSearch/Peers.js rename to frontend/src/InteractiveSearch/Peers.tsx index a55e75c092..9c0caca582 100644 --- a/frontend/src/InteractiveSearch/Peers.js +++ b/frontend/src/InteractiveSearch/Peers.tsx @@ -1,9 +1,8 @@ -import PropTypes from 'prop-types'; import React from 'react'; import Label from 'Components/Label'; import { kinds } from 'Helpers/Props'; -function getKind(seeders) { +function getKind(seeders: number = 0) { if (seeders > 50) { return kinds.PRIMARY; } @@ -19,7 +18,7 @@ function getKind(seeders) { return kinds.DANGER; } -function getPeersTooltipPart(peers, peersUnit) { +function getPeersTooltipPart(peers: number | undefined, peersUnit: string) { if (peers == null) { return `Unknown ${peersUnit}s`; } @@ -31,27 +30,27 @@ function getPeersTooltipPart(peers, peersUnit) { return `${peers} ${peersUnit}s`; } -function Peers(props) { - const { - seeders, - leechers - } = props; +interface PeersProps { + seeders?: number; + leechers?: number; +} + +function Peers(props: PeersProps) { + const { seeders, leechers } = props; const kind = getKind(seeders); return ( ); } -Peers.propTypes = { - seeders: PropTypes.number, - leechers: PropTypes.number -}; - export default Peers; diff --git a/frontend/src/Movie/Details/MovieDetailsConnector.js b/frontend/src/Movie/Details/MovieDetailsConnector.js index 417e0bfe1a..a3af095f9b 100644 --- a/frontend/src/Movie/Details/MovieDetailsConnector.js +++ b/frontend/src/Movie/Details/MovieDetailsConnector.js @@ -8,11 +8,9 @@ import * as commandNames from 'Commands/commandNames'; import { executeCommand } from 'Store/Actions/commandActions'; import { clearExtraFiles, fetchExtraFiles } from 'Store/Actions/extraFileActions'; import { toggleMovieMonitored } from 'Store/Actions/movieActions'; -import { clearMovieBlocklist, fetchMovieBlocklist } from 'Store/Actions/movieBlocklistActions'; import { clearMovieCredits, fetchMovieCredits } from 'Store/Actions/movieCreditsActions'; import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions'; import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions'; -import { cancelFetchReleases, clearReleases } from 'Store/Actions/releaseActions'; import { fetchImportListSchema } from 'Store/Actions/settingsActions'; import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector'; import createCommandsSelector from 'Store/Selectors/createCommandsSelector'; @@ -188,12 +186,6 @@ function createMapDispatchToProps(dispatch, props) { dispatchClearExtraFiles() { dispatch(clearExtraFiles()); }, - dispatchClearReleases() { - dispatch(clearReleases()); - }, - dispatchCancelFetchReleases() { - dispatch(cancelFetchReleases()); - }, dispatchFetchQueueDetails({ movieId }) { dispatch(fetchQueueDetails({ movieId })); }, @@ -211,12 +203,6 @@ function createMapDispatchToProps(dispatch, props) { }, onGoToMovie(titleSlug) { dispatch(push(`${window.Radarr.urlBase}/movie/${titleSlug}`)); - }, - dispatchFetchMovieBlocklist({ movieId }) { - dispatch(fetchMovieBlocklist({ movieId })); - }, - dispatchClearMovieBlocklist() { - dispatch(clearMovieBlocklist()); } }; } @@ -270,7 +256,6 @@ class MovieDetailsConnector extends Component { const movieId = this.props.id; this.props.dispatchFetchMovieFiles({ movieId }); - this.props.dispatchFetchMovieBlocklist({ movieId }); this.props.dispatchFetchExtraFiles({ movieId }); this.props.dispatchFetchMovieCredits({ movieId }); this.props.dispatchFetchQueueDetails({ movieId }); @@ -278,13 +263,10 @@ class MovieDetailsConnector extends Component { }; unpopulate = () => { - this.props.dispatchCancelFetchReleases(); - this.props.dispatchClearMovieBlocklist(); this.props.dispatchClearMovieFiles(); this.props.dispatchClearExtraFiles(); this.props.dispatchClearMovieCredits(); this.props.dispatchClearQueueDetails(); - this.props.dispatchClearReleases(); }; // @@ -341,15 +323,11 @@ MovieDetailsConnector.propTypes = { dispatchClearExtraFiles: PropTypes.func.isRequired, dispatchFetchMovieCredits: PropTypes.func.isRequired, dispatchClearMovieCredits: PropTypes.func.isRequired, - dispatchClearReleases: PropTypes.func.isRequired, - dispatchCancelFetchReleases: PropTypes.func.isRequired, dispatchToggleMovieMonitored: PropTypes.func.isRequired, dispatchFetchQueueDetails: PropTypes.func.isRequired, dispatchClearQueueDetails: PropTypes.func.isRequired, dispatchFetchImportListSchema: PropTypes.func.isRequired, dispatchExecuteCommand: PropTypes.func.isRequired, - dispatchFetchMovieBlocklist: PropTypes.func.isRequired, - dispatchClearMovieBlocklist: PropTypes.func.isRequired, onGoToMovie: PropTypes.func.isRequired }; diff --git a/frontend/src/Movie/Search/MovieInteractiveSearchModal.tsx b/frontend/src/Movie/Search/MovieInteractiveSearchModal.tsx index 5a4fb3a098..511a66e5bb 100644 --- a/frontend/src/Movie/Search/MovieInteractiveSearchModal.tsx +++ b/frontend/src/Movie/Search/MovieInteractiveSearchModal.tsx @@ -2,6 +2,8 @@ import React, { useCallback } from 'react'; import { useDispatch } from 'react-redux'; import Modal from 'Components/Modal/Modal'; import { sizes } from 'Helpers/Props'; +import { clearMovieBlocklist } from 'Store/Actions/movieBlocklistActions'; +import { clearMovieHistory } from 'Store/Actions/movieHistoryActions'; import { cancelFetchReleases, clearReleases, @@ -24,6 +26,9 @@ function MovieInteractiveSearchModal(props: MovieInteractiveSearchModalProps) { dispatch(cancelFetchReleases()); dispatch(clearReleases()); + dispatch(clearMovieBlocklist()); + dispatch(clearMovieHistory()); + onModalClose(); }, [dispatch, onModalClose]); diff --git a/frontend/src/Movie/Search/MovieInteractiveSearchModalContent.tsx b/frontend/src/Movie/Search/MovieInteractiveSearchModalContent.tsx index a5a9db2e22..c9f4c7a7b1 100644 --- a/frontend/src/Movie/Search/MovieInteractiveSearchModalContent.tsx +++ b/frontend/src/Movie/Search/MovieInteractiveSearchModalContent.tsx @@ -6,7 +6,9 @@ import ModalContent from 'Components/Modal/ModalContent'; import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import { scrollDirections } from 'Helpers/Props'; -import InteractiveSearchConnector from 'InteractiveSearch/InteractiveSearchConnector'; +import InteractiveSearch from 'InteractiveSearch/InteractiveSearch'; +import { clearMovieBlocklist } from 'Store/Actions/movieBlocklistActions'; +import { clearMovieHistory } from 'Store/Actions/movieHistoryActions'; import { cancelFetchReleases, clearReleases, @@ -30,6 +32,9 @@ function MovieInteractiveSearchModalContent( return () => { dispatch(cancelFetchReleases()); dispatch(clearReleases()); + + dispatch(clearMovieBlocklist()); + dispatch(clearMovieHistory()); }; }, [dispatch]); @@ -44,7 +49,7 @@ function MovieInteractiveSearchModalContent( - + diff --git a/frontend/src/typings/Release.ts b/frontend/src/typings/Release.ts new file mode 100644 index 0000000000..ec0dffaf67 --- /dev/null +++ b/frontend/src/typings/Release.ts @@ -0,0 +1,35 @@ +import type DownloadProtocol from 'DownloadClient/DownloadProtocol'; +import Language from 'Language/Language'; +import { QualityModel } from 'Quality/Quality'; +import CustomFormat from 'typings/CustomFormat'; + +interface Release { + guid: string; + protocol: DownloadProtocol; + age: number; + ageHours: number; + ageMinutes: number; + publishDate: string; + title: string; + infoUrl: string; + indexerId: number; + indexer: string; + size: number; + seeders?: number; + leechers?: number; + quality: QualityModel; + languages: Language[]; + customFormats: CustomFormat[]; + customFormatScore: number; + mappedMovieId?: number; + indexerFlags: string[]; + rejections: string[]; + movieRequested: boolean; + downloadAllowed: boolean; + + isGrabbing?: boolean; + isGrabbed?: boolean; + grabError?: string; +} + +export default Release; diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index d2c29ed270..77a1a701a2 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -159,6 +159,7 @@ "BlocklistReleaseHelpText": "Blocks this release from being redownloaded by {appName} via RSS or Automatic Search", "BlocklistReleases": "Blocklist Releases", "Blocklisted": "Blocklisted", + "BlocklistedAt": "Blocklisted at {date}", "Branch": "Branch", "BranchUpdate": "Branch to use to update {appName}", "BranchUpdateMechanism": "Branch used by external update mechanism", @@ -645,6 +646,7 @@ "ExtraFileExtensionsHelpText": "Comma separated list of extra files to import (.nfo will be imported as .nfo-orig)", "ExtraFileExtensionsHelpTextsExamples": "Examples: '.sub, .nfo' or 'sub,nfo'", "Failed": "Failed", + "FailedAt": "Failed at {date}", "FailedDownloadHandling": "Failed Download Handling", "FailedLoadingSearchResults": "Failed to load search results, please try again.", "FailedToFetchUpdates": "Failed to fetch updates", @@ -708,6 +710,7 @@ "GrabReleaseMessageText": "{appName} was unable to determine which movie this release was for. {appName} may be unable to automatically import this release. Do you want to grab '{0}'?", "GrabSelected": "Grab Selected", "Grabbed": "Grabbed", + "GrabbedAt": "Grabbed at {date}", "Group": "Group", "HardlinkCopyFiles": "Hardlink/Copy Files", "HaveNotAddedMovies": "You haven't added any movies yet, do you want to import some or all of your movies first?", From 102849a697b37b8961acae593dd311d51a93974a Mon Sep 17 00:00:00 2001 From: Weblate Date: Thu, 6 Mar 2025 21:33:27 +0000 Subject: [PATCH 234/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Chong Yao Jun Co-authored-by: GkhnGRBZ Co-authored-by: Havok Dan Co-authored-by: Oskari Lavinto Co-authored-by: Stan Ulbrych Co-authored-by: Weblate Co-authored-by: Weblate Co-authored-by: fordas Co-authored-by: pbarone Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/de.json | 3 +- src/NzbDrone.Core/Localization/Core/es.json | 8 +++- src/NzbDrone.Core/Localization/Core/fi.json | 5 ++- src/NzbDrone.Core/Localization/Core/fr.json | 3 +- src/NzbDrone.Core/Localization/Core/hu.json | 3 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 8 +++- src/NzbDrone.Core/Localization/Core/pl.json | 5 ++- .../Localization/Core/pt_BR.json | 5 ++- src/NzbDrone.Core/Localization/Core/tr.json | 7 ++- .../Localization/Core/zh_CN.json | 43 ++++++++++++++++++- .../Localization/Core/zh_Hans.json | 3 +- 12 files changed, 82 insertions(+), 13 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 6878351d9b..f042ab0906 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1908,5 +1908,6 @@ "ImportListsTraktSettingsUserListTypeWatch": "Benutzer-Watch-Liste", "ImportListsTraktSettingsUserListTypeWatched": "Benutzer-Gesehene-Liste", "ImportListsTraktSettingsWatchListSorting": "Sortierung der Gesehenen Liste", - "ImportListsTraktSettingsUserListUsernameHelpText": "Benutzername für die Liste, von der du importieren möchtest (leer lassen, um den Authentifizierten Benutzer zu verwenden)" + "ImportListsTraktSettingsUserListUsernameHelpText": "Benutzername für die Liste, von der du importieren möchtest (leer lassen, um den Authentifizierten Benutzer zu verwenden)", + "ImportListsTraktSettingsWatchListSortingHelpText": "Wenn der Listentyp 'Gesehen' ist, wähle die Reihenfolge, in der die Liste sortiert werden soll" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 419fd86424..3e02e3b376 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1926,5 +1926,11 @@ "ImportListsTraktSettingsUserListTypeWatch": "Lista de seguimiento de usuario", "ImportListsTraktSettingsUserListTypeWatched": "Lista de vistos de usuario", "ImportListsTraktSettingsUserListUsernameHelpText": "Usuario para la lista de la que importar (dejar vacío para usar Autenticación de usuario)", - "ImportListsTraktSettingsWatchListSorting": "Ordenar la lista de vistos" + "ImportListsTraktSettingsWatchListSorting": "Ordenar la lista de vistos", + "ImportListsTraktSettingsWatchListSortingHelpText": "Si el tipo de lista es Vistos, selecciona el orden para ordenar la lista", + "BlocklistedAt": "En la lista negra el {date}", + "FailedAt": "Error el {date}", + "GrabbedAt": "Capturado el {date}", + "ReleaseSource": "Origen del lanzamiento", + "DownloadClientUTorrentProviderMessage": "Debido a que uTorrent es conocido por el cryptoware, el malware y la publicidad, sugerimos cambiar a un cliente mejor como qBittorrent, Deluge o ruTorrent." } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 15bc47af66..034f7ada79 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -1929,5 +1929,8 @@ "ImportListsTraktSettingsUserListUsernameHelpText": "Listan tuontiin käytettävä käyttäjänimi. Käytä tunnistautunutta käyttäjää jättämällä tyhjäksi.", "ImportListsTraktSettingsWatchListSorting": "Katselulistan järjestys", "DownloadClientUTorrentProviderMessage": "Koska uTorrent on tunnettu crypto-, haitta- and mainossisällöstä ja sovelluksista, suosittelemme esimerkiksi qBittorrentin, Delugen ja ruTorrentin kaltaisia parempia sovelluksia.", - "ImportListsTraktSettingsWatchListSortingHelpText": "Jos lista on katslutyyppinen, valitse sen järjestystapa." + "ImportListsTraktSettingsWatchListSortingHelpText": "Jos lista on katslutyyppinen, valitse sen järjestystapa.", + "BlocklistedAt": "Estetty {date}", + "FailedAt": "Epäonnistui {date}", + "GrabbedAt": "Kaapattu {date}" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 20e0a753b1..aedcdf99ba 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1908,5 +1908,6 @@ "ImportListsTraktSettingsUserListUsernameHelpText": "Nom d'utilisateur pour la liste à importer (laisser vide pour utiliser Auth User)", "ImportListsTraktSettingsWatchListSorting": "Tri de la liste de surveillance", "ImportListsTraktSettingsUserListTypeWatch": "Liste de surveillance des utilisateurs", - "ImportListsTraktSettingsUserListTypeWatched": "Liste des utilisateurs surveillés" + "ImportListsTraktSettingsUserListTypeWatched": "Liste des utilisateurs surveillés", + "ImportListsTraktSettingsWatchListSortingHelpText": "Si le type de liste est surveillé, sélectionnez l'ordre de tri de la liste" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 95e4b2aafe..671ce7110a 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1476,5 +1476,6 @@ "ImportListsTraktSettingsUserListTypeWatch": "Felhasználói figyelőlista", "ImportListsTraktSettingsUserListTypeWatched": "Felhasználói figyelt lista", "ImportListsTraktSettingsUserListUsernameHelpText": "Felhasználónév az importálandó listához (hagyja üresen az Auth User használatához)", - "ImportListsTraktSettingsWatchListSorting": "Figyelőlista rendezése" + "ImportListsTraktSettingsWatchListSorting": "Figyelőlista rendezése", + "ImportListsTraktSettingsWatchListSortingHelpText": "Ha a Lista típusa Figyelt, válassza ki a sorrendet a lista rendezéséhez" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 8a532aa193..8b547c1d78 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -173,7 +173,7 @@ "Discover": "Scopri", "Details": "Dettagli", "Deleted": "Cancellato", - "Delete": "Cancella", + "Delete": "Elimina", "Day": "Giorno", "Dates": "Date", "Date": "Data", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 24903dfe61..38553247a7 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -1896,5 +1896,11 @@ "Mixed": "결정된", "ImportListsTraktSettingsCertification": "인증", "ImportListsTraktSettingsGenres": "장르", - "ImportListsTraktSettingsRating": "등급" + "ImportListsTraktSettingsRating": "등급", + "ImportListsTraktSettingsYears": "년", + "ImportListsTraktSettingsAdditionalParametersHelpText": "추가 Trakt API 매개변수", + "ImportListsTraktSettingsAdditionalParameters": "매개 변수 추가", + "MediaInfoFootNote2": "MediaInfo AudioLanguages는 영어가 유일한 언어인 경우 영어를 제외합니다. MediaInfo AudioLanguagesAll을 사용하여 영어만 포함합니다", + "ImportListsTraktSettingsLimit": "한도", + "ImportListsTraktSettingsListType": "목록 유형" } diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index d88c4e5263..44d9c6f347 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -1199,5 +1199,8 @@ "Mixed": "Naprawiony", "ImportListsTraktSettingsRating": "Ocena", "ImportListsTraktSettingsCertification": "Certyfikacja", - "ImportListsTraktSettingsGenres": "Gatunki" + "ImportListsTraktSettingsGenres": "Gatunki", + "True": "Prawda", + "Umask": "Umask", + "Or": "lub" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 5cad35f503..b8d91bb93b 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1929,5 +1929,8 @@ "ImportListsTraktSettingsUserListTypeWatched": "Lista de Assistidos do Usuário", "ImportListsTraktSettingsUserListUsernameHelpText": "Nome de usuário da lista a importar (deixe em branco para usar o Usuário autenticado)", "ImportListsTraktSettingsWatchListSorting": "Classificação da Lista para Assistir", - "DownloadClientUTorrentProviderMessage": "Como o uTorrent é conhecido por CryptoWare, malware e anúncios, sugerimos mudar para um cliente melhor como Qbittorrent, Deluge ou ruTorrent." + "DownloadClientUTorrentProviderMessage": "Como o uTorrent é conhecido por CryptoWare, malware e anúncios, sugerimos mudar para um cliente melhor como Qbittorrent, Deluge ou ruTorrent.", + "BlocklistedAt": "Lista de bloqueio em {date}", + "FailedAt": "Falhou em {date}", + "GrabbedAt": "Obtido em {date}" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 55be7f9401..894a6fb1c0 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -875,7 +875,7 @@ "RenameMovies": "Filmleri Yeniden Adlandır", "RenameMoviesHelpText": "Yeniden adlandırma devre dışı bırakılırsa, {appName} mevcut dosya adını kullanacaktır", "ReplaceIllegalCharacters": "Geçersiz Karakterleri Değiştirin", - "ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse bunun yerine {appName} bunları kaldıracak", + "ReplaceIllegalCharactersHelpText": "Geçersiz karakterleri değiştirin. İşaretlenmezse, {appName} bu karakterleri silecektir", "ReplaceWithSpaceDash": "'Boşluk' ve 'Kısa Çizgi' ile değiştir", "Required": "Gerekli", "RequiredRestrictionHelpText": "Yayın, bu terimlerden en az birini içermelidir (büyük / küçük harfe duyarlı değildir)", @@ -1929,5 +1929,8 @@ "ImportListsTraktSettingsUserListUsernameHelpText": "İçe aktarılacak Liste için Kullanıcı Adı (Yetkili Kullanıcı için boş bırakın)", "ImportListsTraktSettingsWatchListSorting": "İzleme Listesi Sıralaması", "ImportListsTraktSettingsWatchListSortingHelpText": "Liste Türü İzleme ise, listeyi sıralama sırasını seçin", - "DownloadClientUTorrentProviderMessage": "uTorrent, kripto yazılımlar, kötü amaçlı yazılımlar ve reklamlarla tanındığı için qBittorrent, Deluge veya ruTorrent gibi daha iyi bir istemciye geçmenizi öneririz." + "DownloadClientUTorrentProviderMessage": "uTorrent, kripto yazılımlar, kötü amaçlı yazılımlar ve reklamlarla tanındığı için qBittorrent, Deluge veya ruTorrent gibi daha iyi bir istemciye geçmenizi öneririz.", + "BlocklistedAt": "{date} tarihinde engellendi", + "FailedAt": "{date} tarihinde başarısız oldu", + "GrabbedAt": "{date} tarihinde yakalandı" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index f09ba82571..cf01b59ecf 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1889,5 +1889,46 @@ "ImportListsTraktSettingsAuthenticateWithTrakt": "使用 Trakt 进行认证", "ImportListsTraktSettingsCertification": "分级", "ImportListsTraktSettingsGenres": "类型", - "ImportListsTraktSettingsRating": "评分" + "ImportListsTraktSettingsRating": "评分", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "按月份推荐的电影", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "按周推荐的电影", + "ImportListsTraktSettingsLimit": "限制", + "ImportListsTraktSettingsCertificationMovieHelpText": "按电影评级筛选(NR,G,PG,PG-13,R,NC-17) (逗号分隔)", + "ImportListsTraktSettingsListType": "列表类型", + "ImportListsTraktSettingsLimitMovieHelpText": "限制获取的电影数量", + "NotificationsTelegramSettingsIncludeInstanceName": "在标题中包含实例名称", + "BlocklistedAt": "在 {date} 被列入黑名单", + "FailedAt": "失败于 {date}", + "ImportListsTraktSettingsGenresMovieHelpText": "按 Trakt 类型标识符筛选电影(逗号分隔),仅适用于热门列表", + "ImportListsTraktSettingsListTypeHelpText": "要导入的列表类型", + "ImportListsTraktSettingsPopularListTypePopularMovies": "热门电影", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "按年份推荐的电影", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "按所有时间推荐的电影", + "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "最受期待的电影", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "最高票房电影", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "按月份观看最多的电影", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "按年份观看最多的电影", + "ImportListsTraktSettingsUserListTypeCollection": "用户收藏列表", + "ImportListsTraktSettingsUserListTypeWatched": "用户已观看列表", + "ImportListsTraktSettingsWatchListSorting": "观看列表排序", + "ImportListsTraktSettingsWatchListSortingHelpText": "如果列表类型为“观看”,请选择排序顺序", + "MetadataKometaDeprecated": "Kometa 文件将不再被创建,支持将在 v6 版本中完全移除", + "MovieRequested": "请求的电影", + "NotificationsTelegramSettingsIncludeInstanceNameHelpText": "可选择在通知中包含实例名称", + "ReleasePush": "发布推送", + "ReleaseSource": "发布来源", + "GrabbedAt": "获取于 {date}", + "ImportListsTraktSettingsUserListUsernameHelpText": "要从中导入列表的用户名(留空以使用授权用户)", + "UserInvokedSearch": "用户触发的搜索", + "ImportListsTraktSettingsAdditionalParametersHelpText": "额外的 Trakt API 参数", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "按周观看最多的电影", + "ImportListsTraktSettingsUserListTypeWatch": "用户观看列表", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "所有时间观看最多的电影", + "ImportListsTraktSettingsPopularListTypeTrendingMovies": "热门趋势电影", + "ImportListsTraktSettingsRatingMovieHelpText": "按评分范围筛选电影(0-100)", + "ImportListsTraktSettingsYears": "年份", + "ImportListsTraktSettingsYearsMovieHelpText": "按年份或年份范围筛选电影", + "AutoTaggingSpecificationMaximumRuntime": "最大运行时间", + "AutoTaggingSpecificationMinimumRuntime": "最小运行时间", + "DownloadClientUTorrentProviderMessage": "由于uTorrent以加密软件、恶意软件和广告而闻名,我们建议切换到更好的客户端,例如qBittorrent、Deluge或ruTorrent。" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_Hans.json b/src/NzbDrone.Core/Localization/Core/zh_Hans.json index 28374badfc..022fc24eae 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_Hans.json +++ b/src/NzbDrone.Core/Localization/Core/zh_Hans.json @@ -4,5 +4,6 @@ "Always": "总是", "Analytics": "分析", "Username": "用户名", - "Activity": "111" + "Activity": "111", + "AcceptConfirmationModal": "中文" } From 8ec60eb0a63e5c63fab012a7662f44b5e7b2f614 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 7 Mar 2025 13:53:50 +0200 Subject: [PATCH 235/579] Convert Movie Formats/Status/CollectionLabel to TypeScript --- .../src/App/State/MovieCollectionAppState.ts | 8 ++- .../Interactive/InteractiveImportRow.tsx | 3 +- .../InteractiveImport/InteractiveImport.ts | 3 +- frontend/src/Movie/Details/MovieDetails.js | 4 +- frontend/src/Movie/Movie.ts | 1 + frontend/src/Movie/MovieCollectionLabel.js | 46 --------------- frontend/src/Movie/MovieCollectionLabel.tsx | 46 +++++++++++++++ .../Movie/MovieCollectionLabelConnector.js | 57 ------------------- frontend/src/Movie/MovieFormats.js | 33 ----------- frontend/src/Movie/MovieFormats.tsx | 22 +++++++ .../Movie/{MovieStatus.js => MovieStatus.tsx} | 48 +++++++--------- frontend/src/Movie/MovieStatusConnector.js | 50 ---------------- frontend/src/Movie/useMovie.ts | 9 ++- .../Selectors/createCollectionSelector.ts | 9 +++ .../Selectors/createQueueItemSelector.ts | 13 +++++ .../src/Wanted/CutoffUnmet/CutoffUnmetRow.js | 4 +- frontend/src/Wanted/Missing/MissingRow.js | 4 +- frontend/src/typings/MovieCollection.ts | 1 + 18 files changed, 137 insertions(+), 224 deletions(-) delete mode 100644 frontend/src/Movie/MovieCollectionLabel.js create mode 100644 frontend/src/Movie/MovieCollectionLabel.tsx delete mode 100644 frontend/src/Movie/MovieCollectionLabelConnector.js delete mode 100644 frontend/src/Movie/MovieFormats.js create mode 100644 frontend/src/Movie/MovieFormats.tsx rename frontend/src/Movie/{MovieStatus.js => MovieStatus.tsx} (66%) delete mode 100644 frontend/src/Movie/MovieStatusConnector.js diff --git a/frontend/src/App/State/MovieCollectionAppState.ts b/frontend/src/App/State/MovieCollectionAppState.ts index 06d143674e..b8bf69ed86 100644 --- a/frontend/src/App/State/MovieCollectionAppState.ts +++ b/frontend/src/App/State/MovieCollectionAppState.ts @@ -1,7 +1,11 @@ -import AppSectionState from 'App/State/AppSectionState'; +import AppSectionState, { + AppSectionSaveState, +} from 'App/State/AppSectionState'; import MovieCollection from 'typings/MovieCollection'; -interface MovieCollectionAppState extends AppSectionState { +interface MovieCollectionAppState + extends AppSectionState, + AppSectionSaveState { itemMap: Record; } diff --git a/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.tsx b/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.tsx index 9abbaed134..2abcf9100b 100644 --- a/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.tsx +++ b/frontend/src/InteractiveImport/Interactive/InteractiveImportRow.tsx @@ -24,6 +24,7 @@ import { reprocessInteractiveImportItems, updateInteractiveImportItem, } from 'Store/Actions/interactiveImportActions'; +import CustomFormat from 'typings/CustomFormat'; import { SelectStateInputProps } from 'typings/props'; import Rejection from 'typings/Rejection'; import formatBytes from 'Utilities/Number/formatBytes'; @@ -52,7 +53,7 @@ interface InteractiveImportRowProps { quality?: QualityModel; languages?: Language[]; size: number; - customFormats?: object[]; + customFormats?: CustomFormat[]; customFormatScore?: number; indexerFlags: number; rejections: Rejection[]; diff --git a/frontend/src/InteractiveImport/InteractiveImport.ts b/frontend/src/InteractiveImport/InteractiveImport.ts index 4e876f8529..518092cdd2 100644 --- a/frontend/src/InteractiveImport/InteractiveImport.ts +++ b/frontend/src/InteractiveImport/InteractiveImport.ts @@ -2,6 +2,7 @@ import ModelBase from 'App/ModelBase'; import Language from 'Language/Language'; import Movie from 'Movie/Movie'; import { QualityModel } from 'Quality/Quality'; +import CustomFormat from 'typings/CustomFormat'; import Rejection from 'typings/Rejection'; export interface InteractiveImportCommandOptions { @@ -27,7 +28,7 @@ interface InteractiveImport extends ModelBase { languages: Language[]; movie?: Movie; qualityWeight: number; - customFormats: object[]; + customFormats: CustomFormat[]; indexerFlags: number; rejections: Rejection[]; movieFileId?: number; diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index d03f7e9c8b..edf9bdcee6 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -27,7 +27,7 @@ import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; import getMovieStatusDetails from 'Movie/getMovieStatusDetails'; import MovieHistoryModal from 'Movie/History/MovieHistoryModal'; -import MovieCollectionLabelConnector from 'Movie/MovieCollectionLabelConnector'; +import MovieCollectionLabel from 'Movie/MovieCollectionLabel'; import MovieGenres from 'Movie/MovieGenres'; import MoviePoster from 'Movie/MoviePoster'; import MovieInteractiveSearchModal from 'Movie/Search/MovieInteractiveSearchModal'; @@ -609,7 +609,7 @@ class MovieDetails extends Component { size={sizes.LARGE} >
-
diff --git a/frontend/src/Movie/Movie.ts b/frontend/src/Movie/Movie.ts index 96a334d7d6..30e622712e 100644 --- a/frontend/src/Movie/Movie.ts +++ b/frontend/src/Movie/Movie.ts @@ -79,6 +79,7 @@ interface Movie extends ModelBase { images: Image[]; movieFile: MovieFile; hasFile: boolean; + grabbed?: boolean; lastSearchTime?: string; isAvailable: boolean; isSaving?: boolean; diff --git a/frontend/src/Movie/MovieCollectionLabel.js b/frontend/src/Movie/MovieCollectionLabel.js deleted file mode 100644 index fb071f91c7..0000000000 --- a/frontend/src/Movie/MovieCollectionLabel.js +++ /dev/null @@ -1,46 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import MonitorToggleButton from 'Components/MonitorToggleButton'; -import styles from './MovieCollectionLabel.css'; - -class MovieCollectionLabel extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - hasPosterError: false - }; - } - - render() { - const { - title, - monitored, - onMonitorTogglePress - } = this.props; - - return ( -
- - {title} -
- ); - } -} - -MovieCollectionLabel.propTypes = { - title: PropTypes.string.isRequired, - monitored: PropTypes.bool.isRequired, - onMonitorTogglePress: PropTypes.func.isRequired -}; - -export default MovieCollectionLabel; diff --git a/frontend/src/Movie/MovieCollectionLabel.tsx b/frontend/src/Movie/MovieCollectionLabel.tsx new file mode 100644 index 0000000000..9d0c4f0227 --- /dev/null +++ b/frontend/src/Movie/MovieCollectionLabel.tsx @@ -0,0 +1,46 @@ +import React, { useCallback } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import MonitorToggleButton from 'Components/MonitorToggleButton'; +import { toggleCollectionMonitored } from 'Store/Actions/movieCollectionActions'; +import { createCollectionSelectorForHook } from 'Store/Selectors/createCollectionSelector'; +import MovieCollection from 'typings/MovieCollection'; +import styles from './MovieCollectionLabel.css'; + +interface MovieCollectionLabelProps { + tmdbId: number; +} + +function MovieCollectionLabel({ tmdbId }: MovieCollectionLabelProps) { + const { + id, + monitored, + title, + isSaving = false, + } = useSelector(createCollectionSelectorForHook(tmdbId)) as MovieCollection; + + const dispatch = useDispatch(); + + const handleMonitorTogglePress = useCallback( + (value: boolean) => { + dispatch( + toggleCollectionMonitored({ collectionId: id, monitored: value }) + ); + }, + [id, dispatch] + ); + + return ( +
+ + {title} +
+ ); +} + +export default MovieCollectionLabel; diff --git a/frontend/src/Movie/MovieCollectionLabelConnector.js b/frontend/src/Movie/MovieCollectionLabelConnector.js deleted file mode 100644 index 3d41e51e51..0000000000 --- a/frontend/src/Movie/MovieCollectionLabelConnector.js +++ /dev/null @@ -1,57 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { toggleCollectionMonitored } from 'Store/Actions/movieCollectionActions'; -import MovieCollectionLabel from './MovieCollectionLabel'; - -function createMapStateToProps() { - return createSelector( - (state, { tmdbId }) => tmdbId, - (state) => state.movieCollections.items, - (tmdbId, collections) => { - const collection = collections.find((movie) => movie.tmdbId === tmdbId); - return { - ...collection - }; - } - ); -} - -const mapDispatchToProps = { - toggleCollectionMonitored -}; - -class MovieCollectionLabelConnector extends Component { - - // - // Listeners - - onMonitorTogglePress = (monitored) => { - this.props.toggleCollectionMonitored({ - collectionId: this.props.id, - monitored - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -MovieCollectionLabelConnector.propTypes = { - tmdbId: PropTypes.number.isRequired, - id: PropTypes.number.isRequired, - monitored: PropTypes.bool.isRequired, - toggleCollectionMonitored: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MovieCollectionLabelConnector); diff --git a/frontend/src/Movie/MovieFormats.js b/frontend/src/Movie/MovieFormats.js deleted file mode 100644 index 9e8051be33..0000000000 --- a/frontend/src/Movie/MovieFormats.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Label from 'Components/Label'; -import { kinds } from 'Helpers/Props'; - -function MovieFormats({ formats }) { - return ( -
- { - formats.map((format) => { - return ( - - ); - }) - } -
- ); -} - -MovieFormats.propTypes = { - formats: PropTypes.arrayOf(PropTypes.object).isRequired -}; - -MovieFormats.defaultProps = { - formats: [] -}; - -export default MovieFormats; diff --git a/frontend/src/Movie/MovieFormats.tsx b/frontend/src/Movie/MovieFormats.tsx new file mode 100644 index 0000000000..5a8d5d4beb --- /dev/null +++ b/frontend/src/Movie/MovieFormats.tsx @@ -0,0 +1,22 @@ +import React from 'react'; +import Label from 'Components/Label'; +import { kinds } from 'Helpers/Props'; +import CustomFormat from 'typings/CustomFormat'; + +interface MovieFormatsProps { + formats: CustomFormat[]; +} + +function MovieFormats({ formats }: MovieFormatsProps) { + return ( +
+ {formats.map(({ id, name }) => ( + + ))} +
+ ); +} + +export default MovieFormats; diff --git a/frontend/src/Movie/MovieStatus.js b/frontend/src/Movie/MovieStatus.tsx similarity index 66% rename from frontend/src/Movie/MovieStatus.js rename to frontend/src/Movie/MovieStatus.tsx index be54b63801..f8f35d5c0b 100644 --- a/frontend/src/Movie/MovieStatus.js +++ b/frontend/src/Movie/MovieStatus.tsx @@ -1,32 +1,40 @@ -import PropTypes from 'prop-types'; import React from 'react'; +import { useSelector } from 'react-redux'; import QueueDetails from 'Activity/Queue/QueueDetails'; import Icon from 'Components/Icon'; import ProgressBar from 'Components/ProgressBar'; import { icons, kinds, sizes } from 'Helpers/Props'; +import Movie from 'Movie/Movie'; +import useMovie, { MovieEntity } from 'Movie/useMovie'; +import useMovieFile from 'MovieFile/useMovieFile'; +import { createQueueItemSelectorForHook } from 'Store/Selectors/createQueueItemSelector'; import translate from 'Utilities/String/translate'; import MovieQuality from './MovieQuality'; import styles from './MovieStatus.css'; -function MovieStatus(props) { +interface MovieStatusProps { + movieId: number; + movieEntity?: MovieEntity; + movieFileId: number | undefined; +} + +function MovieStatus({ movieId, movieFileId }: MovieStatusProps) { const { isAvailable, monitored, - grabbed, - queueItem, - movieFile - } = props; + grabbed = false, + } = useMovie(movieId) as Movie; + + const queueItem = useSelector(createQueueItemSelectorForHook(movieId)); + const movieFile = useMovieFile(movieFileId); const hasMovieFile = !!movieFile; const isQueued = !!queueItem; if (isQueued) { - const { - sizeleft, - size - } = queueItem; + const { sizeleft, size } = queueItem; - const progress = size ? (100 - sizeleft / size * 100) : 0; + const progress = size ? 100 - (sizeleft / size) * 100 : 0; return (
@@ -86,30 +94,16 @@ function MovieStatus(props) { if (isAvailable) { return (
- +
); } return (
- +
); } -MovieStatus.propTypes = { - isAvailable: PropTypes.bool.isRequired, - monitored: PropTypes.bool.isRequired, - grabbed: PropTypes.bool, - queueItem: PropTypes.object, - movieFile: PropTypes.object -}; - export default MovieStatus; diff --git a/frontend/src/Movie/MovieStatusConnector.js b/frontend/src/Movie/MovieStatusConnector.js deleted file mode 100644 index 25b104d35b..0000000000 --- a/frontend/src/Movie/MovieStatusConnector.js +++ /dev/null @@ -1,50 +0,0 @@ -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import MovieStatus from 'Movie/MovieStatus'; -import createMovieFileSelector from 'Store/Selectors/createMovieFileSelector'; -import { createMovieByEntitySelector } from 'Store/Selectors/createMovieSelector'; -import createQueueItemSelector from 'Store/Selectors/createQueueItemSelector'; - -function createMapStateToProps() { - return createSelector( - createMovieByEntitySelector(), - createQueueItemSelector(), - createMovieFileSelector(), - (movie, queueItem, movieFile) => { - const result = _.pick(movie, [ - 'isAvailable', - 'monitored', - 'grabbed' - ]); - - result.queueItem = queueItem; - result.movieFile = movieFile; - - return result; - } - ); -} - -class MovieStatusConnector extends Component { - - // - // Render - - render() { - return ( - - ); - } -} - -MovieStatusConnector.propTypes = { - movieId: PropTypes.number.isRequired, - movieFileId: PropTypes.number.isRequired -}; - -export default connect(createMapStateToProps, null)(MovieStatusConnector); diff --git a/frontend/src/Movie/useMovie.ts b/frontend/src/Movie/useMovie.ts index c1f8cedb87..50a51cc091 100644 --- a/frontend/src/Movie/useMovie.ts +++ b/frontend/src/Movie/useMovie.ts @@ -2,6 +2,13 @@ import { useSelector } from 'react-redux'; import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; +export type MovieEntity = + | 'calendar' + | 'movies' + | 'interactiveImport.movies' + | 'wanted.cutoffUnmet' + | 'wanted.missing'; + export function createMovieSelector(movieId?: number) { return createSelector( (state: AppState) => state.movies.itemMap, @@ -12,7 +19,7 @@ export function createMovieSelector(movieId?: number) { ); } -function useMovie(movieId?: number) { +function useMovie(movieId: number | undefined) { return useSelector(createMovieSelector(movieId)); } diff --git a/frontend/src/Store/Selectors/createCollectionSelector.ts b/frontend/src/Store/Selectors/createCollectionSelector.ts index 9b05202272..caab9ae6d5 100644 --- a/frontend/src/Store/Selectors/createCollectionSelector.ts +++ b/frontend/src/Store/Selectors/createCollectionSelector.ts @@ -1,6 +1,15 @@ import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; +export function createCollectionSelectorForHook(tmdbId: number) { + return createSelector( + (state: AppState) => state.movieCollections.items, + (collections) => { + return collections.find((item) => item.tmdbId === tmdbId); + } + ); +} + function createCollectionSelector() { return createSelector( (_: AppState, { collectionId }: { collectionId: number }) => collectionId, diff --git a/frontend/src/Store/Selectors/createQueueItemSelector.ts b/frontend/src/Store/Selectors/createQueueItemSelector.ts index ab161f5ee2..4a6afe5c67 100644 --- a/frontend/src/Store/Selectors/createQueueItemSelector.ts +++ b/frontend/src/Store/Selectors/createQueueItemSelector.ts @@ -1,6 +1,19 @@ import { createSelector } from 'reselect'; import AppState from 'App/State/AppState'; +export function createQueueItemSelectorForHook(movieId: number) { + return createSelector( + (state: AppState) => state.queue.details.items, + (details) => { + if (!movieId || !details) { + return null; + } + + return details.find((item) => item.movieId === movieId); + } + ); +} + function createQueueItemSelector() { return createSelector( (_: AppState, { movieId }: { movieId: number }) => movieId, diff --git a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js index eb83e34dd2..43c9ab9fbc 100644 --- a/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js +++ b/frontend/src/Wanted/CutoffUnmet/CutoffUnmetRow.js @@ -6,7 +6,7 @@ import TableSelectCell from 'Components/Table/Cells/TableSelectCell'; import TableRow from 'Components/Table/TableRow'; import movieEntities from 'Movie/movieEntities'; import MovieSearchCell from 'Movie/MovieSearchCell'; -import MovieStatusConnector from 'Movie/MovieStatusConnector'; +import MovieStatus from 'Movie/MovieStatus'; import MovieTitleLink from 'Movie/MovieTitleLink'; import MovieFileLanguages from 'MovieFile/MovieFileLanguages'; import styles from './CutoffUnmetRow.css'; @@ -127,7 +127,7 @@ function CutoffUnmetRow(props) { key={name} className={styles.status} > - - Date: Fri, 7 Mar 2025 15:52:23 +0200 Subject: [PATCH 236/579] Convert MoveMovieModal to TypeScript Co-authored-by: Mark McDowall --- .../src/Movie/MoveMovie/MoveMovieModal.css | 4 + .../Movie/MoveMovie/MoveMovieModal.css.d.ts | 1 + .../src/Movie/MoveMovie/MoveMovieModal.js | 93 ------------------- .../src/Movie/MoveMovie/MoveMovieModal.tsx | 82 ++++++++++++++++ src/NzbDrone.Core/Localization/Core/ar.json | 10 +- src/NzbDrone.Core/Localization/Core/bg.json | 10 +- src/NzbDrone.Core/Localization/Core/ca.json | 10 +- src/NzbDrone.Core/Localization/Core/cs.json | 10 +- src/NzbDrone.Core/Localization/Core/da.json | 10 +- src/NzbDrone.Core/Localization/Core/de.json | 10 +- src/NzbDrone.Core/Localization/Core/el.json | 10 +- src/NzbDrone.Core/Localization/Core/en.json | 10 +- src/NzbDrone.Core/Localization/Core/es.json | 10 +- src/NzbDrone.Core/Localization/Core/fi.json | 10 +- src/NzbDrone.Core/Localization/Core/fr.json | 10 +- src/NzbDrone.Core/Localization/Core/he.json | 10 +- src/NzbDrone.Core/Localization/Core/hi.json | 10 +- src/NzbDrone.Core/Localization/Core/hu.json | 10 +- src/NzbDrone.Core/Localization/Core/is.json | 10 +- src/NzbDrone.Core/Localization/Core/it.json | 10 +- src/NzbDrone.Core/Localization/Core/ja.json | 10 +- src/NzbDrone.Core/Localization/Core/ko.json | 10 +- src/NzbDrone.Core/Localization/Core/nl.json | 10 +- src/NzbDrone.Core/Localization/Core/pl.json | 10 +- src/NzbDrone.Core/Localization/Core/pt.json | 10 +- .../Localization/Core/pt_BR.json | 10 +- src/NzbDrone.Core/Localization/Core/ro.json | 10 +- src/NzbDrone.Core/Localization/Core/ru.json | 10 +- src/NzbDrone.Core/Localization/Core/sv.json | 10 +- src/NzbDrone.Core/Localization/Core/th.json | 10 +- src/NzbDrone.Core/Localization/Core/tr.json | 10 +- src/NzbDrone.Core/Localization/Core/uk.json | 10 +- src/NzbDrone.Core/Localization/Core/vi.json | 10 +- .../Localization/Core/zh_CN.json | 10 +- 34 files changed, 237 insertions(+), 243 deletions(-) delete mode 100644 frontend/src/Movie/MoveMovie/MoveMovieModal.js create mode 100644 frontend/src/Movie/MoveMovie/MoveMovieModal.tsx diff --git a/frontend/src/Movie/MoveMovie/MoveMovieModal.css b/frontend/src/Movie/MoveMovie/MoveMovieModal.css index c1e247a50c..c7d8b1ed1d 100644 --- a/frontend/src/Movie/MoveMovie/MoveMovieModal.css +++ b/frontend/src/Movie/MoveMovie/MoveMovieModal.css @@ -3,3 +3,7 @@ margin-right: auto; } + +.folderRenameMessage { + margin-top: 20px; +} diff --git a/frontend/src/Movie/MoveMovie/MoveMovieModal.css.d.ts b/frontend/src/Movie/MoveMovie/MoveMovieModal.css.d.ts index 0475f5a86d..3fa13ff663 100644 --- a/frontend/src/Movie/MoveMovie/MoveMovieModal.css.d.ts +++ b/frontend/src/Movie/MoveMovie/MoveMovieModal.css.d.ts @@ -2,6 +2,7 @@ // Please do not change this file! interface CssExports { 'doNotMoveButton': string; + 'folderRenameMessage': string; } export const cssExports: CssExports; export default cssExports; diff --git a/frontend/src/Movie/MoveMovie/MoveMovieModal.js b/frontend/src/Movie/MoveMovie/MoveMovieModal.js deleted file mode 100644 index c395561bb1..0000000000 --- a/frontend/src/Movie/MoveMovie/MoveMovieModal.js +++ /dev/null @@ -1,93 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Button from 'Components/Link/Button'; -import Modal from 'Components/Modal/Modal'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import { kinds, sizes } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import styles from './MoveMovieModal.css'; - -function MoveMovieModal(props) { - const { - originalPath, - destinationPath, - destinationRootFolder, - isOpen, - onModalClose, - onSavePress, - onMoveMoviePress - } = props; - - if ( - isOpen && - !originalPath && - !destinationPath && - !destinationRootFolder - ) { - console.error('orginalPath and destinationPath OR destinationRootFolder must be provided'); - } - - return ( - - - - {translate('MoveFiles')} - - - - { - destinationRootFolder ? - translate('MoveFolders1', [destinationRootFolder]) : - translate('MoveFolders2', [originalPath, destinationPath]) - } - { - destinationRootFolder ? -
- {translate('FolderMoveRenameWarning')} -
: - null - } -
- - - - - - -
-
- ); -} - -MoveMovieModal.propTypes = { - originalPath: PropTypes.string, - destinationPath: PropTypes.string, - destinationRootFolder: PropTypes.string, - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onMoveMoviePress: PropTypes.func.isRequired -}; - -export default MoveMovieModal; diff --git a/frontend/src/Movie/MoveMovie/MoveMovieModal.tsx b/frontend/src/Movie/MoveMovie/MoveMovieModal.tsx new file mode 100644 index 0000000000..75d0764b4c --- /dev/null +++ b/frontend/src/Movie/MoveMovie/MoveMovieModal.tsx @@ -0,0 +1,82 @@ +import React from 'react'; +import Button from 'Components/Link/Button'; +import Modal from 'Components/Modal/Modal'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import { kinds, sizes } from 'Helpers/Props'; +import translate from 'Utilities/String/translate'; +import styles from './MoveMovieModal.css'; + +interface MoveMovieModalProps { + originalPath?: string; + destinationPath?: string; + destinationRootFolder?: string; + isOpen: boolean; + onModalClose: () => void; + onSavePress: () => void; + onMoveMoviePress: () => void; +} + +function MoveMovieModal({ + originalPath, + destinationPath, + destinationRootFolder, + isOpen, + onModalClose, + onSavePress, + onMoveMoviePress, +}: MoveMovieModalProps) { + if (isOpen && !originalPath && !destinationPath && !destinationRootFolder) { + console.error( + 'originalPath and destinationPath OR destinationRootFolder must be provided' + ); + } + + return ( + + + {translate('MoveFiles')} + + + {destinationRootFolder + ? translate('MoveMovieFoldersToRootFolder', { + destinationRootFolder, + }) + : null} + + {originalPath && destinationPath + ? translate('MoveMovieFoldersToNewPath', { + originalPath, + destinationPath, + }) + : null} + + {destinationRootFolder ? ( +
+ {translate('MoveMovieFoldersRenameFolderWarning')} +
+ ) : null} +
+ + + + + + +
+
+ ); +} + +export default MoveMovieModal; diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 3b2f1d19f7..c6beb3ee5d 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -1,7 +1,7 @@ { "YouCanAlsoSearch": "يمكنك أيضًا البحث باستخدام معرف TMDb أو معرف IMDb للفيلم. على سبيل المثال \"tmdb: 71663\"", "Yesterday": "في الامس", - "YesMoveFiles": "نعم ، انقل الملفات", + "MoveMovieFoldersMoveFiles": "نعم ، انقل الملفات", "YesCancel": "نعم إلغاء", "Year": "عام", "WouldYouLikeToRestoreBackup": "هل ترغب في استعادة النسخة الاحتياطية {0}؟", @@ -250,7 +250,7 @@ "NoResultsFound": "لم يتم العثور على نتائج", "None": "لا شيء", "NoMoviesExist": "لم يتم العثور على أفلام ، للبدء ، ستحتاج إلى إضافة فيلم جديد أو استيراد بعض الأفلام الموجودة.", - "NoMoveFilesSelf": " لا ، سأقوم بنقل الملفات بنفسي", + "MoveMovieFoldersDontMoveFiles": " لا ، سأقوم بنقل الملفات بنفسي", "NoMinimumForAnyRuntime": "لا يوجد حد أدنى لأي وقت تشغيل", "NoMatchFound": "لا يوجد تطابق!", "NoLogFiles": "لا توجد ملفات سجل", @@ -421,7 +421,7 @@ "Forecast": "توقعات", "FollowPerson": "اتبع الشخص", "Folders": "المجلدات", - "FolderMoveRenameWarning": "سيؤدي هذا أيضًا إلى إعادة تسمية مجلد الفيلم لكل تنسيق مجلد الفيلم في الإعدادات.", + "MoveMovieFoldersRenameFolderWarning": "سيؤدي هذا أيضًا إلى إعادة تسمية مجلد الفيلم لكل تنسيق مجلد الفيلم في الإعدادات.", "Folder": "مجلد", "FocusSearchBox": "التركيز على مربع البحث", "Fixed": "ثابت", @@ -829,8 +829,8 @@ "MovieChat": "دردشة الفيلم", "MovieAlreadyExcluded": "الفيلم مستبعد بالفعل", "Movie": "فيلم", - "MoveFolders2": "هل تريد نقل ملفات الأفلام من \"{0}\" إلى \"{1}\"؟", - "MoveFolders1": "هل تريد نقل مجلدات الفيلم إلى \"{0}\"؟", + "MoveMovieFoldersToNewPath": "هل تريد نقل ملفات الأفلام من \"{0}\" إلى \"{1}\"؟", + "MoveMovieFoldersToRootFolder": "هل تريد نقل مجلدات الفيلم إلى \"{0}\"؟", "MoveFiles": "نقل الملفات", "MountMovieHealthCheckMessage": "تم تثبيت الحامل الذي يحتوي على مسار فيلم للقراءة فقط: ", "MoreInfo": "مزيد من المعلومات", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 440f130858..0ed5845151 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -239,7 +239,7 @@ "Fixed": "Фиксирана", "FocusSearchBox": "Фокусно поле за търсене", "Folder": "Папка", - "FolderMoveRenameWarning": "Това също ще преименува папката с филм във формата на папката с филм в настройките.", + "MoveMovieFoldersRenameFolderWarning": "Това също ще преименува папката с филм във формата на папката с филм в настройките.", "Folders": "Папки", "FollowPerson": "Следвайте човек", "Forecast": "Прогноза", @@ -355,7 +355,7 @@ "MonitorMovie": "Монитор на филм", "Months": "Месеци", "MoreInfo": "Повече информация", - "MoveFolders1": "Искате ли да преместите папките с филми в „{0}“?", + "MoveMovieFoldersToRootFolder": "Искате ли да преместите папките с филми в „{0}“?", "Movie": "Филм", "MovieAlreadyExcluded": "Филмът вече е изключен", "MovieChat": "Чат за филми", @@ -662,13 +662,13 @@ "WouldYouLikeToRestoreBackup": "Искате ли да възстановите архива {0}?", "Year": "Година", "YesCancel": "Да, Отказ", - "YesMoveFiles": "Да, премести файловете", + "MoveMovieFoldersMoveFiles": "Да, премести файловете", "Yesterday": "Вчера", "YouCanAlsoSearch": "Можете също да търсите с помощта на TMDb ID или IMDb ID на филм. напр. `tmdb: 71663`", "MaintenanceRelease": "Издание за поддръжка: поправки на грешки и други подобрения. Вижте История на комисиите на Github за повече подробности", "MissingMonitoredAndConsideredAvailable": "Липсва (Мониториран)", "MissingNotMonitored": "Липсва (без наблюдение)", - "MoveFolders2": "Искате ли да преместите филмовите файлове от „{0}“ в „{1}“?", + "MoveMovieFoldersToNewPath": "Искате ли да преместите филмовите файлове от „{0}“ в „{1}“?", "MovieDetailsPreviousMovie": "Подробности за филма: Предишен филм", "MovieEditor": "Редактор на филми", "MovieExcludedFromAutomaticAdd": "Филмът е изключен от автоматично добавяне", @@ -829,7 +829,7 @@ "PendingChangesDiscardChanges": "Изхвърлете промените и оставете", "PendingChangesStayReview": "Останете и прегледайте промените", "Password": "Парола", - "NoMoveFilesSelf": " Не, сам ще преместя досиетата", + "MoveMovieFoldersDontMoveFiles": " Не, сам ще преместя досиетата", "ShowGenres": "Показване на жанрове", "SuggestTranslationChange": "Предложете промяна на превода", "NoMoviesExist": "Не са намерени филми, за да започнете, ще искате да добавите нов филм или да импортирате някои съществуващи.", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index a3d297c3f3..3ed5fa74fd 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -92,8 +92,8 @@ "InteractiveImport": "Importació interactiva", "MaximumSize": "Mida màxima", "MaximumSizeHelpText": "Mida màxima per a una versió que es pot capturar en MB. Establiu a zero per a establir-lo en il·limitat", - "MoveFolders1": "Voleu moure les carpetes de pel·lícules a '{0}'?", - "MoveFolders2": "Voleu moure els fitxers de la pel·lícula de '{0}' a '{1}'?", + "MoveMovieFoldersToRootFolder": "Voleu moure les carpetes de pel·lícules a '{0}'?", + "MoveMovieFoldersToNewPath": "Voleu moure els fitxers de la pel·lícula de '{0}' a '{1}'?", "MovieEditor": "Editor de pel·lícules", "MovieFilesTotaling": "Total de fitxers de pel·lícules", "MovieFolderFormat": "Format de carpeta de pel·lícules", @@ -501,7 +501,7 @@ "FileNameTokens": "Testimonis de nom de fitxer", "Files": "Fitxers", "FocusSearchBox": "Posa el focus a la caixa de cerca", - "FolderMoveRenameWarning": "Això també reanomenarà la carpeta de pel·lícules segons el format de la carpeta de pel·lícules a la configuració.", + "MoveMovieFoldersRenameFolderWarning": "Això també reanomenarà la carpeta de pel·lícules segons el format de la carpeta de pel·lícules a la configuració.", "Forecast": "Previsió", "Formats": "Formats", "SupportedDownloadClientsMoreInfo": "Per a obtenir més informació sobre els clients de baixada individuals, feu clic als botons de més informació.", @@ -629,7 +629,7 @@ "NoLogFiles": "No hi ha fitxers de registre", "NoMatchFound": "No s'ha trobat cap coincidència!", "NoMinimumForAnyRuntime": "No hi ha mínim per a cap temps d'execució", - "NoMoveFilesSelf": " No, moure els fitxers jo mateix", + "MoveMovieFoldersDontMoveFiles": " No, moure els fitxers jo mateix", "NoMoviesExist": "No s'han trobat pel·lícules, per a començar, podeu afegir una pel·lícula nova o importar-ne algunes existents.", "None": "Cap", "NoResultsFound": "Sense resultats", @@ -936,7 +936,7 @@ "WhitelistedSubtitleTags": "Etiquetes de subtítols a la llista blanca", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Voleu restaurar la còpia de seguretat '{name}'?", - "YesMoveFiles": "Si, mou els fitxers", + "MoveMovieFoldersMoveFiles": "Si, mou els fitxers", "Yesterday": "Ahir", "Agenda": "Agenda", "InstanceName": "Nom de la instància", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 5922d51392..f475106816 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -251,7 +251,7 @@ "NextExecution": "Další spuštění", "NoAlternativeTitles": "Žádné alternativní tituly.", "NoMinimumForAnyRuntime": "Žádné minimum za běhu", - "NoMoveFilesSelf": " Ne, přesunu soubory sám", + "MoveMovieFoldersDontMoveFiles": " Ne, přesunu soubory sám", "NoMoviesExist": "Nebyly nalezeny žádné filmy. Chcete-li začít, budete chtít přidat nový film nebo importovat některé stávající.", "DatabaseMigration": "Migrace databáze", "ImportExtraFiles": "Importujte další soubory", @@ -588,7 +588,7 @@ "FirstDayOfWeek": "První den v týdnu", "FocusSearchBox": "Zaostřovací vyhledávací pole", "Folder": "Složka", - "FolderMoveRenameWarning": "Tím se také přejmenuje složka filmu na formát složky filmu v nastavení.", + "MoveMovieFoldersRenameFolderWarning": "Tím se také přejmenuje složka filmu na formát složky filmu v nastavení.", "Folders": "Složky", "FollowPerson": "Sledujte osobu", "Forecast": "Předpověď", @@ -687,7 +687,7 @@ "MonitorMovie": "Monitorujte film", "Months": "Měsíce", "MoreInfo": "Více informací", - "MoveFolders1": "Chcete přesunout složky filmu do složky „{0}“?", + "MoveMovieFoldersToRootFolder": "Chcete přesunout složky filmu do složky „{0}“?", "Movie": "Film", "MovieAlreadyExcluded": "Film je již vyloučen", "MovieChat": "Filmový chat", @@ -933,13 +933,13 @@ "WouldYouLikeToRestoreBackup": "Chcete obnovit zálohu {0}?", "Year": "Rok", "YesCancel": "Ano, zrušit", - "YesMoveFiles": "Ano, přesuňte soubory", + "MoveMovieFoldersMoveFiles": "Ano, přesuňte soubory", "Yesterday": "Včera", "YouCanAlsoSearch": "Můžete také hledat pomocí ID TMDb nebo IMDb ID filmu. např. `tmdb: 71663`", "MaintenanceRelease": "Údržbové vydání: opravy chyb a další vylepšení. Další podrobnosti najdete v GitHub Commit History", "MissingMonitoredAndConsideredAvailable": "Chybí (sledováno)", "MissingNotMonitored": "Chybí (nesledováno)", - "MoveFolders2": "Chcete přesunout filmové soubory z „{0}“ do „{1}“?", + "MoveMovieFoldersToNewPath": "Chcete přesunout filmové soubory z „{0}“ do „{1}“?", "MovieEditor": "Editor filmů", "MovieExcludedFromAutomaticAdd": "Film je vyloučen z automatického přidání", "Search": "Vyhledávání", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index ad11842ece..2e844c7a07 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -271,7 +271,7 @@ "NoEventsFound": "Ingen begivenheder fundet", "NoLinks": "Ingen links", "NoMinimumForAnyRuntime": "Intet minimum for enhver driftstid", - "NoMoveFilesSelf": " Nej, jeg flytter filerne selv", + "MoveMovieFoldersDontMoveFiles": " Nej, jeg flytter filerne selv", "NoMoviesExist": "Ingen film fundet. For at komme i gang vil du tilføje en ny film eller importere nogle eksisterende.", "None": "Ingen", "NoResultsFound": "Ingen resultater fundet", @@ -569,7 +569,7 @@ "FilterPlaceHolder": "Søg i film", "Fixed": "Fast", "FocusSearchBox": "Fokus søgefelt", - "FolderMoveRenameWarning": "Dette omdøber også filmmappen i henhold til filmmappens format i indstillingerne.", + "MoveMovieFoldersRenameFolderWarning": "Dette omdøber også filmmappen i henhold til filmmappens format i indstillingerne.", "Folders": "Mapper", "FollowPerson": "Følg Person", "Forecast": "Vejrudsigt", @@ -649,7 +649,7 @@ "MonitorMovie": "Overvåg film", "Months": "Måneder", "MoreInfo": "Mere info", - "MoveFolders1": "Vil du flytte filmmapperne til '{0}'?", + "MoveMovieFoldersToRootFolder": "Vil du flytte filmmapperne til '{0}'?", "Movie": "Film", "MovieAlreadyExcluded": "Film allerede ekskluderet", "MovieChat": "Filmchat", @@ -933,13 +933,13 @@ "WouldYouLikeToRestoreBackup": "Vil du gendanne sikkerhedskopien »{name}«?", "Year": "År", "YesCancel": "Ja, Annuller", - "YesMoveFiles": "Ja, flyt filerne", + "MoveMovieFoldersMoveFiles": "Ja, flyt filerne", "Yesterday": "I går", "YouCanAlsoSearch": "Du kan også søge ved hjælp af TMDb ID eller IMDb ID for en film. f.eks. `tmdb: 71663`", "MaintenanceRelease": "Vedligeholdelsesfrigivelse: fejlrettelser og andre forbedringer. Se Github Commit History for flere detaljer", "MissingMonitoredAndConsideredAvailable": "Mangler (overvåges)", "MissingNotMonitored": "Mangler (ikke overvåget)", - "MoveFolders2": "Vil du flytte filmfilerne fra '{0}' til '{1}'?", + "MoveMovieFoldersToNewPath": "Vil du flytte filmfilerne fra '{0}' til '{1}'?", "MovieDetailsPreviousMovie": "Filmdetaljer: Forrige film", "MovieEditor": "Filmredaktør", "MovieExcludedFromAutomaticAdd": "Film ekskluderet fra automatisk tilføjelse", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index f042ab0906..e8aff45e62 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -760,7 +760,7 @@ "ChmodFolderHelpText": "Oktal, angewendet beim Importieren/Umbenennen auf Medienordner und -dateien (ohne Ausführungsbits)", "ChmodFolder": "chmod Ordner", "FileNameTokens": "Dateinamen Token", - "YesMoveFiles": "Ja, Dateien verschieben", + "MoveMovieFoldersMoveFiles": "Ja, Dateien verschieben", "WouldYouLikeToRestoreBackup": "Willst du das Backup '{name}' wiederherstellen?", "Wiki": "Wiki", "WhatsNew": "Was gibt's Neues?", @@ -834,7 +834,7 @@ "NoResultsFound": "Keine Ergebnisse gefunden", "None": "Keine", "NoMoviesExist": "Keine Filme gefunden. Zum Starten solltest du einen Film hinzufügen oder vorhandene Importieren.", - "NoMoveFilesSelf": " Nein, Dateien selbst verschieben", + "MoveMovieFoldersDontMoveFiles": " Nein, Dateien selbst verschieben", "NoListRecommendations": "Keine Listeneinträge oder Empfehlungen gefunden. Zum Start solltest du einen Film hinzufügen, vorhandene importieren oder eine Liste hinzufügen.", "NoLinks": "Keine Links", "NoEventsFound": "Keine Ereignisse gefunden", @@ -846,7 +846,7 @@ "MovieInvalidFormat": "Film: Ungütiges Format", "MovieFilesTotaling": "Filmdateien insgesamt", "MovieChat": "Filmchat", - "MoveFolders1": "Wilst du die Filmordner nach '{0}' verschieben ?", + "MoveMovieFoldersToRootFolder": "Wilst du die Filmordner nach '{0}' verschieben ?", "Months": "Monate", "MonitoredStatus": "Überwacht/Status", "Monday": "Montag", @@ -876,7 +876,7 @@ "HttpHttps": "HTTP(S)", "Hours": "Stunden", "HomePage": "Hauptseite", - "FolderMoveRenameWarning": "Dies wird auch den Filmordner nach dem Filmordnerformat aus den Einstellungen umbenennen.", + "MoveMovieFoldersRenameFolderWarning": "Dies wird auch den Filmordner nach dem Filmordnerformat aus den Einstellungen umbenennen.", "FeatureRequests": "Feature Anfragen", "FailedToLoadMovieFromAPI": "Film konnte nicht über die API geladen werden", "ExternalUpdater": "{appName} ist so konfiguriert, dass es einen externen Aktualisierungsmechanismus verwendet", @@ -931,7 +931,7 @@ "AddDelayProfile": "Verzögerungsprofil hinzufügen", "Add": "Hinzufügen", "RequiredRestrictionHelpText": "Das Release mus mindesten eines der Begriffe beinhalten ( Groß-/Kleinschreibung wird nicht beachtet )", - "MoveFolders2": "Bist du sicher, dass du die Filmdateien von '{0}' nach '{1}' verschieben willst ?", + "MoveMovieFoldersToNewPath": "Bist du sicher, dass du die Filmdateien von '{0}' nach '{1}' verschieben willst ?", "ImportLibrary": "Importieren", "ImportNotForDownloads": "Benutze dies NICHT um abgeschlossene Downloads deines Download Clients hinzuzufügen. Dies ist NUR für vorhandene organisierte Mediatheken und nicht für unsortierte Dateien.", "SqliteVersionCheckUpgradeRequiredMessage": "Die derzeit installierte SQLite-Version {0} wird nicht mehr unterstützt. Bitte aktualisieren Sie SQLite auf mindestens Version {1}.", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 9999afe3c2..8ff5b110ff 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -121,7 +121,7 @@ "ImportListsSettingsSummary": "Εισαγωγή λιστών, εξαιρέσεις λίστας", "ManualImportSelectMovie": "Μη αυτόματη εισαγωγή - Επιλέξτε ταινία", "MoreInfo": "Περισσότερες πληροφορίες", - "MoveFolders1": "Θέλετε να μετακινήσετε τους φακέλους της ταινίας στο \"{0}\";", + "MoveMovieFoldersToRootFolder": "Θέλετε να μετακινήσετε τους φακέλους της ταινίας στο \"{0}\";", "MultiLanguage": "Πολλαπλών γλωσσών", "NoListRecommendations": "Δεν βρέθηκαν στοιχεία λίστας ή προτάσεις, για να ξεκινήσετε θα θέλετε να προσθέσετε μια νέα ταινία, να εισαγάγετε ορισμένες υπάρχουσες ή να προσθέσετε μια λίστα.", "PreferIndexerFlagsHelpText": "Προτεραιότητα στις κυκλοφορίες με ειδικές σημαίες", @@ -261,7 +261,7 @@ "NoEventsFound": "Δεν βρέθηκαν συμβάντα", "NoLinks": "Χωρίς συνδέσμους", "NoMinimumForAnyRuntime": "Χωρίς ελάχιστο για κάθε χρόνο εκτέλεσης", - "NoMoveFilesSelf": " Όχι, θα μετακινήσω τον εαυτό μου τα αρχεία", + "MoveMovieFoldersDontMoveFiles": " Όχι, θα μετακινήσω τον εαυτό μου τα αρχεία", "Ended": "Έληξε", "NoMoviesExist": "Δεν βρέθηκαν ταινίες, για να ξεκινήσετε θα θέλετε να προσθέσετε μια νέα ταινία ή να εισαγάγετε ορισμένες υπάρχουσες.", "NoResultsFound": "Δεν βρέθηκαν αποτελέσματα", @@ -551,7 +551,7 @@ "ChangeFileDateHelpText": "Αλλαγή ημερομηνίας αρχείου κατά την εισαγωγή / επανασύνδεση", "FileNames": "Ονόματα αρχείων", "FocusSearchBox": "Πλαίσιο αναζήτησης εστίασης", - "FolderMoveRenameWarning": "Αυτό θα μετονομάσει επίσης το φάκελο ταινίας ανά μορφή φακέλου ταινίας στις ρυθμίσεις.", + "MoveMovieFoldersRenameFolderWarning": "Αυτό θα μετονομάσει επίσης το φάκελο ταινίας ανά μορφή φακέλου ταινίας στις ρυθμίσεις.", "FollowPerson": "Ακολουθήστε το άτομο", "SupportedListsMoreInfo": "Για περισσότερες πληροφορίες σχετικά με τις μεμονωμένες λίστες εισαγωγής, κάντε κλικ στα κουμπιά πληροφοριών.", "SupportedIndexersMoreInfo": "Για περισσότερες πληροφορίες σχετικά με τους μεμονωμένους δείκτες, κάντε κλικ στα κουμπιά πληροφοριών.", @@ -933,13 +933,13 @@ "WouldYouLikeToRestoreBackup": "Θέλετε να επαναφέρετε το αντίγραφο ασφαλείας {0};", "Year": "Ετος", "YesCancel": "Ναι, Ακύρωση", - "YesMoveFiles": "Ναι, Μετακινήστε τα αρχεία", + "MoveMovieFoldersMoveFiles": "Ναι, Μετακινήστε τα αρχεία", "Yesterday": "Εχθές", "YouCanAlsoSearch": "Μπορείτε επίσης να πραγματοποιήσετε αναζήτηση χρησιμοποιώντας TMDb ID ή IMDb ID μιας ταινίας. π.χ. \"tmdb: 71663\"", "MaintenanceRelease": "Έκδοση συντήρησης: επιδιορθώσεις σφαλμάτων και άλλες βελτιώσεις. Δείτε το Github Commit History για περισσότερες λεπτομέρειες", "MissingMonitoredAndConsideredAvailable": "Λείπει (παρακολουθείται)", "MissingNotMonitored": "Λείπει (Χωρίς παρακολούθηση)", - "MoveFolders2": "Θέλετε να μετακινήσετε τα αρχεία ταινιών από το \"{0}\" στο \"{1}\";", + "MoveMovieFoldersToNewPath": "Θέλετε να μετακινήσετε τα αρχεία ταινιών από το \"{0}\" στο \"{1}\";", "MovieDetailsPreviousMovie": "Λεπτομέρειες ταινίας: Προηγούμενη ταινία", "MovieEditor": "Πρόγραμμα επεξεργασίας ταινιών", "MovieExcludedFromAutomaticAdd": "Η ταινία εξαιρείται από την αυτόματη προσθήκη", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index 77a1a701a2..1d61b6775c 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -673,7 +673,6 @@ "Fixed": "Fixed", "FocusSearchBox": "Focus Search Box", "Folder": "Folder", - "FolderMoveRenameWarning": "This will also rename the movie folder per the movie folder format in settings.", "FolderNameTokens": "Folder Name Tokens", "Folders": "Folders", "FollowPerson": "Follow Person", @@ -1034,8 +1033,11 @@ "MountMovieHealthCheckMessage": "Mount containing a movie path is mounted read-only: ", "MoveAutomatically": "Move Automatically", "MoveFiles": "Move Files", - "MoveFolders1": "Would you like to move the movie folders to '{0}' ?", - "MoveFolders2": "Would you like to move the movie files from '{0}' to '{1}' ?", + "MoveMovieFoldersDontMoveFiles": "No, I'll Move the Files Myself", + "MoveMovieFoldersMoveFiles": "Yes, Move the Files", + "MoveMovieFoldersRenameFolderWarning": "This will also rename the movie folder per the movie folder format in settings.", + "MoveMovieFoldersToNewPath": "Would you like to move the movie files from '{originalPath}' to '{destinationPath}'?", + "MoveMovieFoldersToRootFolder": "Would you like to move the movie folders to '{destinationRootFolder}'?", "Movie": "Movie", "MovieAlreadyExcluded": "Movie already Excluded", "MovieAndCollection": "Movie and Collection", @@ -1129,7 +1131,6 @@ "NoLogFiles": "No log files", "NoMatchFound": "No match found!", "NoMinimumForAnyRuntime": "No minimum for any runtime", - "NoMoveFilesSelf": " No, I'll Move the Files Myself", "NoMovieFilesToManage": "No movie files to manage.", "NoMovieReleaseDatesAvailable": "No release dates available on [TMDb]({url}) for this movie.", "NoMoviesExist": "No movies found, to get started you'll want to add a new movie or import some existing ones.", @@ -1929,7 +1930,6 @@ "Year": "Year", "Yes": "Yes", "YesCancel": "Yes, Cancel", - "YesMoveFiles": "Yes, Move the Files", "Yesterday": "Yesterday", "YesterdayAt": "Yesterday at {time}", "YouCanAlsoSearch": "You can also search using TMDb ID or IMDb ID of a movie. e.g. `tmdb:71663`" diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 3e02e3b376..9b1fe1dffa 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -793,7 +793,7 @@ "NoAlternativeTitles": "Sin títulos alternativos.", "NoEventsFound": "Ningún evento encontrado", "NoLinks": "Sin enlaces", - "NoMoveFilesSelf": " No, moveré los archivos yo mismo", + "MoveMovieFoldersDontMoveFiles": " No, moveré los archivos yo mismo", "NoMoviesExist": "No se encontraron películas. Para comenzar añade una nueva película o importa algunas existentes.", "NoResultsFound": "Ningún resultado encontrado", "MovieFilesTotaling": "Total de archivos de película", @@ -856,7 +856,7 @@ "ExternalUpdater": "{appName} está configurado para usar un mecanismo de actualización externo", "FailedToLoadMovieFromAPI": "No se pudo cargar la película desde la API", "FeatureRequests": "Peticiones de características", - "FolderMoveRenameWarning": "Esto también renombrará la carpeta de películas según el formato de carpeta de películas en la configuración.", + "MoveMovieFoldersRenameFolderWarning": "Esto también renombrará la carpeta de películas según el formato de carpeta de películas en la configuración.", "IMDb": "IMDb", "InstallLatest": "Instala el último", "KeepAndUnmonitorMovie": "Mantener y no monitorizar la película", @@ -874,7 +874,7 @@ "MinimumCustomFormatScore": "Puntuación mínima de formato personalizado", "MonitoredStatus": "Monitorizados/Estado", "Months": "Meses", - "MoveFolders1": "¿Te gustaría mover las carpetas de películas a '{0}'?", + "MoveMovieFoldersToRootFolder": "¿Te gustaría mover las carpetas de películas a '{0}'?", "MovieChat": "Chat de películas", "MovieInvalidFormat": "Película: formato no válido", "MultiLanguage": "Multi-idioma", @@ -934,9 +934,9 @@ "Weeks": "Semanas", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Te gustaria restaurar la copia de seguridad '{name}'?", - "YesMoveFiles": "Sí, mover los archivos", + "MoveMovieFoldersMoveFiles": "Sí, mover los archivos", "Yesterday": "Ayer", - "MoveFolders2": "¿Te gustaría mover los archivos de película de '{0}' a '{1}'?", + "MoveMovieFoldersToNewPath": "¿Te gustaría mover los archivos de película de '{0}' a '{1}'?", "SqliteVersionCheckUpgradeRequiredMessage": "La versión {0} de SQLite instalada actualmente ya no es compatible. Actualice SQLite al menos a la versión {1}.", "ShowCinemaRelease": "Mostrar fecha de estreno en el cine", "ShowReleaseDate": "Mostrar fecha de lanzamiento", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index 034f7ada79..44f2a29599 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -50,7 +50,7 @@ "MinimumAgeHelpText": "Vain Usenet: NZB:n vähimmäisikä minuutteina, ennen niiden kaappausta. Tämän avulla uusille julkaisuille voidaan antaa aikaa levitä Usenet-palveluntarjoajalle.", "MinimumFreeSpaceHelpText": "Estä tuonti, jos sen jälkeinen vapaa levytila olisi tässä määritettyä pienempi.", "MonitoredHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.", - "MoveFolders1": "Haluatko siirtää elokuvakansiot kohteeseen \"{0}\"?", + "MoveMovieFoldersToRootFolder": "Haluatko siirtää elokuvakansiot kohteeseen \"{0}\"?", "MovieChat": "Elokuvakeskustelu", "MultiLanguage": "Useita kieliä", "PosterOptions": "Julistenäkymän asetukset", @@ -201,7 +201,7 @@ "NoEventsFound": "Tapahtumia ei löytynyt", "NoLinks": "Linkkejä ei ole", "NoMinimumForAnyRuntime": "Ei toistoajan vähimmäiskestoa", - "NoMoveFilesSelf": " Ei, siirrän tiedostot itse", + "MoveMovieFoldersDontMoveFiles": " Ei, siirrän tiedostot itse", "NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.", "NoResultsFound": "Tuloksia ei löytynyt.", "BranchUpdate": "{appName}in versiopäivityksiin käytettävä kehityshaara.", @@ -555,7 +555,7 @@ "Fixed": "Korjattu", "FocusSearchBox": "Kohdista hakukenttä", "Folder": "Kansio", - "FolderMoveRenameWarning": "Tämä nimeää myös elokuvakansion uudelleen asetuksissa määritettyjen nimeämissääntöjen mukaisesti.", + "MoveMovieFoldersRenameFolderWarning": "Tämä nimeää myös elokuvakansion uudelleen asetuksissa määritettyjen nimeämissääntöjen mukaisesti.", "Folders": "Kansiot", "FollowPerson": "Seuraa henkilöä", "Forecast": "Ennuste", @@ -932,13 +932,13 @@ "WouldYouLikeToRestoreBackup": "Haluatko palauttaa varmuuskopion \"{name}\"?", "Year": "Vuosi", "YesCancel": "Kyllä, peru", - "YesMoveFiles": "Kyllä, siirrä tiedostot", + "MoveMovieFoldersMoveFiles": "Kyllä, siirrä tiedostot", "Yesterday": "Eilen", "YouCanAlsoSearch": "Voit etsiä myös elokuvien TMDB- tai IMDb-tunnisteilla (esim. \"tmdb:71663\").", "MaintenanceRelease": "Huoltojulkaisu: korjauksia ja muita parannuksia. Lue lisää Githubin muutoshistoriasta.", "MissingMonitoredAndConsideredAvailable": "Puuttuu (valvotaan)", "MissingNotMonitored": "Puuttuu (valvomattomat)", - "MoveFolders2": "Haluatko siirtää elokuvatiedostot kansiosta {0} kansioon {1}?", + "MoveMovieFoldersToNewPath": "Haluatko siirtää elokuvatiedostot kansiosta {0} kansioon {1}?", "MovieDetailsPreviousMovie": "Elokuvan tiedot: Edellinen elokuva", "MovieEditor": "Elokuvien monivalinta", "MovieExcludedFromAutomaticAdd": "Elokuvaa ei huomioida automaattisessa lisäyksessä.", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index aedcdf99ba..cf90295db7 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -818,7 +818,7 @@ "FailedToLoadMovieFromAPI": "Erreur lors du chargement du film via l'API", "FeatureRequests": "Requêtes de nouvelles fonctionnalités", "FileNameTokens": "Jetons de nom de fichier", - "FolderMoveRenameWarning": "Ceci va également renommer le dossier du film par le format de dossier défini dans les paramètres.", + "MoveMovieFoldersRenameFolderWarning": "Ceci va également renommer le dossier du film par le format de dossier défini dans les paramètres.", "Images": "Images", "IMDb": "IMDb", "Hours": "Heures", @@ -851,7 +851,7 @@ "MovieFilesTotaling": "Totalisation des fichiers vidéo", "NextExecution": "Prochaine exécution", "NoEventsFound": "Aucun événement trouvé", - "NoMoveFilesSelf": " Non, je vais déplacer les fichiers moi-même", + "MoveMovieFoldersDontMoveFiles": " Non, je vais déplacer les fichiers moi-même", "None": "Aucun", "NoResultsFound": "Aucun résultat trouvé", "OnGrab": "Lors de la saisie", @@ -883,7 +883,7 @@ "MinimumCustomFormatScore": "Score minimum de format personnalisé", "MonitoredStatus": "Surveillé/Statut", "Months": "Mois", - "MoveFolders1": "Souhaitez-vous déplacer les dossiers de films vers «{0}» ?", + "MoveMovieFoldersToRootFolder": "Souhaitez-vous déplacer les dossiers de films vers «{0}» ?", "MovieChat": "Movie Chat", "MovieInvalidFormat": "Film : format non valide", "MultiLanguage": "Multi-langue", @@ -943,8 +943,8 @@ "Weeks": "Semaines", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Souhaitez-vous restaurer la sauvegarde « {name} » ?", - "YesMoveFiles": "Oui, déplacez les fichiers", - "MoveFolders2": "Souhaitez-vous déplacer les fichiers vidéo de «{0}» vers «{1}» ?", + "MoveMovieFoldersMoveFiles": "Oui, déplacez les fichiers", + "MoveMovieFoldersToNewPath": "Souhaitez-vous déplacer les fichiers vidéo de «{0}» vers «{1}» ?", "SqliteVersionCheckUpgradeRequiredMessage": "La version {0} de SQLite actuellement installée n'est plus prise en charge. Veuillez mettre à niveau SQLite vers au moins la version {1}.", "ShowCinemaRelease": "Afficher la date de sortie au cinéma", "ShowReleaseDate": "Afficher la date de sortie", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index 154318879f..0fd64783cb 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -189,7 +189,7 @@ "NoEventsFound": "לא נמצאו אירועים", "NoLinks": "אין קישורים", "NoMinimumForAnyRuntime": "אין מינימום לכל זמן ריצה", - "NoMoveFilesSelf": " לא, אני אעביר את הקבצים בעצמי", + "MoveMovieFoldersDontMoveFiles": " לא, אני אעביר את הקבצים בעצמי", "Add": "הוסף", "NoMoviesExist": "לא נמצאו סרטים, כדי להתחיל, תרצה להוסיף סרט חדש או לייבא סרטים קיימים.", "None": "אף אחד", @@ -550,7 +550,7 @@ "FilterPlaceHolder": "חפש סרטים", "Fixed": "תוקן", "FocusSearchBox": "תיבת חיפוש פוקוס", - "FolderMoveRenameWarning": "זה גם ישנה את שם תיקיית הסרט לפי פורמט תיקיית הסרט בהגדרות.", + "MoveMovieFoldersRenameFolderWarning": "זה גם ישנה את שם תיקיית הסרט לפי פורמט תיקיית הסרט בהגדרות.", "Folders": "תיקיות", "FollowPerson": "עקוב אחר האדם", "Forecast": "תַחֲזִית", @@ -653,7 +653,7 @@ "MonitorMovie": "צג סרט", "Months": "חודשים", "MoreInfo": "עוד מידע", - "MoveFolders1": "האם ברצונך להעביר את תיקיות הסרטים ל '{0}'?", + "MoveMovieFoldersToRootFolder": "האם ברצונך להעביר את תיקיות הסרטים ל '{0}'?", "Movie": "סרט", "MovieAlreadyExcluded": "הסרט כבר לא נכלל", "MovieChat": "צ'אט בסרט", @@ -933,12 +933,12 @@ "WouldYouLikeToRestoreBackup": "האם ברצונך לשחזר את הגיבוי {0}?", "Year": "שָׁנָה", "YesCancel": "כן, בטל", - "YesMoveFiles": "כן, העבר את הקבצים", + "MoveMovieFoldersMoveFiles": "כן, העבר את הקבצים", "Yesterday": "אתמול", "YouCanAlsoSearch": "ניתן גם לחפש באמצעות מזהה TMDb או מזהה IMDb של סרט. לְמָשָׁל 'tmdb: 71663'", "MaintenanceRelease": "שחרור תחזוקה: תיקוני באגים ושיפורים אחרים. לפרטים נוספים, ראה היסטוריית התחייבויות של Github", "MissingNotMonitored": "חסר (ללא פיקוח)", - "MoveFolders2": "האם ברצונך להעביר את קובצי הסרט מ- '{0}' ל '{1}'?", + "MoveMovieFoldersToNewPath": "האם ברצונך להעביר את קובצי הסרט מ- '{0}' ל '{1}'?", "MovieDetailsPreviousMovie": "פרטי הסרט: הסרט הקודם", "MovieEditor": "עורך סרטים", "MovieExcludedFromAutomaticAdd": "סרט שאינו הוסף אוטומטי", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 0555d4e0cb..32175a8929 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -86,7 +86,7 @@ "ChangeFileDateHelpText": "आयात / रेस्क्यू पर फ़ाइल तिथि बदलें", "Filter": "फ़िल्टर", "FirstDayOfWeek": "सप्ताह का पहला दिन", - "FolderMoveRenameWarning": "यह सेटिंग्स में मूवी फ़ोल्डर प्रारूप के अनुसार मूवी फ़ोल्डर का नाम भी बदलेगा।", + "MoveMovieFoldersRenameFolderWarning": "यह सेटिंग्स में मूवी फ़ोल्डर प्रारूप के अनुसार मूवी फ़ोल्डर का नाम भी बदलेगा।", "Formats": "प्रारूप", "SupportedListsMoreInfo": "व्यक्तिगत आयात सूचियों की अधिक जानकारी के लिए, जानकारी बटन पर क्लिक करें।", "SupportedIndexersMoreInfo": "अलग-अलग इंडेक्सर्स के बारे में अधिक जानकारी के लिए, जानकारी बटन पर क्लिक करें।", @@ -263,7 +263,7 @@ "YesCancel": "हाँ, रद्द करें", "YouCanAlsoSearch": "आप किसी मूवी की TMDb ID या IMDb ID का उपयोग करके भी खोज सकते हैं। जैसे `TMDb: 71663`", "MissingMonitoredAndConsideredAvailable": "गुम (निगरानी)", - "MoveFolders2": "क्या आप फ़िल्म फ़ाइलों को '{0}' से '{1}' में ले जाना चाहेंगे?", + "MoveMovieFoldersToNewPath": "क्या आप फ़िल्म फ़ाइलों को '{0}' से '{1}' में ले जाना चाहेंगे?", "MovieExcludedFromAutomaticAdd": "मूवी स्वचालित ऐड से बहिष्कृत", "Search": "खोज", "Updates": "अपडेट", @@ -410,7 +410,7 @@ "NegateHelpText": "यदि जाँच की जाती है, तो कस्टम प्रारूप लागू नहीं होगा यदि यह {0} स्थिति से मेल खाता है।", "NoAlternativeTitles": "कोई वैकल्पिक शीर्षक नहीं।", "NoMinimumForAnyRuntime": "किसी रनटाइम के लिए कोई न्यूनतम नहीं", - "NoMoveFilesSelf": " नहीं, मैं फ़ाइलों को स्वयं स्थानांतरित करूँगा", + "MoveMovieFoldersDontMoveFiles": " नहीं, मैं फ़ाइलों को स्वयं स्थानांतरित करूँगा", "NoMoviesExist": "कोई फ़िल्म नहीं मिली, आरंभ करने के लिए आप एक नई फ़िल्म जोड़ना चाहेंगे या कुछ मौजूदा चीज़ों को आयात करेंगे।", "BypassProxyForLocalAddresses": "स्थानीय पते के लिए बायपास प्रॉक्सी", "Calendar": "पंचांग", @@ -764,7 +764,7 @@ "MonitorMovie": "मॉनिटर मूवी", "Months": "महीने", "MoreInfo": "और जानकारी", - "MoveFolders1": "क्या आप मूवी फोल्डर को '{0}' में ले जाना चाहेंगे?", + "MoveMovieFoldersToRootFolder": "क्या आप मूवी फोल्डर को '{0}' में ले जाना चाहेंगे?", "MovieAlreadyExcluded": "मूवी पहले ही बाहर कर दी गई", "MovieChat": "मूवी चैट", "MovieInfoLanguage": "मूवी की जानकारी भाषा", @@ -937,7 +937,7 @@ "Weeks": "हफ्तों", "WhitelistedSubtitleTags": "सफेदीकृत उपशीर्षक टैग", "WouldYouLikeToRestoreBackup": "क्या आप बैकअप {0} को पुनर्स्थापित करना चाहेंगे?", - "YesMoveFiles": "हाँ, फ़ाइलें स्थानांतरित करें", + "MoveMovieFoldersMoveFiles": "हाँ, फ़ाइलें स्थानांतरित करें", "Yesterday": "बिता कल", "MaintenanceRelease": "रखरखाव रिलीज: बग फिक्स और अन्य सुधार। अधिक जानकारी के लिए गितुब कमिट इतिहास देखें", "MissingNotMonitored": "अनुपलब्ध (अज्ञात)", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 671ce7110a..5cf018a729 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -821,7 +821,7 @@ "FailedToLoadMovieFromAPI": "Nem sikerült betölteni a filmet az API-ból", "ExternalUpdater": "A {appName} egy külső frissítési mechanizmus használatára van konfigurálva", "ExcludeTitle": "Kizárja a következőt: {0}? Ez megakadályozza, hogy a {appName} automatikusan hozzáadja a listaszinkronizáláshoz.", - "FolderMoveRenameWarning": "Ezzel a filmmappa a filmmappa formátuma szerint is átnevezésre kerül a beállításokban.", + "MoveMovieFoldersRenameFolderWarning": "Ezzel a filmmappa a filmmappa formátuma szerint is átnevezésre kerül a beállításokban.", "Images": "Képek", "HttpHttps": "HTTP(S)", "Hours": "Órák", @@ -908,7 +908,7 @@ "NoResultsFound": "Nincs találat", "None": "Egyik sem", "NoMoviesExist": "Nem találhatóak filmek, kezdésnek adjon hozzá egy új filmet vagy importáljon már meglévőket.", - "NoMoveFilesSelf": " Ne, magam mozgatom át a fájlokat", + "MoveMovieFoldersDontMoveFiles": " Ne, magam mozgatom át a fájlokat", "NoListRecommendations": "Nincs elem a listában és az ajánlások között, kezdésnek adjon hozzá egy filmet, importáljon meglévőket, vagy adjon hozzá egy listát.", "NoLinks": "Nincsenek Linkek", "NoEventsFound": "Nem található események", @@ -920,7 +920,7 @@ "MovieInvalidFormat": "Film: Érvénytelen formátum", "MovieFilesTotaling": "Film fájlok összege", "MovieChat": "Film Chat", - "MoveFolders1": "Szeretné áthelyezni a film mappáját ide: '{0}'?", + "MoveMovieFoldersToRootFolder": "Szeretné áthelyezni a film mappáját ide: '{0}'?", "Months": "Hónapok", "MonitoredStatus": "Felügyelt/állapot", "Monday": "Hétfő", @@ -939,9 +939,9 @@ "WhatsNew": "Mi az újdonság?", "Weeks": "Hetek", "WouldYouLikeToRestoreBackup": "Szeretné visszaállítani a(z) „{name}” biztonsági másolatot?", - "YesMoveFiles": "Igen, helyezze át a fájlokat", + "MoveMovieFoldersMoveFiles": "Igen, helyezze át a fájlokat", "RequiredRestrictionHelpText": "A kiadásnak tartalmaznia kell legalább egy ilyen kifejezést (a kis- és nagybetűk nem számítanak)", - "MoveFolders2": "Szeretnéd áthelyezni a filmfájlokat a(z) „{0}” mappából a(z) „{1}” mappába?", + "MoveMovieFoldersToNewPath": "Szeretnéd áthelyezni a filmfájlokat a(z) „{0}” mappából a(z) „{1}” mappába?", "ImportNotForDownloads": "Ne használja letöltések importálására a letöltötőkliensről, ez csak a meglévő szervezett könyvtárakra vonatkozik, nem rendezetlen mappákra/fájlokra.", "ImportLibrary": "Könyvtár importálás", "SqliteVersionCheckUpgradeRequiredMessage": "A jelenleg telepített {0} SQLite verzió már nem támogatott. Kérjük, frissítse az SQLite-t legalább a (z) {1} verzióra.", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 4c591ae050..6aaa4ec9a7 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -56,7 +56,7 @@ "FailedLoadingSearchResults": "Mistókst að hlaða leitarniðurstöður. Reyndu aftur.", "FileManagement": "Skráastjórnun", "Filename": "Skráarnafn", - "FolderMoveRenameWarning": "Þetta mun einnig endurnefna kvikmyndamöppuna eftir sniði kvikmyndamöppunnar í stillingum.", + "MoveMovieFoldersRenameFolderWarning": "Þetta mun einnig endurnefna kvikmyndamöppuna eftir sniði kvikmyndamöppunnar í stillingum.", "SupportedDownloadClientsMoreInfo": "Fyrir frekari upplýsingar um einstaka niðurhal viðskiptavini, smelltu á upplýsingatakkana.", "HideAdvanced": "Fela lengra komna", "Ignored": "Hunsað", @@ -248,7 +248,7 @@ "NoAlternativeTitles": "Engir aðrir titlar.", "NoEventsFound": "Engir viðburðir fundust", "NoMinimumForAnyRuntime": "Ekkert lágmark fyrir neina keyrslutíma", - "NoMoveFilesSelf": " Nei, ég skal færa skrárnar sjálfur", + "MoveMovieFoldersDontMoveFiles": " Nei, ég skal færa skrárnar sjálfur", "NoMoviesExist": "Engar kvikmyndir fundust, til að byrja, þá viltu bæta við nýrri kvikmynd eða flytja inn þær sem fyrir eru.", "None": "Enginn", "NoResultsFound": "Engar niðurstöður fundust", @@ -683,7 +683,7 @@ "MonitorMovie": "Fylgstu með kvikmynd", "Months": "Mánuðum", "MoreInfo": "Meiri upplýsingar", - "MoveFolders1": "Viltu færa kvikmyndamöppurnar í „{0}“?", + "MoveMovieFoldersToRootFolder": "Viltu færa kvikmyndamöppurnar í „{0}“?", "Movie": "Kvikmynd", "MovieAlreadyExcluded": "Kvikmynd þegar undanskilin", "MovieChat": "Kvikmyndaspjall", @@ -934,12 +934,12 @@ "WouldYouLikeToRestoreBackup": "Viltu endurheimta öryggisafritið {0}?", "Year": "Ár", "YesCancel": "Já, hætta við", - "YesMoveFiles": "Já, hreyfðu skrárnar", + "MoveMovieFoldersMoveFiles": "Já, hreyfðu skrárnar", "Yesterday": "Í gær", "YouCanAlsoSearch": "Þú getur líka leitað með því að nota TMDb auðkenni eða IMDb auðkenni kvikmyndar. t.d. `tmdb: 71663`", "MaintenanceRelease": "Útgáfa viðhalds: villuleiðréttingar og aðrar úrbætur. Sjá Github skuldbindingarferil fyrir frekari upplýsingar", "MissingNotMonitored": "Vantar (óeftirlit)", - "MoveFolders2": "Viltu færa kvikmyndaskrárnar frá '{0}' til '{1}'?", + "MoveMovieFoldersToNewPath": "Viltu færa kvikmyndaskrárnar frá '{0}' til '{1}'?", "MovieDetailsPreviousMovie": "Upplýsingar um kvikmynd: Fyrri kvikmynd", "MovieExcludedFromAutomaticAdd": "Kvikmynd útilokuð frá sjálfvirkri viðbót", "Search": "Leitaðu", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 8b547c1d78..49e93ef7f6 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -810,7 +810,7 @@ "NoAlternativeTitles": "Nessun titolo alternativo.", "NoEventsFound": "Nessun evento trovato", "NoLinks": "Nessun Collegamento", - "NoMoveFilesSelf": " No, sposterò i file da solo", + "MoveMovieFoldersDontMoveFiles": " No, sposterò i file da solo", "NoMoviesExist": "Nessun film trovato, per iniziare ti consigliamo di aggiungere un nuovo film o importarne alcuni esistenti.", "None": "Nessuna", "NoResultsFound": "nessun risultato trovato", @@ -858,7 +858,7 @@ "ErrorRestoringBackup": "Errore durante il ripristino del backup", "FailedToLoadMovieFromAPI": "Impossibile caricare il film dall'API", "FeatureRequests": "Richieste di funzionalità", - "FolderMoveRenameWarning": "Questo rinominerà anche la cartella del film in base al formato della cartella del film nelle impostazioni.", + "MoveMovieFoldersRenameFolderWarning": "Questo rinominerà anche la cartella del film in base al formato della cartella del film nelle impostazioni.", "Images": "immagini", "IMDb": "IMDb", "InCinemasDate": "In data di cinema", @@ -879,7 +879,7 @@ "MinimumCustomFormatScore": "Punteggio formato personalizzato minimo", "MonitoredStatus": "Monitorato/Stato", "Months": "Mesi", - "MoveFolders1": "Spostare le cartelle dei film in \"{0}\"?", + "MoveMovieFoldersToRootFolder": "Spostare le cartelle dei film in \"{0}\"?", "MovieChat": "Movie Chat", "MovieInvalidFormat": "Film: formato non valido", "MultiLanguage": "Multi lingua", @@ -940,8 +940,8 @@ "Weeks": "Settimane", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Vuoi ripristinare il backup '{name}'?", - "YesMoveFiles": "Sì, sposta i file", - "MoveFolders2": "Spostare i file del film da \"{0}\" a \"{1}\"?", + "MoveMovieFoldersMoveFiles": "Sì, sposta i file", + "MoveMovieFoldersToNewPath": "Spostare i file del film da \"{0}\" a \"{1}\"?", "SqliteVersionCheckUpgradeRequiredMessage": "La versione SQLite attualmente installata {0} non è più supportata. Aggiorna SQLite almeno alla versione {1}.", "ShowCinemaRelease": "Mostra la data di uscita del cinema", "ShowReleaseDate": "Mostra data di uscita", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 64f3646734..a452be50f7 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -52,7 +52,7 @@ "ExtraFileExtensionsHelpText": "インポートする追加ファイルのコンマ区切りリスト(.nfoは.nfo-origとしてインポートされます)", "FailedLoadingSearchResults": "検索結果の読み込みに失敗しました。もう一度お試しください。", "ChangeFileDateHelpText": "インポート/再スキャン時にファイルの日付を変更する", - "FolderMoveRenameWarning": "これにより、設定のムービーフォルダ形式に従ってムービーフォルダの名前も変更されます。", + "MoveMovieFoldersRenameFolderWarning": "これにより、設定のムービーフォルダ形式に従ってムービーフォルダの名前も変更されます。", "SupportedDownloadClientsMoreInfo": "個々のダウンロードクライアントの詳細については、情報ボタンをクリックしてください。", "SupportedListsMoreInfo": "個々のインポートリストの詳細については、情報ボタンをクリックしてください。", "SupportedIndexersMoreInfo": "個々のインデクサーの詳細については、情報ボタンをクリックしてください。", @@ -81,7 +81,7 @@ "UseHardlinksInsteadOfCopy": "コピーの代わりにハードリンクを使用する", "Wiki": "ウィキ", "MaintenanceRelease": "メンテナンスリリース:バグ修正およびその他の改善。詳細については、Githubのコミット履歴を参照してください", - "MoveFolders2": "ムービーファイルを「{0}」から「{1}」に移動しますか?", + "MoveMovieFoldersToNewPath": "ムービーファイルを「{0}」から「{1}」に移動しますか?", "Announced": "発表", "ApplyTags": "タグを適用する", "Authentication": "認証", @@ -228,7 +228,7 @@ "NoEventsFound": "イベントが見つかりません", "NoLinks": "リンクなし", "NoMinimumForAnyRuntime": "ランタイムの最小値はありません", - "NoMoveFilesSelf": " いいえ、ファイルを自分で移動します", + "MoveMovieFoldersDontMoveFiles": " いいえ、ファイルを自分で移動します", "NoMoviesExist": "映画が見つかりません。開始するには、新しい映画を追加するか、既存の映画をインポートする必要があります。", "NoResultsFound": "結果が見つかりません", "BranchUpdate": "{appName}の更新に使用するブランチ", @@ -640,7 +640,7 @@ "MonitorMovie": "モニタームービー", "Months": "月", "MoreInfo": "より詳しい情報", - "MoveFolders1": "ムービーフォルダを「{0}」に移動しますか?", + "MoveMovieFoldersToRootFolder": "ムービーフォルダを「{0}」に移動しますか?", "Movie": "映画", "MovieAlreadyExcluded": "映画はすでに除外されています", "MovieChat": "ムービーチャット", @@ -934,7 +934,7 @@ "WouldYouLikeToRestoreBackup": "バックアップ{0}を復元しますか?", "Year": "年", "YesCancel": "はい、キャンセル", - "YesMoveFiles": "はい、ファイルを移動します", + "MoveMovieFoldersMoveFiles": "はい、ファイルを移動します", "Yesterday": "昨日", "YouCanAlsoSearch": "映画のTMDbIDまたはIMDbIDを使用して検索することもできます。例えば`tmdb:71663`", "MissingMonitoredAndConsideredAvailable": "行方不明(監視済み)", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index 38553247a7..d5a85351ae 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -231,7 +231,7 @@ "MovieNaming": "영화 이름 지정", "NegateHelpText": "선택하면이 {0} 조건이 일치하면 맞춤 형식이 적용되지 않습니다.", "NoMinimumForAnyRuntime": "런타임에 대한 최소값 없음", - "NoMoveFilesSelf": " 아니요, 파일을 직접 이동하겠습니다.", + "MoveMovieFoldersDontMoveFiles": " 아니요, 파일을 직접 이동하겠습니다.", "NoMoviesExist": "영화를 찾을 수 없음 시작하려면 새 영화를 추가하거나 기존 영화를 가져와야합니다.", "NoResultsFound": "결과를 찾을 수 없습니다", "BranchUpdate": "{appName} 업데이트에 사용할 파생 버전", @@ -549,7 +549,7 @@ "FilterPlaceHolder": "영화 검색", "Fixed": "고정됨", "FocusSearchBox": "포커스 검색 창", - "FolderMoveRenameWarning": "설정에서 동영상 폴더 형식에 따라 동영상 폴더의 이름도 변경됩니다.", + "MoveMovieFoldersRenameFolderWarning": "설정에서 동영상 폴더 형식에 따라 동영상 폴더의 이름도 변경됩니다.", "Folders": "폴더", "FollowPerson": "사람을 따르십시오", "Forecast": "예보", @@ -648,7 +648,7 @@ "MonitoredStatus": "모니터링 됨 / 상태", "MonitorMovie": "영화 모니터링", "MoreInfo": "더많은 정보", - "MoveFolders1": "동영상 폴더를 '{0}'(으)로 이동 하시겠습니까?", + "MoveMovieFoldersToRootFolder": "동영상 폴더를 '{0}'(으)로 이동 하시겠습니까?", "Movie": "영화", "MovieAlreadyExcluded": "이미 제외된 영화", "MovieChat": "영화 채팅", @@ -933,12 +933,12 @@ "WouldYouLikeToRestoreBackup": "'{name}' 백업을 복원하시겠습니까?", "Year": "년", "YesCancel": "예, 취소합니다", - "YesMoveFiles": "예, 파일을 이동합니다", + "MoveMovieFoldersMoveFiles": "예, 파일을 이동합니다", "Yesterday": "어제", "MaintenanceRelease": "유지 관리 출시: 버그 수정 및 기타 개선. 상세 내용은 Github 커밋 내역을 참조하세요.", "MissingMonitoredAndConsideredAvailable": "누락 (모니터링 됨)", "MissingNotMonitored": "누락 (모니터링되지 않음)", - "MoveFolders2": "동영상 파일을 '{0}'에서 '{1}'(으)로 이동 하시겠습니까?", + "MoveMovieFoldersToNewPath": "동영상 파일을 '{0}'에서 '{1}'(으)로 이동 하시겠습니까?", "MovieDetailsPreviousMovie": "영화 정보: 이전 영화", "MovieEditor": "영화 편집기", "MovieExcludedFromAutomaticAdd": "자동 추가에서 제외된 영화", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index fde307f78c..3629d54b54 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -755,8 +755,8 @@ "MovieDetailsPreviousMovie": "Film Details: Vorige Film", "MovieDetailsNextMovie": "Film Details: Volgende Film", "MovieChat": "Film Chat", - "MoveFolders2": "Wil je de film bestanden verplaatsen van '{0}' naar '{1}'?", - "MoveFolders1": "Wil je de film mappen naar '{0}' verplaatsen?", + "MoveMovieFoldersToNewPath": "Wil je de film bestanden verplaatsen van '{0}' naar '{1}'?", + "MoveMovieFoldersToRootFolder": "Wil je de film mappen naar '{0}' verplaatsen?", "Months": "Maanden", "MonitoredStatus": "Bewaakt/Status", "Monday": "Maandag", @@ -883,7 +883,7 @@ "PreferAndUpgrade": "Prefereer en Waardeer Op", "PhysicalReleaseDate": "Fysieke Release Datum", "OpenThisModal": "Open deze modal", - "FolderMoveRenameWarning": "Dit zal ook de naam van de film map per film formaat in instellingen wijzigen.", + "MoveMovieFoldersRenameFolderWarning": "Dit zal ook de naam van de film map per film formaat in instellingen wijzigen.", "NextExecution": "Volgende uitvoering", "MovieFilesTotaling": "Totaal aantal filmbestanden", "NoEventsFound": "Geen gebeurtenissen gevonden", @@ -899,7 +899,7 @@ "NoResultsFound": "Geen resultaten gevonden", "None": "Geen", "NoMoviesExist": "Geen films gevonden, om te beginnen, voeg een nieuwe film toe of importeer bestaande films.", - "NoMoveFilesSelf": " Nee, ik verplaats de bestanden zelf", + "MoveMovieFoldersDontMoveFiles": " Nee, ik verplaats de bestanden zelf", "NoMatchFound": "Geen overeenkomst gevonden!", "NoListRecommendations": "Geen lijst aanbevelingen gevonden, om te beginnen, voeg een nieuwe film toe, importeer bestaande of voeg een lijst toe.", "NoLinks": "Geen koppelingen", @@ -943,7 +943,7 @@ "Weeks": "Weken", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Wilt u de back-up {name} herstellen?", - "YesMoveFiles": "Ja, verplaats de bestanden", + "MoveMovieFoldersMoveFiles": "Ja, verplaats de bestanden", "Yesterday": "Gisteren", "SqliteVersionCheckUpgradeRequiredMessage": "De momenteel geïnstalleerde SQLite-versie {0} wordt niet langer ondersteund. Upgrade SQLite naar minimaal versie {1}.", "ShowCinemaRelease": "Show Cinema-releasedatum", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index 44d9c6f347..354d86a335 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -140,7 +140,7 @@ "UsenetDelayTime": "Opóźnienie Usenetu: {0}", "WouldYouLikeToRestoreBackup": "Czy chcesz przywrócić kopię zapasową {0}?", "YesCancel": "Tak, anuluj", - "MoveFolders2": "Czy chcesz przenieść pliki filmowe z „{0}” do „{1}”?", + "MoveMovieFoldersToNewPath": "Czy chcesz przenieść pliki filmowe z „{0}” do „{1}”?", "DownloadPropersAndRepacksHelpText": "Czy automatycznie uaktualnić do Propers / Repacks", "DownloadPropersAndRepacksHelpTextCustomFormat": "Użyj opcji „Nie preferuj”, aby posortować wyniki według niestandardowego formatu w porównaniu z properami / przepakowaniami", "BackupIntervalHelpText": "Odstęp czasu między automatycznymi kopiami zapasowymi", @@ -243,7 +243,7 @@ "NoEventsFound": "Nie znaleziono wydarzeń", "NoLinks": "Brak linków", "NoMinimumForAnyRuntime": "Brak minimum dla dowolnego środowiska uruchomieniowego", - "NoMoveFilesSelf": " Nie, sam przeniosę pliki", + "MoveMovieFoldersDontMoveFiles": " Nie, sam przeniosę pliki", "NoMoviesExist": "Nie znaleziono żadnych filmów. Aby rozpocząć, musisz dodać nowy film lub zaimportować istniejące.", "NoResultsFound": "Nie znaleziono wyników", "BranchUpdate": "Gałąź do użycia do aktualizacji {appName}", @@ -565,7 +565,7 @@ "Fixed": "Naprawiony", "FocusSearchBox": "Zaznacz pole wyszukiwania", "Folder": "Teczka", - "FolderMoveRenameWarning": "Spowoduje to również zmianę nazwy folderu filmów zgodnie z formatem folderu filmów w ustawieniach.", + "MoveMovieFoldersRenameFolderWarning": "Spowoduje to również zmianę nazwy folderu filmów zgodnie z formatem folderu filmów w ustawieniach.", "Folders": "Lornetka składana", "Forecast": "Prognoza", "Formats": "Formaty", @@ -663,7 +663,7 @@ "MonitoredStatus": "Monitorowane / Stan", "MonitorMovie": "Monitoruj film", "MoreInfo": "Więcej informacji", - "MoveFolders1": "Czy chcesz przenieść foldery z filmami do „{0}”?", + "MoveMovieFoldersToRootFolder": "Czy chcesz przenieść foldery z filmami do „{0}”?", "Movie": "Film", "MovieAlreadyExcluded": "Film już wykluczony", "MovieChat": "Czat filmowy", @@ -932,7 +932,7 @@ "WhitelistedSubtitleTags": "Tagi napisów umieszczone na białej liście", "Wiki": "Wiki", "Year": "Rok", - "YesMoveFiles": "Tak, przenieś pliki", + "MoveMovieFoldersMoveFiles": "Tak, przenieś pliki", "Yesterday": "Wczoraj", "YouCanAlsoSearch": "Możesz również wyszukiwać za pomocą TMDb ID lub IMDb ID filmu. na przykład `tmdb: 71663`", "MaintenanceRelease": "Wersja konserwacyjna: poprawki błędów i inne ulepszenia. Aby uzyskać więcej informacji, zobacz historię zatwierdzeń na Github", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index 5106914c58..fa02f42723 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -767,8 +767,8 @@ "CustomFormatHelpText": "O {appName} pontua cada versão usando a soma das pontuações de formatos personalizados correspondentes. Se uma nova versão melhorar a pontuação, com a mesma qualidade ou melhor, o {appName} a capturará.", "DefaultDelayProfileMovie": "Este é o perfil padrão. Isso se aplica a todos os filmes que não têm um perfil explícito.", "DoNotUpgradeAutomatically": "Não atualizar automaticamente", - "FolderMoveRenameWarning": "Isso também renomeará a pasta do filme de acordo com o formato de pasta nas definições.", - "MoveFolders1": "Deseja mover as pastas de filmes para \"{0}\"?", + "MoveMovieFoldersRenameFolderWarning": "Isso também renomeará a pasta do filme de acordo com o formato de pasta nas definições.", + "MoveMovieFoldersToRootFolder": "Deseja mover as pastas de filmes para \"{0}\"?", "NoListRecommendations": "Não foram encontrados itens de lista ou recomendações. Para começar, adiciona um novo filme, importa alguns existentes ou adiciona uma lista.", "LastExecution": "Execução mais recente", "OnGrab": "Ao capturar", @@ -802,7 +802,7 @@ "NoAlternativeTitles": "Sem títulos alternativos.", "NoEventsFound": "Nenhum evento encontrado", "NoLinks": "Sem ligações", - "NoMoveFilesSelf": " Não, eu mesmo moverei os ficheiros", + "MoveMovieFoldersDontMoveFiles": " Não, eu mesmo moverei os ficheiros", "Presets": "Pré-sintonizações", "ChmodFolderHelpTextWarning": "Isso só funciona se o utilizador que executa o {appName} é o proprietário do ficheiro. É melhor garantir que o cliente de transferências defina as permissões corretamente.", "ChownGroupHelpText": "Nome do grupo ou gid. Use gid para sistemas de ficheiros remotos.", @@ -943,8 +943,8 @@ "Weeks": "Semanas", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Deseja restaurar a cópia de segurança {0}?", - "YesMoveFiles": "Sim, mova os ficheiros", - "MoveFolders2": "Deseja mover os ficheiros de filme de \"{0}\" para \"{1}\"?", + "MoveMovieFoldersMoveFiles": "Sim, mova os ficheiros", + "MoveMovieFoldersToNewPath": "Deseja mover os ficheiros de filme de \"{0}\" para \"{1}\"?", "SqliteVersionCheckUpgradeRequiredMessage": "A versão do SQLite atualmente instalada {0} não é mais suportada. Atualiza o SQLite para pelo menos a versão {1}.", "ShowCinemaRelease": "Mostrar data de lançamento no cinema", "ShowReleaseDate": "Mostrar data de lançamento", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index b8d91bb93b..e1fd2ba678 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -98,7 +98,7 @@ "Forecast": "Previsão", "FollowPerson": "Seguir pessoa", "Folders": "Pastas", - "FolderMoveRenameWarning": "Isso também renomeará a pasta do filme de acordo com o formato para pastas de filmes nas Configurações.", + "MoveMovieFoldersRenameFolderWarning": "Isso também renomeará a pasta do filme de acordo com o formato para pastas de filmes nas Configurações.", "Folder": "Pasta", "FocusSearchBox": "Selecionar a caixa de pesquisa", "Fixed": "Corrigido", @@ -491,8 +491,8 @@ "MovieChat": "Bate-papo sobre o filme", "MovieAlreadyExcluded": "Filme já excluído", "Movie": "Filme", - "MoveFolders2": "Deseja mover os arquivos de filmes de \"{0}\" para \"{1}\"?", - "MoveFolders1": "Deseja mover as pastas de filmes para \"{0}\"?", + "MoveMovieFoldersToNewPath": "Deseja mover os arquivos de filmes de \"{0}\" para \"{1}\"?", + "MoveMovieFoldersToRootFolder": "Deseja mover as pastas de filmes para \"{0}\"?", "MoveFiles": "Mover arquivos", "MountMovieHealthCheckMessage": "O ponto de montagem que contém um caminho de filme é montado somente para leitura: ", "MoreInfo": "Mais informações", @@ -515,7 +515,7 @@ "Wiki": "Wiki", "Year": "Ano", "YesCancel": "Sim, Cancelar", - "YesMoveFiles": "Sim, mova os arquivos", + "MoveMovieFoldersMoveFiles": "Sim, mova os arquivos", "YouCanAlsoSearch": "Você também pode pesquisar usando TMDb ID ou IMDb ID de um filme. Por exemplo: `tmdb: 71663`", "NoMatchFound": "Nenhum resultado encontrado!", "NoLogFiles": "Nenhum arquivo de registro", @@ -870,7 +870,7 @@ "NoResultsFound": "Nenhum resultado encontrado", "None": "Nenhum", "NoMoviesExist": "Nenhum filme encontrado. Para começar, adicione um novo filme ou importe alguns existentes.", - "NoMoveFilesSelf": " Não, eu mesmo moverei os arquivos", + "MoveMovieFoldersDontMoveFiles": " Não, eu mesmo moverei os arquivos", "NoMinimumForAnyRuntime": "Sem mínimo para qualquer duração", "ReplaceWithSpaceDashSpace": "Substituir com Espaço, Traço e Espaço", "ReplaceWithSpaceDash": "Substituir por Espaço e Traço", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index 053237e6d5..5b453f87c6 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -292,7 +292,7 @@ "MinutesHundredTwenty": "120 de minute: {0}", "MinutesNinety": "90 de minute: {0}", "Months": "Luni", - "MoveFolders1": "Doriți să mutați dosarele filmelor în „{0}”?", + "MoveMovieFoldersToRootFolder": "Doriți să mutați dosarele filmelor în „{0}”?", "MovieInvalidFormat": "Film: Format nevalid", "NoListRecommendations": "Nu s-au găsit elemente de listă sau recomandări, pentru a începe, va trebui să adăugați un film nou, să importați unele existente sau să adăugați o listă.", "NoTagsHaveBeenAddedYet": "Nu s-au adăugat încă etichete", @@ -335,7 +335,7 @@ "Version": "Versiune", "YouCanAlsoSearch": "De asemenea, puteți căuta utilizând ID-ul TMDb sau ID-ul IMDb al unui film. de exemplu. `tmdb: 71663`", "MissingMonitoredAndConsideredAvailable": "Lipsește (monitorizat)", - "MoveFolders2": "Doriți să mutați fișierele filmului din „{0}” în „{1}”?", + "MoveMovieFoldersToNewPath": "Doriți să mutați fișierele filmului din „{0}” în „{1}”?", "Result": "Rezultat", "DownloadPropersAndRepacksHelpTextCustomFormat": "Utilizați „Nu preferați” pentru a sorta în funcție de scorul de format personalizat peste Propers / Repacks", "ImportFailed": "Importul nu a reușit: {0}", @@ -442,7 +442,7 @@ "NoEventsFound": "Nu s-au găsit evenimente", "NoLinks": "Fără linkuri", "NoMinimumForAnyRuntime": "Niciun minim pentru orice timp de rulare", - "NoMoveFilesSelf": " Nu, voi muta singur dosarele", + "MoveMovieFoldersDontMoveFiles": " Nu, voi muta singur dosarele", "NoMoviesExist": "Nu s-au găsit filme, pentru a începe, va trebui să adăugați un film nou sau să importați unele existente.", "None": "Nici unul", "NoResultsFound": "Nici un rezultat gasit", @@ -683,7 +683,7 @@ "FilterPlaceHolder": "Căutați filme", "Fixed": "Fix", "FocusSearchBox": "Caseta de căutare Focus", - "FolderMoveRenameWarning": "Aceasta va redenumi și folderul filmului în funcție de formatul folderului filmului în setări.", + "MoveMovieFoldersRenameFolderWarning": "Aceasta va redenumi și folderul filmului în funcție de formatul folderului filmului în setări.", "Folders": "Dosare", "FollowPerson": "Urmărește persoana", "SupportedDownloadClientsMoreInfo": "Pentru mai multe informații despre clienții individuali de descărcare, faceți clic pe butoanele de informații.", @@ -939,7 +939,7 @@ "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Doriți să restaurați copia de rezervă {0}?", "YesCancel": "Da, Anulați", - "YesMoveFiles": "Da, mutați fișierele", + "MoveMovieFoldersMoveFiles": "Da, mutați fișierele", "Yesterday": "Ieri", "MaintenanceRelease": "Versiune de întreținere: remedieri de erori și alte îmbunătățiri. Consultați Istoricul comiterilor Github pentru mai multe detalii", "MissingNotMonitored": "Lipsește (fără monitorizare)", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index 8768d6750c..46cb4610f5 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -291,7 +291,7 @@ "WhatsNew": "Что нового?", "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "Хотите восстановить резервную копию '{name}'?", - "YesMoveFiles": "Да, перенести файлы", + "MoveMovieFoldersMoveFiles": "Да, перенести файлы", "Logs": "Журналы", "ManualImport": "Ручной импорт", "MarkAsFailed": "Пометить как неудачный", @@ -465,7 +465,7 @@ "NoResultsFound": "Нет результатов", "None": "Ничего", "NoMoviesExist": "Фильмов не найдено. Для начала вам нужно добавить новый фильм или импортировать уже существующие.", - "NoMoveFilesSelf": " Нет, я сам перенесу файлы", + "MoveMovieFoldersDontMoveFiles": " Нет, я сам перенесу файлы", "NoMinimumForAnyRuntime": "Нет минимума для любого времени", "NoMatchFound": "Совпадений не найдено!", "NoLogFiles": "Файлов журнала нет", @@ -519,8 +519,8 @@ "MovieChat": "Чат по фильму", "MovieAlreadyExcluded": "Фильм уже добавлен в исключения", "Movie": "Фильм", - "MoveFolders2": "Желаете перенести паки с фильмами из '{0}' в '{1}' ?", - "MoveFolders1": "Желаете перенести папки с фильмами в '{0}' ?", + "MoveMovieFoldersToNewPath": "Желаете перенести паки с фильмами из '{0}' в '{1}' ?", + "MoveMovieFoldersToRootFolder": "Желаете перенести папки с фильмами в '{0}' ?", "MoveFiles": "Переместить файлы", "MoreInfo": "Больше информации", "MoreDetails": "Ещё подробности", @@ -589,7 +589,7 @@ "Forecast": "Прогноз", "FollowPerson": "Отслеживать человека", "Folders": "Папки", - "FolderMoveRenameWarning": "Папка фильма будет переименована согласно формату в настройках.", + "MoveMovieFoldersRenameFolderWarning": "Папка фильма будет переименована согласно формату в настройках.", "Folder": "Каталог", "Fixed": "Исправлено", "FirstDayOfWeek": "Первый день недели", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 07bb14e90e..22d67d6d45 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -427,7 +427,7 @@ "IgnoredAddresses": "Ignorerade adresser", "ICalFeed": "iCal-flöde", "Wiki": "Wiki", - "YesMoveFiles": "Ja, flytta filerna", + "MoveMovieFoldersMoveFiles": "Ja, flytta filerna", "YesCancel": "Ja, avbryt", "RenameMovies": "Byt namn på filmer", "RemoveMovieAndKeepFiles": "Ta bort film och behåll filerna", @@ -528,9 +528,9 @@ "ShowCertification": "Visa certifiering", "ShowMovieInformationHelpText": "Visa filmgenrer och certifiering", "ShowMovieInformation": "Visa filminformation", - "MoveFolders1": "Skulle du vilja flytta filmmapparna till '{0}' ?", + "MoveMovieFoldersToRootFolder": "Skulle du vilja flytta filmmapparna till '{0}' ?", "MovieFiles": "Filmfiler", - "MoveFolders2": "Skulle du vilja flytta filmfilerna från '{0}' till '{1}' ?", + "MoveMovieFoldersToNewPath": "Skulle du vilja flytta filmfilerna från '{0}' till '{1}' ?", "EditQualityProfile": "Redigera kvalitetsprofil", "EditImportListExclusion": "Redigera listuteslutning", "EditGroups": "Redigera grupper", @@ -552,7 +552,7 @@ "InteractiveImport": "Interaktiv import", "NoMoviesExist": "Inga filmer hittades, för att komma igång lägg till en ny film eller importera några befintliga.", "NoMinimumForAnyRuntime": "Inget minimum för någon körtid", - "NoMoveFilesSelf": " Nej, jag flyttar filerna själv", + "MoveMovieFoldersDontMoveFiles": " Nej, jag flyttar filerna själv", "NoLimitForAnyRuntime": "Ingen gräns för någon körtid", "NoLeaveIt": "Nej, lämna det", "NoEventsFound": "Inga händelser hittades", @@ -785,7 +785,7 @@ "FileNames": "Filnamn", "Fixed": "Fast", "FocusSearchBox": "Fokus sökruta", - "FolderMoveRenameWarning": "Detta kommer också att byta namn på filmmappen enligt filmmappens format i inställningarna.", + "MoveMovieFoldersRenameFolderWarning": "Detta kommer också att byta namn på filmmappen enligt filmmappens format i inställningarna.", "FollowPerson": "Följ Person", "SupportedDownloadClientsMoreInfo": "Klicka på informationsknapparna för mer information om de enskilda nedladdningsklienterna.", "SupportedIndexersMoreInfo": "För mer information om de enskilda indexerarna, klicka på informationsknapparna.", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index af6e6cf809..19709f2dba 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -73,7 +73,7 @@ "ExtraFileExtensionsHelpText": "รายการไฟล์พิเศษที่คั่นด้วยจุลภาคที่จะนำเข้า (.nfo จะนำเข้าเป็น. nfo-orig)", "FailedToLoadMovieFromAPI": "ไม่สามารถโหลดภาพยนตร์จาก API", "ChangeFileDateHelpText": "เปลี่ยนวันที่ของไฟล์ในการนำเข้า / สแกนใหม่", - "FolderMoveRenameWarning": "นอกจากนี้ยังจะเปลี่ยนชื่อโฟลเดอร์ภาพยนตร์ตามรูปแบบโฟลเดอร์ภาพยนตร์ในการตั้งค่า", + "MoveMovieFoldersRenameFolderWarning": "นอกจากนี้ยังจะเปลี่ยนชื่อโฟลเดอร์ภาพยนตร์ตามรูปแบบโฟลเดอร์ภาพยนตร์ในการตั้งค่า", "FollowPerson": "ติดตามบุคคล", "SupportedListsMoreInfo": "สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรายการนำเข้าแต่ละรายการให้คลิกที่ปุ่มข้อมูล", "SupportedIndexersMoreInfo": "สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตัวสร้างดัชนีแต่ละตัวคลิกที่ปุ่มข้อมูล", @@ -107,7 +107,7 @@ "MinimumAgeHelpText": "Usenet เท่านั้น: อายุต่ำสุดเป็นนาทีของ NZB ก่อนที่จะถูกคว้า ใช้สิ่งนี้เพื่อให้เวลารุ่นใหม่เผยแพร่ไปยังผู้ให้บริการ usenet ของคุณ", "MinimumFreeSpaceHelpText": "ป้องกันการนำเข้าหากเหลือพื้นที่ดิสก์น้อยกว่าจำนวนนี้", "MonitoredHelpText": "ดาวน์โหลดภาพยนตร์ถ้ามี", - "MoveFolders1": "คุณต้องการย้ายโฟลเดอร์ภาพยนตร์ไปที่ \"{0}\" หรือไม่", + "MoveMovieFoldersToRootFolder": "คุณต้องการย้ายโฟลเดอร์ภาพยนตร์ไปที่ \"{0}\" หรือไม่", "MoreInfo": "ข้อมูลเพิ่มเติม", "MovieAlreadyExcluded": "ยกเว้นภาพยนตร์แล้ว", "MovieDetailsNextMovie": "รายละเอียดภาพยนตร์: ภาพยนตร์เรื่องต่อไป", @@ -195,7 +195,7 @@ "Year": "ปี", "YouCanAlsoSearch": "คุณยังสามารถค้นหาโดยใช้ TMDb ID หรือ IMDb ID ของภาพยนตร์ เช่น. `tmdb: 71663`", "MaintenanceRelease": "รุ่นการบำรุงรักษา: การแก้ไขข้อบกพร่องและการปรับปรุงอื่น ๆ ดู Github Commit History สำหรับรายละเอียดเพิ่มเติม", - "MoveFolders2": "คุณต้องการย้ายไฟล์ภาพยนตร์จาก \"{0}\" ไปที่ \"{1}\" หรือไม่", + "MoveMovieFoldersToNewPath": "คุณต้องการย้ายไฟล์ภาพยนตร์จาก \"{0}\" ไปที่ \"{1}\" หรือไม่", "MovieExcludedFromAutomaticAdd": "ภาพยนตร์ไม่รวมจากการเพิ่มอัตโนมัติ", "Search": "ค้นหา", "AddNew": "เพิ่มใหม่", @@ -343,7 +343,7 @@ "NextExecution": "การดำเนินการถัดไป", "NoAlternativeTitles": "ไม่มีชื่ออื่น", "NoEventsFound": "ไม่พบกิจกรรม", - "NoMoveFilesSelf": " ไม่ฉันจะย้ายไฟล์เอง", + "MoveMovieFoldersDontMoveFiles": " ไม่ฉันจะย้ายไฟล์เอง", "None": "ไม่มี", "NoResultsFound": "ไม่พบผลลัพธ์", "BranchUpdate": "สาขาที่จะใช้ในการอัปเดต {appName}", @@ -937,7 +937,7 @@ "WhitelistedSubtitleTags": "แท็กคำบรรยายที่อนุญาตพิเศษ", "WouldYouLikeToRestoreBackup": "คุณต้องการกู้คืนข้อมูลสำรอง {0} หรือไม่", "YesCancel": "ใช่ยกเลิก", - "YesMoveFiles": "ใช่ย้ายไฟล์", + "MoveMovieFoldersMoveFiles": "ใช่ย้ายไฟล์", "Yesterday": "เมื่อวานนี้", "MissingMonitoredAndConsideredAvailable": "ขาดหายไป (ตรวจสอบ)", "MissingNotMonitored": "ขาดหายไป (ไม่ถูกตรวจสอบ)", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 894a6fb1c0..75b8af0393 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -365,7 +365,7 @@ "Wiki": "Wiki", "WouldYouLikeToRestoreBackup": "'{name}' yedeğini geri yüklemek ister misiniz?", "YesCancel": "Evet İptal", - "YesMoveFiles": "Evet, Dosyaları Taşı", + "MoveMovieFoldersMoveFiles": "Evet, Dosyaları Taşı", "Yesterday": "Dün", "YouCanAlsoSearch": "Filmin TMDb kimliğini veya IMDb kimliğini kullanarak da arama yapabilirsiniz. Örneğin. \"tmdb: 50737\"", "MaintenanceRelease": "Bakım Sürümü: hata düzeltmeleri ve diğer iyileştirmeler. Daha fazla ayrıntı için Github İşlem Geçmişine bakın", @@ -470,7 +470,7 @@ "NextExecution": "Sonraki Yürütme", "NoAlternativeTitles": "Alternatif başlık yok.", "NoLinks": "Bağlantı Yok", - "NoMoveFilesSelf": " Hayır, Dosyaları Kendim Taşıyacağım", + "MoveMovieFoldersDontMoveFiles": " Hayır, Dosyaları Kendim Taşıyacağım", "None": "Yok", "NoResultsFound": "Sonuç bulunamadı", "MovieFilesTotaling": "Film Dosyaları Toplamı", @@ -739,7 +739,7 @@ "FilterPlaceHolder": "Film ara", "FirstDayOfWeek": "Haftanın İlk Günü", "Fixed": "Düzeltilen", - "FolderMoveRenameWarning": "Bu aynı zamanda ayarlarda film klasörü formatına göre film klasörünü yeniden adlandıracaktır.", + "MoveMovieFoldersRenameFolderWarning": "Bu aynı zamanda ayarlarda film klasörü formatına göre film klasörünü yeniden adlandıracaktır.", "SupportedDownloadClientsMoreInfo": "Bireysel indirme istemcileri hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", "SupportedListsMoreInfo": "Ayrı ayrı içe aktarma listeleri hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", "SupportedIndexersMoreInfo": "Bireysel indeksleyiciler hakkında daha fazla bilgi için bilgi düğmelerine tıklayın.", @@ -821,7 +821,7 @@ "MonitoredStatus": "Takip Edilen/Durum", "MonitorMovie": "Filmi Takip Et", "Months": "Aylar", - "MoveFolders1": "Film klasörlerini '{0}' klasörüne taşımak ister misiniz?", + "MoveMovieFoldersToRootFolder": "Film klasörlerini '{0}' klasörüne taşımak ister misiniz?", "MovieAlreadyExcluded": "Film zaten Hariç tutuldu", "MovieChat": "Film Sohbeti", "MovieDetailsNextMovie": "Film Ayrıntıları: Sonraki Film", @@ -943,7 +943,7 @@ "Weeks": "Haftalar", "MissingMonitoredAndConsideredAvailable": "Eksik (Takip Ediliyor)", "MissingNotMonitored": "Eksik (Takip Edilmiyor)", - "MoveFolders2": "Film dosyalarını '{0}' konumundan '{1}' konumuna taşımak ister misiniz?", + "MoveMovieFoldersToNewPath": "Film dosyalarını '{0}' konumundan '{1}' konumuna taşımak ister misiniz?", "SqliteVersionCheckUpgradeRequiredMessage": "Şu anda kurulu olan SQLite sürümü {0} artık desteklenmiyor. Lütfen SQLite'ı en az {1} sürümüne yükseltin.", "ShowCinemaRelease": "Sinema Çıkış Tarihini Göster", "ShowReleaseDate": "Çıkış Tarihini Göster", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index eef5500054..4176ff8ebb 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -308,7 +308,7 @@ "Language": "Мова", "MetadataSettingsMovieSummary": "Створюйте файли метаданих, коли фільми імпортуються або оновлюються", "Month": "Місяць", - "NoMoveFilesSelf": " Ні, я сам перенесу файли", + "MoveMovieFoldersDontMoveFiles": " Ні, я сам перенесу файли", "Sunday": "Неділя", "Tasks": "Задачі", "Today": "Сьогодні", @@ -413,7 +413,7 @@ "AnalyseVideoFilesHelpText": "Отримайте з файлів інформацію про відео, таку як роздільна здатність, час виконання та кодек. Це вимагає, щоб {appName} читав частини файлу, що може спричинити високу дискову або мережеву активність під час сканування.", "ExtraFileExtensionsHelpText": "Розділений комами список додаткових файлів для імпорту (.nfo буде імпортовано як .nfo-orig)", "FileNameTokens": "Маркери імен файлів", - "FolderMoveRenameWarning": "Це також перейменує папку з фільмами відповідно до формату папки з фільмами в налаштуваннях.", + "MoveMovieFoldersRenameFolderWarning": "Це також перейменує папку з фільмами відповідно до формату папки з фільмами в налаштуваннях.", "IndexerSearchCheckNoAutomaticMessage": "Немає доступних індексаторів із увімкненим автоматичним пошуком, {appName} не надаватиме автоматичних результатів пошуку", "HiddenClickToShow": "Приховано, натисніть, щоб показати", "HomePage": "Домашня сторінка", @@ -439,8 +439,8 @@ "MinimumFreeSpace": "Мінімальний вільний простір", "MinimumLimits": "Мінімальні обмеження", "MovieCollectionRootFolderMissingRootHealthCheckMessage": "Відсутня коренева папка для колекції фільмів: {rootFolderInfo}", - "MoveFolders1": "Бажаєте перемістити папки з фільмами до \"{0}\"?", - "MoveFolders2": "Бажаєте перемістити файли фільму з \"{0}\" до \"{1}\"?", + "MoveMovieFoldersToRootFolder": "Бажаєте перемістити папки з фільмами до \"{0}\"?", + "MoveMovieFoldersToNewPath": "Бажаєте перемістити файли фільму з \"{0}\" до \"{1}\"?", "MovieFolderFormat": "Формат папки фільму", "MovieIndexScrollTop": "Індекс фільму: прокрутка вгору", "MovieInfoLanguageHelpText": "Мова, яку {appName} використовуватиме для інформації про фільм в інтерфейсі користувача", @@ -920,7 +920,7 @@ "WhitelistedSubtitleTags": "Теги субтитрів із білого списку", "Year": "Рік", "YesCancel": "Так, скасувати", - "YesMoveFiles": "Так, перемістити файли", + "MoveMovieFoldersMoveFiles": "Так, перемістити файли", "Yesterday": "Вчора", "ApplicationURL": "URL програми", "ApplicationUrlHelpText": "Зовнішня URL-адреса цієї програми, включаючи http(s)://, порт і базу URL-адрес", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 922345710b..60b653cb67 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -108,7 +108,7 @@ "MonitoredHelpText": "Tải xuống phim nếu có", "MonitoredOnly": "Chỉ giám sát", "MonitoredStatus": "Theo dõi / Trạng thái", - "MoveFolders1": "Bạn có muốn di chuyển các thư mục phim vào '{0}' không?", + "MoveMovieFoldersToRootFolder": "Bạn có muốn di chuyển các thư mục phim vào '{0}' không?", "MovieAlreadyExcluded": "Phim đã bị loại trừ", "MovieChat": "Trò chuyện phim", "MovieDetailsNextMovie": "Chi tiết phim: Phim tiếp theo", @@ -276,7 +276,7 @@ "Yesterday": "Hôm qua", "MaintenanceRelease": "Bản phát hành bảo trì: sửa lỗi và các cải tiến khác. Xem Lịch sử cam kết Github để biết thêm chi tiết", "MissingMonitoredAndConsideredAvailable": "Thiếu (Theo dõi)", - "MoveFolders2": "Bạn có muốn di chuyển các tệp phim từ '{0}' sang '{1}' không?", + "MoveMovieFoldersToNewPath": "Bạn có muốn di chuyển các tệp phim từ '{0}' sang '{1}' không?", "MovieExcludedFromAutomaticAdd": "Phim bị loại trừ khỏi tính năng thêm tự động", "AvailabilityDelay": "Độ trễ sẵn có", "AddMovie": "Thêm phim", @@ -407,7 +407,7 @@ "MovieIsRecommend": "Phim được đề xuất dựa trên phần bổ sung gần đây", "MovieNaming": "Đặt tên phim", "NoMinimumForAnyRuntime": "Không có tối thiểu cho bất kỳ thời gian chạy nào", - "NoMoveFilesSelf": " Không, tôi sẽ tự di chuyển tệp", + "MoveMovieFoldersDontMoveFiles": " Không, tôi sẽ tự di chuyển tệp", "NoMoviesExist": "Không tìm thấy phim nào, để bắt đầu, bạn sẽ muốn thêm phim mới hoặc nhập một số phim hiện có.", "None": "không ai", "NoResultsFound": "không tìm thấy kết quả nào", @@ -741,7 +741,7 @@ "Fixed": "đã sửa", "FocusSearchBox": "Hộp Tìm kiếm Tiêu điểm", "Folder": "Thư mục", - "FolderMoveRenameWarning": "Thao tác này cũng sẽ đổi tên thư mục phim theo định dạng thư mục phim trong cài đặt.", + "MoveMovieFoldersRenameFolderWarning": "Thao tác này cũng sẽ đổi tên thư mục phim theo định dạng thư mục phim trong cài đặt.", "Folders": "Thư mục", "FollowPerson": "Theo dõi người", "Forecast": "Dự báo", @@ -938,7 +938,7 @@ "Wiki": "Wiki", "Year": "Năm", "YesCancel": "Có, Hủy bỏ", - "YesMoveFiles": "Có, di chuyển tệp", + "MoveMovieFoldersMoveFiles": "Có, di chuyển tệp", "YouCanAlsoSearch": "Bạn cũng có thể tìm kiếm bằng cách sử dụng TMDb ID hoặc IMDb ID của một bộ phim. ví dụ. `tmdb: 71663 '", "MissingNotMonitored": "Thiếu (Không được giám sát)", "MovieDetailsPreviousMovie": "Chi tiết phim: Phim trước", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index cf01b59ecf..f307b52e55 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -545,15 +545,15 @@ "OnLatestVersion": "已安装最新版的{appName}", "OnGrab": "抓取中", "NotMonitored": "不追踪项", - "NoMoveFilesSelf": " 不,我要自己移动文件", + "MoveMovieFoldersDontMoveFiles": " 不,我要自己移动文件", "NoLeaveIt": "不,就这样", "NamingSettings": "命名设置", "Name": "名称", "MovieIsOnImportExclusionList": "电影在导入排除列表中", "MovieInvalidFormat": "电影: 无效格式", "MovieFilesTotaling": "电影文件总计", - "MoveFolders2": "要将电影文件从“{0}” 移至 “{1}” 吗?", - "MoveFolders1": "要将电影文件夹移至 “{0}” 吗?", + "MoveMovieFoldersToNewPath": "要将电影文件从“{0}” 移至 “{1}” 吗?", + "MoveMovieFoldersToRootFolder": "要将电影文件夹移至 “{0}” 吗?", "MonitorMovie": "追踪电影", "MonitoredStatus": "已追踪/状态", "MonitoredOnly": "已追踪项", @@ -610,7 +610,7 @@ "GrabRelease": "抓取版本", "GoToInterp": "跳转到 {0}", "Genres": "类型", - "FolderMoveRenameWarning": "这也将根据设置中的电影文件夹格式重命名电影文件夹。", + "MoveMovieFoldersRenameFolderWarning": "这也将根据设置中的电影文件夹格式重命名电影文件夹。", "FocusSearchBox": "聚焦搜索框", "Fixed": "已修复", "FailedToLoadMovieFromAPI": "从 API 加载电影失败", @@ -696,7 +696,7 @@ "Qualities": "质量", "TagIsNotUsedAndCanBeDeleted": "标签未被使用,可删除", "LastUsed": "上次使用", - "YesMoveFiles": "是,移动文件", + "MoveMovieFoldersMoveFiles": "是,移动文件", "UpdateMechanismHelpText": "使用 {appName} 内置的更新程序或脚本", "SystemTimeHealthCheckMessage": "系统时间相差超过1天。在纠正时间之前,计划的任务可能无法正确运行", "Table": "表格", From 7db12b6e589325f3c48b425593785eb0054899e7 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Fri, 7 Mar 2025 18:12:02 +0200 Subject: [PATCH 237/579] Convert EditMovieModal to TypeScript Towards #10700 Co-authored-by: Mark McDowall --- frontend/src/App/State/MoviesAppState.ts | 2 + .../Collection/Overview/CollectionMovie.js | 4 +- frontend/src/Movie/Details/MovieDetails.js | 4 +- frontend/src/Movie/Edit/EditMovieModal.js | 26 -- frontend/src/Movie/Edit/EditMovieModal.tsx | 32 +++ .../src/Movie/Edit/EditMovieModalConnector.js | 40 --- .../src/Movie/Edit/EditMovieModalContent.js | 217 ----------------- .../src/Movie/Edit/EditMovieModalContent.tsx | 229 ++++++++++++++++++ .../Edit/EditMovieModalContentConnector.js | 115 --------- .../Index/Overview/MovieIndexOverview.tsx | 4 +- .../Movie/Index/Posters/MovieIndexPoster.tsx | 4 +- .../src/Movie/Index/Table/MovieIndexRow.tsx | 4 +- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 3 +- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 2 +- 42 files changed, 304 insertions(+), 438 deletions(-) delete mode 100644 frontend/src/Movie/Edit/EditMovieModal.js create mode 100644 frontend/src/Movie/Edit/EditMovieModal.tsx delete mode 100644 frontend/src/Movie/Edit/EditMovieModalConnector.js delete mode 100644 frontend/src/Movie/Edit/EditMovieModalContent.js create mode 100644 frontend/src/Movie/Edit/EditMovieModalContent.tsx delete mode 100644 frontend/src/Movie/Edit/EditMovieModalContentConnector.js diff --git a/frontend/src/App/State/MoviesAppState.ts b/frontend/src/App/State/MoviesAppState.ts index 13df312217..d9b78d8cab 100644 --- a/frontend/src/App/State/MoviesAppState.ts +++ b/frontend/src/App/State/MoviesAppState.ts @@ -64,6 +64,8 @@ interface MoviesAppState deleteOptions: { addImportExclusion: boolean; }; + + pendingChanges: Partial; } export default MoviesAppState; diff --git a/frontend/src/Collection/Overview/CollectionMovie.js b/frontend/src/Collection/Overview/CollectionMovie.js index 2eb42afdc0..5e499c2dc3 100644 --- a/frontend/src/Collection/Overview/CollectionMovie.js +++ b/frontend/src/Collection/Overview/CollectionMovie.js @@ -2,7 +2,7 @@ import PropTypes from 'prop-types'; import React, { Component } from 'react'; import Link from 'Components/Link/Link'; import MonitorToggleButton from 'Components/MonitorToggleButton'; -import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; +import EditMovieModal from 'Movie/Edit/EditMovieModal'; import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar'; import MoviePoster from 'Movie/MoviePoster'; import translate from 'Utilities/String/translate'; @@ -172,7 +172,7 @@ class CollectionMovie extends Component { collectionId={collectionId} /> - - - - - ); -} - -EditMovieModal.propTypes = { - ...EditMovieModalContentConnector.propTypes, - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default EditMovieModal; diff --git a/frontend/src/Movie/Edit/EditMovieModal.tsx b/frontend/src/Movie/Edit/EditMovieModal.tsx new file mode 100644 index 0000000000..f4fcb50933 --- /dev/null +++ b/frontend/src/Movie/Edit/EditMovieModal.tsx @@ -0,0 +1,32 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import Modal from 'Components/Modal/Modal'; +import { clearPendingChanges } from 'Store/Actions/baseActions'; +import EditMovieModalContent, { + EditMovieModalContentProps, +} from './EditMovieModalContent'; + +interface EditMovieModalProps extends EditMovieModalContentProps { + isOpen: boolean; +} + +function EditMovieModal({ + isOpen, + onModalClose, + ...otherProps +}: EditMovieModalProps) { + const dispatch = useDispatch(); + + const handleModalClose = useCallback(() => { + dispatch(clearPendingChanges({ section: 'movies' })); + onModalClose(); + }, [dispatch, onModalClose]); + + return ( + + + + ); +} + +export default EditMovieModal; diff --git a/frontend/src/Movie/Edit/EditMovieModalConnector.js b/frontend/src/Movie/Edit/EditMovieModalConnector.js deleted file mode 100644 index d3eeb06786..0000000000 --- a/frontend/src/Movie/Edit/EditMovieModalConnector.js +++ /dev/null @@ -1,40 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearPendingChanges } from 'Store/Actions/baseActions'; -import EditMovieModal from './EditMovieModal'; - -const mapDispatchToProps = { - clearPendingChanges -}; - -class EditMovieModalConnector extends Component { - - // - // Listeners - - onModalClose = () => { - this.props.clearPendingChanges({ section: 'movies' }); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditMovieModalConnector.propTypes = { - ...EditMovieModal.propTypes, - onModalClose: PropTypes.func.isRequired, - clearPendingChanges: PropTypes.func.isRequired -}; - -export default connect(undefined, mapDispatchToProps)(EditMovieModalConnector); diff --git a/frontend/src/Movie/Edit/EditMovieModalContent.js b/frontend/src/Movie/Edit/EditMovieModalContent.js deleted file mode 100644 index f6cefb798f..0000000000 --- a/frontend/src/Movie/Edit/EditMovieModalContent.js +++ /dev/null @@ -1,217 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import MovieMinimumAvailabilityPopoverContent from 'AddMovie/MovieMinimumAvailabilityPopoverContent'; -import Form from 'Components/Form/Form'; -import FormGroup from 'Components/Form/FormGroup'; -import FormInputGroup from 'Components/Form/FormInputGroup'; -import FormLabel from 'Components/Form/FormLabel'; -import Icon from 'Components/Icon'; -import Button from 'Components/Link/Button'; -import SpinnerButton from 'Components/Link/SpinnerButton'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import Popover from 'Components/Tooltip/Popover'; -import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props'; -import MoveMovieModal from 'Movie/MoveMovie/MoveMovieModal'; -import translate from 'Utilities/String/translate'; -import styles from './EditMovieModalContent.css'; - -class EditMovieModalContent extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isConfirmMoveModalOpen: false - }; - } - - // - // Listeners - - onCancelPress = () => { - this.setState({ isConfirmMoveModalOpen: false }); - }; - - onSavePress = () => { - const { - isPathChanging, - onSavePress - } = this.props; - - if (isPathChanging && !this.state.isConfirmMoveModalOpen) { - this.setState({ isConfirmMoveModalOpen: true }); - } else { - this.setState({ isConfirmMoveModalOpen: false }); - - onSavePress(false); - } - }; - - onMoveMoviePress = () => { - this.setState({ isConfirmMoveModalOpen: false }); - - this.props.onSavePress(true); - }; - - // - // Render - - render() { - const { - title, - item, - isSaving, - originalPath, - onInputChange, - onModalClose, - onDeleteMoviePress, - ...otherProps - } = this.props; - - const { - monitored, - qualityProfileId, - minimumAvailability, - // Id, - path, - tags - } = item; - - return ( - - - {translate('Edit')} - {title} - - - -
- - {translate('Monitored')} - - - - - - - {translate('MinimumAvailability')} - - - } - title={translate('MinimumAvailability')} - body={} - position={tooltipPositions.RIGHT} - /> - - - - - - - {translate('QualityProfile')} - - - - - - {translate('Path')} - - - - - - {translate('Tags')} - - - -
-
- - - - - - - - {translate('Save')} - - - - -
- ); - } -} - -EditMovieModalContent.propTypes = { - movieId: PropTypes.number.isRequired, - title: PropTypes.string.isRequired, - item: PropTypes.object.isRequired, - isSaving: PropTypes.bool.isRequired, - isPathChanging: PropTypes.bool.isRequired, - originalPath: PropTypes.string.isRequired, - onInputChange: PropTypes.func.isRequired, - onSavePress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired, - onDeleteMoviePress: PropTypes.func.isRequired -}; - -export default EditMovieModalContent; diff --git a/frontend/src/Movie/Edit/EditMovieModalContent.tsx b/frontend/src/Movie/Edit/EditMovieModalContent.tsx new file mode 100644 index 0000000000..e0b3367367 --- /dev/null +++ b/frontend/src/Movie/Edit/EditMovieModalContent.tsx @@ -0,0 +1,229 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import MovieMinimumAvailabilityPopoverContent from 'AddMovie/MovieMinimumAvailabilityPopoverContent'; +import AppState from 'App/State/AppState'; +import Form from 'Components/Form/Form'; +import FormGroup from 'Components/Form/FormGroup'; +import FormInputGroup from 'Components/Form/FormInputGroup'; +import FormLabel from 'Components/Form/FormLabel'; +import Icon from 'Components/Icon'; +import Button from 'Components/Link/Button'; +import SpinnerErrorButton from 'Components/Link/SpinnerErrorButton'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import Popover from 'Components/Tooltip/Popover'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props'; +import MoveMovieModal from 'Movie/MoveMovie/MoveMovieModal'; +import useMovie from 'Movie/useMovie'; +import { saveMovie, setMovieValue } from 'Store/Actions/movieActions'; +import selectSettings from 'Store/Selectors/selectSettings'; +import { InputChanged } from 'typings/inputs'; +import translate from 'Utilities/String/translate'; +import styles from './EditMovieModalContent.css'; + +export interface EditMovieModalContentProps { + movieId: number; + onModalClose: () => void; + onDeleteMoviePress: () => void; +} + +function EditMovieModalContent({ + movieId, + onModalClose, + onDeleteMoviePress, +}: EditMovieModalContentProps) { + const dispatch = useDispatch(); + const { + title, + monitored, + minimumAvailability, + qualityProfileId, + path, + tags, + } = useMovie(movieId)!; + + const { isSaving, saveError, pendingChanges } = useSelector( + (state: AppState) => state.movies + ); + + const wasSaving = usePrevious(isSaving); + + const isPathChanging = pendingChanges.path && path !== pendingChanges.path; + + const [isConfirmMoveModalOpen, setIsConfirmMoveModalOpen] = useState(false); + + const { settings, ...otherSettings } = useMemo(() => { + return selectSettings( + { + monitored, + minimumAvailability, + qualityProfileId, + path, + tags, + }, + pendingChanges, + saveError + ); + }, [ + monitored, + minimumAvailability, + qualityProfileId, + path, + tags, + pendingChanges, + saveError, + ]); + + const handleInputChange = useCallback( + ({ name, value }: InputChanged) => { + // @ts-expect-error actions aren't typed + dispatch(setMovieValue({ name, value })); + }, + [dispatch] + ); + + const handleCancelPress = useCallback(() => { + setIsConfirmMoveModalOpen(false); + }, []); + + const handleSavePress = useCallback(() => { + if (isPathChanging && !isConfirmMoveModalOpen) { + setIsConfirmMoveModalOpen(true); + } else { + setIsConfirmMoveModalOpen(false); + + dispatch( + saveMovie({ + id: movieId, + moveFiles: false, + }) + ); + } + }, [movieId, isPathChanging, isConfirmMoveModalOpen, dispatch]); + + const handleMoveMoviePress = useCallback(() => { + setIsConfirmMoveModalOpen(false); + + dispatch( + saveMovie({ + id: movieId, + moveFiles: true, + }) + ); + }, [movieId, dispatch]); + + useEffect(() => { + if (!isSaving && wasSaving && !saveError) { + onModalClose(); + } + }, [isSaving, wasSaving, saveError, onModalClose]); + + return ( + + {translate('EditMovieModalHeader', { title })} + + +
+ + {translate('Monitored')} + + + + + + + {translate('MinimumAvailability')} + + } + title={translate('MinimumAvailability')} + body={} + position={tooltipPositions.RIGHT} + /> + + + + + + + {translate('QualityProfile')} + + + + + + {translate('Path')} + + + + + + {translate('Tags')} + + + +
+
+ + + + + + + + {translate('Save')} + + + + +
+ ); +} + +export default EditMovieModalContent; diff --git a/frontend/src/Movie/Edit/EditMovieModalContentConnector.js b/frontend/src/Movie/Edit/EditMovieModalContentConnector.js deleted file mode 100644 index 4fae004900..0000000000 --- a/frontend/src/Movie/Edit/EditMovieModalContentConnector.js +++ /dev/null @@ -1,115 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { saveMovie, setMovieValue } from 'Store/Actions/movieActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import selectSettings from 'Store/Selectors/selectSettings'; -import EditMovieModalContent from './EditMovieModalContent'; - -function createIsPathChangingSelector() { - return createSelector( - (state) => state.movies.pendingChanges, - createMovieSelector(), - (pendingChanges, movie) => { - const path = pendingChanges.path; - - if (path == null) { - return false; - } - - return movie.path !== path; - } - ); -} - -function createMapStateToProps() { - return createSelector( - (state) => state.movies, - createMovieSelector(), - createIsPathChangingSelector(), - (moviesState, movie, isPathChanging) => { - const { - isSaving, - saveError, - pendingChanges - } = moviesState; - - const movieSettings = { - monitored: movie.monitored, - qualityProfileId: movie.qualityProfileId, - minimumAvailability: movie.minimumAvailability, - path: movie.path, - tags: movie.tags - }; - - const settings = selectSettings(movieSettings, pendingChanges, saveError); - - return { - title: movie.title, - isSaving, - saveError, - isPathChanging, - originalPath: movie.path, - item: settings.settings, - ...settings - }; - } - ); -} - -const mapDispatchToProps = { - dispatchSetMovieValue: setMovieValue, - dispatchSaveMovie: saveMovie -}; - -class EditMovieModalContentConnector extends Component { - - // - // Lifecycle - - componentDidUpdate(prevProps, prevState) { - if (prevProps.isSaving && !this.props.isSaving && !this.props.saveError) { - this.props.onModalClose(); - } - } - - // - // Listeners - - onInputChange = ({ name, value }) => { - this.props.dispatchSetMovieValue({ name, value }); - }; - - onSavePress = (moveFiles) => { - this.props.dispatchSaveMovie({ - id: this.props.movieId, - moveFiles - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -EditMovieModalContentConnector.propTypes = { - movieId: PropTypes.number, - isSaving: PropTypes.bool.isRequired, - saveError: PropTypes.object, - dispatchSetMovieValue: PropTypes.func.isRequired, - dispatchSaveMovie: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(EditMovieModalContentConnector); diff --git a/frontend/src/Movie/Index/Overview/MovieIndexOverview.tsx b/frontend/src/Movie/Index/Overview/MovieIndexOverview.tsx index af28196778..50ea54a77c 100644 --- a/frontend/src/Movie/Index/Overview/MovieIndexOverview.tsx +++ b/frontend/src/Movie/Index/Overview/MovieIndexOverview.tsx @@ -11,7 +11,7 @@ import Popover from 'Components/Tooltip/Popover'; import { icons } from 'Helpers/Props'; import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks'; -import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector'; +import EditMovieModal from 'Movie/Edit/EditMovieModal'; import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar'; import MovieIndexPosterSelect from 'Movie/Index/Select/MovieIndexPosterSelect'; import { Statistics } from 'Movie/Movie'; @@ -250,7 +250,7 @@ function MovieIndexOverview(props: MovieIndexOverviewProps) {
- - Date: Fri, 7 Mar 2025 18:35:12 +0200 Subject: [PATCH 238/579] Increase input sizes in edit movie modal Closes #10749 --- .../src/Movie/Edit/EditMovieModalContent.tsx | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/frontend/src/Movie/Edit/EditMovieModalContent.tsx b/frontend/src/Movie/Edit/EditMovieModalContent.tsx index e0b3367367..8f28313770 100644 --- a/frontend/src/Movie/Edit/EditMovieModalContent.tsx +++ b/frontend/src/Movie/Edit/EditMovieModalContent.tsx @@ -15,7 +15,13 @@ import ModalFooter from 'Components/Modal/ModalFooter'; import ModalHeader from 'Components/Modal/ModalHeader'; import Popover from 'Components/Tooltip/Popover'; import usePrevious from 'Helpers/Hooks/usePrevious'; -import { icons, inputTypes, kinds, tooltipPositions } from 'Helpers/Props'; +import { + icons, + inputTypes, + kinds, + sizes, + tooltipPositions, +} from 'Helpers/Props'; import MoveMovieModal from 'Movie/MoveMovie/MoveMovieModal'; import useMovie from 'Movie/useMovie'; import { saveMovie, setMovieValue } from 'Store/Actions/movieActions'; @@ -127,7 +133,7 @@ function EditMovieModalContent({
- + {translate('Monitored')} - + {translate('MinimumAvailability')} @@ -159,7 +165,7 @@ function EditMovieModalContent({ /> - + {translate('QualityProfile')} - + {translate('Path')} - + {translate('Tags')} Date: Fri, 7 Mar 2025 19:17:58 +0200 Subject: [PATCH 239/579] Bump SixLabors.ImageSharp to 3.1.7 --- src/NzbDrone.Core/Radarr.Core.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NzbDrone.Core/Radarr.Core.csproj b/src/NzbDrone.Core/Radarr.Core.csproj index a5ae1fd538..3be8e2c3e6 100644 --- a/src/NzbDrone.Core/Radarr.Core.csproj +++ b/src/NzbDrone.Core/Radarr.Core.csproj @@ -21,7 +21,7 @@ - + From 049bf7715e314073de8f32826ab18e33ae6fa13d Mon Sep 17 00:00:00 2001 From: Weblate Date: Sat, 8 Mar 2025 13:15:31 +0000 Subject: [PATCH 240/579] Multiple Translations updated by Weblate ignore-downstream Co-authored-by: Oskari Lavinto Co-authored-by: Weblate Co-authored-by: Weblate Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/ Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/ Translation: Servarr/Radarr --- src/NzbDrone.Core/Localization/Core/de.json | 3 ++- src/NzbDrone.Core/Localization/Core/es.json | 3 ++- src/NzbDrone.Core/Localization/Core/fi.json | 27 ++++++++++--------- src/NzbDrone.Core/Localization/Core/fr.json | 3 ++- src/NzbDrone.Core/Localization/Core/hu.json | 3 ++- src/NzbDrone.Core/Localization/Core/it.json | 3 ++- .../Localization/Core/pt_BR.json | 3 ++- src/NzbDrone.Core/Localization/Core/ru.json | 3 ++- src/NzbDrone.Core/Localization/Core/tr.json | 3 ++- .../Localization/Core/zh_CN.json | 3 ++- 10 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 6d6ab9c77d..6ea84b59e1 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -1909,5 +1909,6 @@ "ImportListsTraktSettingsUserListTypeWatched": "Benutzer-Gesehene-Liste", "ImportListsTraktSettingsWatchListSorting": "Sortierung der Gesehenen Liste", "ImportListsTraktSettingsUserListUsernameHelpText": "Benutzername für die Liste, von der du importieren möchtest (leer lassen, um den Authentifizierten Benutzer zu verwenden)", - "ImportListsTraktSettingsWatchListSortingHelpText": "Wenn der Listentyp 'Gesehen' ist, wähle die Reihenfolge, in der die Liste sortiert werden soll" + "ImportListsTraktSettingsWatchListSortingHelpText": "Wenn der Listentyp 'Gesehen' ist, wähle die Reihenfolge, in der die Liste sortiert werden soll", + "EditMovieModalHeader": "Bearbeiten - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index e3351f552c..1212f769b4 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -1932,5 +1932,6 @@ "FailedAt": "Error el {date}", "GrabbedAt": "Capturado el {date}", "ReleaseSource": "Origen del lanzamiento", - "DownloadClientUTorrentProviderMessage": "Debido a que uTorrent es conocido por el cryptoware, el malware y la publicidad, sugerimos cambiar a un cliente mejor como qBittorrent, Deluge o ruTorrent." + "DownloadClientUTorrentProviderMessage": "Debido a que uTorrent es conocido por el cryptoware, el malware y la publicidad, sugerimos cambiar a un cliente mejor como qBittorrent, Deluge o ruTorrent.", + "EditMovieModalHeader": "Editar - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index bd91087ad4..bd8a460a12 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -50,7 +50,7 @@ "MinimumAgeHelpText": "Vain Usenet: NZB:n vähimmäisikä minuutteina, ennen niiden kaappausta. Tämän avulla uusille julkaisuille voidaan antaa aikaa levitä Usenet-palveluntarjoajalle.", "MinimumFreeSpaceHelpText": "Estä tuonti, jos sen jälkeinen vapaa levytila olisi tässä määritettyä pienempi.", "MonitoredMovieHelpText": "Elokuvaa etsitään ja se ladataan, jos se on saatavilla.", - "MoveMovieFoldersToRootFolder": "Haluatko siirtää elokuvakansiot kohteeseen \"{0}\"?", + "MoveMovieFoldersToRootFolder": "Haluatko siirtää elokuvakansiot kohteeseen \"{destinationRootFolder}\"?", "MovieChat": "Elokuvakeskustelu", "MultiLanguage": "Useita kieliä", "PosterOptions": "Julistenäkymän asetukset", @@ -201,7 +201,7 @@ "NoEventsFound": "Tapahtumia ei löytynyt", "NoLinks": "Linkkejä ei ole", "NoMinimumForAnyRuntime": "Ei toistoajan vähimmäiskestoa", - "MoveMovieFoldersDontMoveFiles": " Ei, siirrän tiedostot itse", + "MoveMovieFoldersDontMoveFiles": "En, siirrän tiedostot itse", "NoMoviesExist": "Elokuvia ei löytynyt. Aloita lisäämällä uusi elokuva tai tuo joitakin olemassa olevia.", "NoResultsFound": "Tuloksia ei löytynyt.", "BranchUpdate": "{appName}in versiopäivityksiin käytettävä kehityshaara.", @@ -938,7 +938,7 @@ "MaintenanceRelease": "Huoltojulkaisu: korjauksia ja muita parannuksia. Lue lisää Githubin muutoshistoriasta.", "MissingMonitoredAndConsideredAvailable": "Puuttuu (valvotaan)", "MissingNotMonitored": "Puuttuu (valvomattomat)", - "MoveMovieFoldersToNewPath": "Haluatko siirtää elokuvatiedostot kansiosta {0} kansioon {1}?", + "MoveMovieFoldersToNewPath": "Haluatko siirtää elokuvatiedostot lähteestä \"{originalPath}\" kohteeseen \"{destinationPath}\"?", "MovieDetailsPreviousMovie": "Elokuvan tiedot: Edellinen elokuva", "MovieEditor": "Elokuvien monivalinta", "MovieExcludedFromAutomaticAdd": "Elokuvaa ei huomioida automaattisessa lisäyksessä.", @@ -1908,29 +1908,30 @@ "ImportListsTraktSettingsYears": "Vuodet", "ImportListsTraktSettingsCertificationMovieHelpText": "Suodata elokuvia ikäluokitusten perusteella (NR,G,PG,PG-13,R,NC-17) (pilkuin eroteltuna).", "ImportListsTraktSettingsPopularListTypeRecommendedMoviesOfAllTime": "Kaikkien aikojen elokuvasuositukset", - "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Kuukausikohtaiset elokuvasuositukset", - "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Viikkokohtaiset elokuvasuositukset", - "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Vuosikohtaiset elokuvasuositukset", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByMonth": "Elokuvasuositukset kuukausittain", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByWeek": "Elokuvasuositukset viikottain", + "ImportListsTraktSettingsPopularListTypeRecommendedMoviesByYear": "Elokuvasuositukset vuosittain", "ImportListsTraktSettingsPopularListTypePopularMovies": "Suositut elokuvat", "ImportListsTraktSettingsLimitMovieHelpText": "Rajoita noudettavien elokuvien määrää.", "ImportListsTraktSettingsPopularListTypeTopAnticipatedMovies": "Odotetuimmat elokuvat", - "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Viikottain katsotuimmat elokuvat", - "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Kuukausittain katsotuimmat elokuvat", - "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Vuosittain katsotuimmat elokuvat", - "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Teattereissa katsotuimmat elokuvat", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByWeek": "Katsotuimmat elokuvat viikottain", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByMonth": "Katsotuimmat elokuvat kuukausittain", + "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesByYear": "Katsotuimmat elokuvat vuosittain", + "ImportListsTraktSettingsPopularListTypeTopBoxOfficeMovies": "Katsotuimmat elokuvat teattereissa", "ImportListsTraktSettingsYearsMovieHelpText": "Suodata elokuvia vuoden tai vuosivälin perusteella.", "ImportListsTraktSettingsRatingMovieHelpText": "Suodata elokuvia arvioden perusteella (alue 0–100).", "ImportListsTraktSettingsPopularListTypeTopWatchedMoviesOfAllTime": "Kaikkien aikojen katsotuimmat elokuvat", "ImportListsTraktSettingsPopularListTypeTrendingMovies": "Trendaavat elokuvat", "ImportListsTraktSettingsGenresMovieHelpText": "Suodata elokuvia Trakt-lajityyppien slug-arvojen perusteella (pilkuin eroteltuna). Koskee vain suosituimpia listoja.", - "ImportListsTraktSettingsUserListTypeCollection": "Käyttäjän kokoelmat", + "ImportListsTraktSettingsUserListTypeCollection": "Käyttäjän kokoelmalista", "ImportListsTraktSettingsUserListTypeWatch": "Käyttäjän katselulista", "ImportListsTraktSettingsUserListTypeWatched": "Käyttäjän katseltujen lista", "ImportListsTraktSettingsUserListUsernameHelpText": "Listan tuontiin käytettävä käyttäjänimi. Käytä tunnistautunutta käyttäjää jättämällä tyhjäksi.", "ImportListsTraktSettingsWatchListSorting": "Katselulistan järjestys", "DownloadClientUTorrentProviderMessage": "Koska uTorrent on tunnettu crypto-, haitta- and mainossisällöstä ja sovelluksista, suosittelemme esimerkiksi qBittorrentin, Delugen ja ruTorrentin kaltaisia parempia sovelluksia.", - "ImportListsTraktSettingsWatchListSortingHelpText": "Jos lista on katslutyyppinen, valitse sen järjestystapa.", + "ImportListsTraktSettingsWatchListSortingHelpText": "Jos \"Listan tyyppi\" on \"Katselu\", valitse listan järjestysperuste.", "BlocklistedAt": "Estetty {date}", "FailedAt": "Epäonnistui {date}", - "GrabbedAt": "Kaapattu {date}" + "GrabbedAt": "Kaapattu {date}", + "EditMovieModalHeader": "Muokataan – {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 6b91282ffc..40c1a7032d 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -1909,5 +1909,6 @@ "ImportListsTraktSettingsWatchListSorting": "Tri de la liste de surveillance", "ImportListsTraktSettingsUserListTypeWatch": "Liste de surveillance des utilisateurs", "ImportListsTraktSettingsUserListTypeWatched": "Liste des utilisateurs surveillés", - "ImportListsTraktSettingsWatchListSortingHelpText": "Si le type de liste est surveillé, sélectionnez l'ordre de tri de la liste" + "ImportListsTraktSettingsWatchListSortingHelpText": "Si le type de liste est surveillé, sélectionnez l'ordre de tri de la liste", + "EditMovieModalHeader": "Modifier - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 2b8e33b3b7..4515108fe0 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -1477,5 +1477,6 @@ "ImportListsTraktSettingsUserListTypeWatched": "Felhasználói figyelt lista", "ImportListsTraktSettingsUserListUsernameHelpText": "Felhasználónév az importálandó listához (hagyja üresen az Auth User használatához)", "ImportListsTraktSettingsWatchListSorting": "Figyelőlista rendezése", - "ImportListsTraktSettingsWatchListSortingHelpText": "Ha a Lista típusa Figyelt, válassza ki a sorrendet a lista rendezéséhez" + "ImportListsTraktSettingsWatchListSortingHelpText": "Ha a Lista típusa Figyelt, válassza ki a sorrendet a lista rendezéséhez", + "EditMovieModalHeader": "Szerkesztés – {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 34baafe832..9dfac63ac1 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -1501,5 +1501,6 @@ "ImportListsTraktSettingsCertification": "Certificazione", "ImportListsTraktSettingsGenres": "Generi", "ImportListsTraktSettingsLimit": "Limite", - "ImportListsTraktSettingsListType": "Tipo Lista" + "ImportListsTraktSettingsListType": "Tipo Lista", + "EditMovieModalHeader": "Modifica - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index 4d7a22f243..d8ab1f31a5 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -1932,5 +1932,6 @@ "DownloadClientUTorrentProviderMessage": "Como o uTorrent é conhecido por CryptoWare, malware e anúncios, sugerimos mudar para um cliente melhor como Qbittorrent, Deluge ou ruTorrent.", "BlocklistedAt": "Lista de bloqueio em {date}", "FailedAt": "Falhou em {date}", - "GrabbedAt": "Obtido em {date}" + "GrabbedAt": "Obtido em {date}", + "EditMovieModalHeader": "Editar - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index ade8eb46a6..a165bae602 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -1928,5 +1928,6 @@ "MovieFileRenamed": "Файл фильма переименован", "MovieFileRenamedTooltip": "Файл фильма переименован", "MovieFolderImportedTooltip": "Фильм импортирован из папки фильма", - "Recommended": "Рекомендуемое" + "Recommended": "Рекомендуемое", + "EditMovieModalHeader": "Изменить – {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 782007968d..943a525349 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -1932,5 +1932,6 @@ "DownloadClientUTorrentProviderMessage": "uTorrent, kripto yazılımlar, kötü amaçlı yazılımlar ve reklamlarla tanındığı için qBittorrent, Deluge veya ruTorrent gibi daha iyi bir istemciye geçmenizi öneririz.", "BlocklistedAt": "{date} tarihinde engellendi", "FailedAt": "{date} tarihinde başarısız oldu", - "GrabbedAt": "{date} tarihinde yakalandı" + "GrabbedAt": "{date} tarihinde yakalandı", + "EditMovieModalHeader": "Düzenle - {title}" } diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index a20722a919..778987a55f 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -1930,5 +1930,6 @@ "ImportListsTraktSettingsYearsMovieHelpText": "按年份或年份范围筛选电影", "AutoTaggingSpecificationMaximumRuntime": "最大运行时间", "AutoTaggingSpecificationMinimumRuntime": "最小运行时间", - "DownloadClientUTorrentProviderMessage": "由于uTorrent以加密软件、恶意软件和广告而闻名,我们建议切换到更好的客户端,例如qBittorrent、Deluge或ruTorrent。" + "DownloadClientUTorrentProviderMessage": "由于uTorrent以加密软件、恶意软件和广告而闻名,我们建议切换到更好的客户端,例如qBittorrent、Deluge或ruTorrent。", + "EditMovieModalHeader": "编辑 - {title}" } From e4e96fc7f9b95fc2423fc628fa45c6773cbf5330 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 22 Dec 2024 21:46:10 -0800 Subject: [PATCH 241/579] Convert Preview Rename to TypeScript (cherry picked from commit a2fd23c84d0a9d01864119d2e643970845c9e49e) --- frontend/src/App/State/AppState.ts | 2 + .../src/App/State/OrganizePreviewAppState.ts | 13 ++ frontend/src/Movie/Details/MovieDetails.js | 4 +- frontend/src/Organize/OrganizePreviewModal.js | 34 --- .../src/Organize/OrganizePreviewModal.tsx | 37 ++++ .../Organize/OrganizePreviewModalConnector.js | 39 ---- .../Organize/OrganizePreviewModalContent.js | 196 ------------------ .../Organize/OrganizePreviewModalContent.tsx | 193 +++++++++++++++++ .../OrganizePreviewModalContentConnector.js | 88 -------- frontend/src/Organize/OrganizePreviewRow.js | 90 -------- frontend/src/Organize/OrganizePreviewRow.tsx | 61 ++++++ frontend/src/typings/inputs.ts | 4 +- 12 files changed, 311 insertions(+), 450 deletions(-) create mode 100644 frontend/src/App/State/OrganizePreviewAppState.ts delete mode 100644 frontend/src/Organize/OrganizePreviewModal.js create mode 100644 frontend/src/Organize/OrganizePreviewModal.tsx delete mode 100644 frontend/src/Organize/OrganizePreviewModalConnector.js delete mode 100644 frontend/src/Organize/OrganizePreviewModalContent.js create mode 100644 frontend/src/Organize/OrganizePreviewModalContent.tsx delete mode 100644 frontend/src/Organize/OrganizePreviewModalContentConnector.js delete mode 100644 frontend/src/Organize/OrganizePreviewRow.js create mode 100644 frontend/src/Organize/OrganizePreviewRow.tsx diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index 82dcc9341b..3203fae548 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -9,6 +9,7 @@ import MovieCreditAppState from './MovieCreditAppState'; import MovieFilesAppState from './MovieFilesAppState'; import MovieHistoryAppState from './MovieHistoryAppState'; import MoviesAppState, { MovieIndexAppState } from './MoviesAppState'; +import OrganizePreviewAppState from './OrganizePreviewAppState'; import ParseAppState from './ParseAppState'; import PathsAppState from './PathsAppState'; import QueueAppState from './QueueAppState'; @@ -76,6 +77,7 @@ interface AppState { movieHistory: MovieHistoryAppState; movieIndex: MovieIndexAppState; movies: MoviesAppState; + organizePreview: OrganizePreviewAppState; parse: ParseAppState; paths: PathsAppState; queue: QueueAppState; diff --git a/frontend/src/App/State/OrganizePreviewAppState.ts b/frontend/src/App/State/OrganizePreviewAppState.ts new file mode 100644 index 0000000000..b8b907852b --- /dev/null +++ b/frontend/src/App/State/OrganizePreviewAppState.ts @@ -0,0 +1,13 @@ +import ModelBase from 'App/ModelBase'; +import AppSectionState from 'App/State/AppSectionState'; + +export interface OrganizePreviewModel extends ModelBase { + movieId: number; + movieFileId: number; + existingPath: string; + newPath: string; +} + +type OrganizePreviewAppState = AppSectionState; + +export default OrganizePreviewAppState; diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 077f8cb65b..6b23dee7e3 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -33,7 +33,7 @@ import MoviePoster from 'Movie/MoviePoster'; import MovieInteractiveSearchModal from 'Movie/Search/MovieInteractiveSearchModal'; import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable'; import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable'; -import OrganizePreviewModalConnector from 'Organize/OrganizePreviewModalConnector'; +import OrganizePreviewModal from 'Organize/OrganizePreviewModal'; import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; import fonts from 'Styles/Variables/fonts'; import * as keyCodes from 'Utilities/Constants/keyCodes'; @@ -724,7 +724,7 @@ class MovieDetails extends Component {
- - { - isOpen && - - } - - ); -} - -OrganizePreviewModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default OrganizePreviewModal; diff --git a/frontend/src/Organize/OrganizePreviewModal.tsx b/frontend/src/Organize/OrganizePreviewModal.tsx new file mode 100644 index 0000000000..4160a5885b --- /dev/null +++ b/frontend/src/Organize/OrganizePreviewModal.tsx @@ -0,0 +1,37 @@ +import React, { useCallback } from 'react'; +import { useDispatch } from 'react-redux'; +import Modal from 'Components/Modal/Modal'; +import { clearOrganizePreview } from 'Store/Actions/organizePreviewActions'; +import OrganizePreviewModalContent, { + OrganizePreviewModalContentProps, +} from './OrganizePreviewModalContent'; + +interface OrganizePreviewModalProps extends OrganizePreviewModalContentProps { + isOpen: boolean; + onModalClose: () => void; +} + +function OrganizePreviewModal({ + isOpen, + onModalClose, + ...otherProps +}: OrganizePreviewModalProps) { + const dispatch = useDispatch(); + + const handleOnModalClose = useCallback(() => { + dispatch(clearOrganizePreview()); + onModalClose(); + }, [dispatch, onModalClose]); + + return ( + + {isOpen ? ( + + ) : null} + + ); +} +export default OrganizePreviewModal; diff --git a/frontend/src/Organize/OrganizePreviewModalConnector.js b/frontend/src/Organize/OrganizePreviewModalConnector.js deleted file mode 100644 index 4abcaf8422..0000000000 --- a/frontend/src/Organize/OrganizePreviewModalConnector.js +++ /dev/null @@ -1,39 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { clearOrganizePreview } from 'Store/Actions/organizePreviewActions'; -import OrganizePreviewModal from './OrganizePreviewModal'; - -const mapDispatchToProps = { - clearOrganizePreview -}; - -class OrganizePreviewModalConnector extends Component { - - // - // Listeners - - onModalClose = () => { - this.props.clearOrganizePreview(); - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -OrganizePreviewModalConnector.propTypes = { - clearOrganizePreview: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(undefined, mapDispatchToProps)(OrganizePreviewModalConnector); diff --git a/frontend/src/Organize/OrganizePreviewModalContent.js b/frontend/src/Organize/OrganizePreviewModalContent.js deleted file mode 100644 index 33ee8baa6c..0000000000 --- a/frontend/src/Organize/OrganizePreviewModalContent.js +++ /dev/null @@ -1,196 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import CheckInput from 'Components/Form/CheckInput'; -import Button from 'Components/Link/Button'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import { kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import getSelectedIds from 'Utilities/Table/getSelectedIds'; -import selectAll from 'Utilities/Table/selectAll'; -import toggleSelected from 'Utilities/Table/toggleSelected'; -import OrganizePreviewRow from './OrganizePreviewRow'; -import styles from './OrganizePreviewModalContent.css'; - -function getValue(allSelected, allUnselected) { - if (allSelected) { - return true; - } else if (allUnselected) { - return false; - } - - return null; -} - -class OrganizePreviewModalContent extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - allSelected: false, - allUnselected: false, - lastToggled: null, - selectedState: {} - }; - } - - // - // Control - - getSelectedIds = () => { - return getSelectedIds(this.state.selectedState); - }; - - // - // Listeners - - onSelectAllChange = ({ value }) => { - this.setState(selectAll(this.state.selectedState, value)); - }; - - onSelectedChange = ({ id, value, shiftKey = false }) => { - this.setState((state) => { - return toggleSelected(state, this.props.items, id, value, shiftKey); - }); - }; - - onOrganizePress = () => { - this.props.onOrganizePress(this.getSelectedIds()); - }; - - // - // Render - - render() { - const { - isFetching, - isPopulated, - error, - items, - renameMovies, - standardMovieFormat, - path, - onModalClose - } = this.props; - - const { - allSelected, - allUnselected, - selectedState - } = this.state; - - const selectAllValue = getValue(allSelected, allUnselected); - - return ( - - - {translate('OrganizeModalHeader')} - - - - { - isFetching && - - } - - { - !isFetching && error && - {translate('OrganizeLoadError')} - } - - { - !isFetching && isPopulated && !items.length && -
- { - renameMovies ? -
{translate('OrganizeNothingToRename')}
: -
{translate('OrganizeRenamingDisabled')}
- } -
- } - - { - !isFetching && isPopulated && !!items.length && -
- -
- -
- -
- -
-
- -
- { - items.map((item) => { - return ( - - ); - }) - } -
-
- } -
- - - { - isPopulated && !!items.length && - - } - - - - - -
- ); - } -} - -OrganizePreviewModalContent.propTypes = { - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - path: PropTypes.string.isRequired, - renameMovies: PropTypes.bool, - standardMovieFormat: PropTypes.string, - onOrganizePress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default OrganizePreviewModalContent; diff --git a/frontend/src/Organize/OrganizePreviewModalContent.tsx b/frontend/src/Organize/OrganizePreviewModalContent.tsx new file mode 100644 index 0000000000..009345c6d4 --- /dev/null +++ b/frontend/src/Organize/OrganizePreviewModalContent.tsx @@ -0,0 +1,193 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import * as commandNames from 'Commands/commandNames'; +import Alert from 'Components/Alert'; +import CheckInput from 'Components/Form/CheckInput'; +import Button from 'Components/Link/Button'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import useSelectState from 'Helpers/Hooks/useSelectState'; +import { kinds } from 'Helpers/Props'; +import useMovie from 'Movie/useMovie'; +import { executeCommand } from 'Store/Actions/commandActions'; +import { fetchOrganizePreview } from 'Store/Actions/organizePreviewActions'; +import { fetchNamingSettings } from 'Store/Actions/settingsActions'; +import { CheckInputChanged } from 'typings/inputs'; +import { SelectStateInputProps } from 'typings/props'; +import translate from 'Utilities/String/translate'; +import getSelectedIds from 'Utilities/Table/getSelectedIds'; +import OrganizePreviewRow from './OrganizePreviewRow'; +import styles from './OrganizePreviewModalContent.css'; + +function getValue(allSelected: boolean, allUnselected: boolean) { + if (allSelected) { + return true; + } else if (allUnselected) { + return false; + } + + return null; +} + +export interface OrganizePreviewModalContentProps { + movieId: number; + onModalClose: () => void; +} + +function OrganizePreviewModalContent({ + movieId, + onModalClose, +}: OrganizePreviewModalContentProps) { + const dispatch = useDispatch(); + const { + items, + isFetching: isPreviewFetching, + isPopulated: isPreviewPopulated, + error: previewError, + } = useSelector((state: AppState) => state.organizePreview); + + const { + isFetching: isNamingFetching, + isPopulated: isNamingPopulated, + error: namingError, + item: naming, + } = useSelector((state: AppState) => state.settings.naming); + + const movie = useMovie(movieId)!; + const [selectState, setSelectState] = useSelectState(); + + const { allSelected, allUnselected, selectedState } = selectState; + const isFetching = isPreviewFetching || isNamingFetching; + const isPopulated = isPreviewPopulated && isNamingPopulated; + const error = previewError || namingError; + const { renameMovies, standardMovieFormat } = naming; + + const selectAllValue = getValue(allSelected, allUnselected); + + const handleSelectAllChange = useCallback( + ({ value }: CheckInputChanged) => { + setSelectState({ type: value ? 'selectAll' : 'unselectAll', items }); + }, + [items, setSelectState] + ); + + const handleSelectedChange = useCallback( + ({ id, value, shiftKey = false }: SelectStateInputProps) => { + setSelectState({ + type: 'toggleSelected', + items, + id, + isSelected: value, + shiftKey, + }); + }, + [items, setSelectState] + ); + + const handleOrganizePress = useCallback(() => { + const files = getSelectedIds(selectedState); + + dispatch( + executeCommand({ + name: commandNames.RENAME_FILES, + files, + movieId, + }) + ); + + onModalClose(); + }, [movieId, selectedState, dispatch, onModalClose]); + + useEffect(() => { + dispatch(fetchOrganizePreview({ movieId })); + dispatch(fetchNamingSettings()); + }, [movieId, dispatch]); + + return ( + + {translate('OrganizeModalHeader')} + + + {isFetching ? : null} + + {!isFetching && error ? ( + {translate('OrganizeLoadError')} + ) : null} + + {!isFetching && isPopulated && !items.length ? ( +
+ {renameMovies ? ( +
{translate('OrganizeNothingToRename')}
+ ) : ( +
{translate('OrganizeRenamingDisabled')}
+ )} +
+ ) : null} + + {!isFetching && isPopulated && items.length ? ( +
+ +
+ +
+ +
+ +
+
+ +
+ {items.map((item) => { + return ( + + ); + })} +
+
+ ) : null} +
+ + + {isPopulated && items.length ? ( + + ) : null} + + + + + +
+ ); +} + +export default OrganizePreviewModalContent; diff --git a/frontend/src/Organize/OrganizePreviewModalContentConnector.js b/frontend/src/Organize/OrganizePreviewModalContentConnector.js deleted file mode 100644 index b171f69162..0000000000 --- a/frontend/src/Organize/OrganizePreviewModalContentConnector.js +++ /dev/null @@ -1,88 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import * as commandNames from 'Commands/commandNames'; -import { executeCommand } from 'Store/Actions/commandActions'; -import { fetchOrganizePreview } from 'Store/Actions/organizePreviewActions'; -import { fetchNamingSettings } from 'Store/Actions/settingsActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import OrganizePreviewModalContent from './OrganizePreviewModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.organizePreview, - (state) => state.settings.naming, - createMovieSelector(), - (organizePreview, naming, movie) => { - const props = { ...organizePreview }; - props.isFetching = organizePreview.isFetching || naming.isFetching; - props.isPopulated = organizePreview.isPopulated && naming.isPopulated; - props.error = organizePreview.error || naming.error; - props.renameMovies = naming.item.renameMovies; - props.standardMovieFormat = naming.item.standardMovieFormat; - props.path = movie.path; - - return props; - } - ); -} - -const mapDispatchToProps = { - fetchOrganizePreview, - fetchNamingSettings, - executeCommand -}; - -class OrganizePreviewModalContentConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - movieId - } = this.props; - - this.props.fetchOrganizePreview({ - movieId - }); - - this.props.fetchNamingSettings(); - } - - // - // Listeners - - onOrganizePress = (files) => { - this.props.executeCommand({ - name: commandNames.RENAME_FILES, - movieId: this.props.movieId, - files - }); - - this.props.onModalClose(); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -OrganizePreviewModalContentConnector.propTypes = { - movieId: PropTypes.number.isRequired, - fetchOrganizePreview: PropTypes.func.isRequired, - fetchNamingSettings: PropTypes.func.isRequired, - executeCommand: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(OrganizePreviewModalContentConnector); diff --git a/frontend/src/Organize/OrganizePreviewRow.js b/frontend/src/Organize/OrganizePreviewRow.js deleted file mode 100644 index 00040ba3ed..0000000000 --- a/frontend/src/Organize/OrganizePreviewRow.js +++ /dev/null @@ -1,90 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import CheckInput from 'Components/Form/CheckInput'; -import Icon from 'Components/Icon'; -import { icons, kinds } from 'Helpers/Props'; -import styles from './OrganizePreviewRow.css'; - -class OrganizePreviewRow extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - id, - onSelectedChange - } = this.props; - - onSelectedChange({ id, value: true }); - } - - // - // Listeners - - onSelectedChange = ({ value, shiftKey }) => { - const { - id, - onSelectedChange - } = this.props; - - onSelectedChange({ id, value, shiftKey }); - }; - - // - // Render - - render() { - const { - id, - existingPath, - newPath, - isSelected - } = this.props; - - return ( -
- - -
-
- - - - {existingPath} - -
- -
- - - - {newPath} - -
-
-
- ); - } -} - -OrganizePreviewRow.propTypes = { - id: PropTypes.number.isRequired, - existingPath: PropTypes.string.isRequired, - newPath: PropTypes.string.isRequired, - isSelected: PropTypes.bool, - onSelectedChange: PropTypes.func.isRequired -}; - -export default OrganizePreviewRow; diff --git a/frontend/src/Organize/OrganizePreviewRow.tsx b/frontend/src/Organize/OrganizePreviewRow.tsx new file mode 100644 index 0000000000..398ea31ea1 --- /dev/null +++ b/frontend/src/Organize/OrganizePreviewRow.tsx @@ -0,0 +1,61 @@ +import React, { useCallback, useEffect } from 'react'; +import CheckInput from 'Components/Form/CheckInput'; +import Icon from 'Components/Icon'; +import { icons, kinds } from 'Helpers/Props'; +import { CheckInputChanged } from 'typings/inputs'; +import { SelectStateInputProps } from 'typings/props'; +import styles from './OrganizePreviewRow.css'; + +interface OrganizePreviewRowProps { + id: number; + existingPath: string; + newPath: string; + isSelected?: boolean; + onSelectedChange: (props: SelectStateInputProps) => void; +} + +function OrganizePreviewRow({ + id, + existingPath, + newPath, + isSelected, + onSelectedChange, +}: OrganizePreviewRowProps) { + const handleSelectedChange = useCallback( + ({ value, shiftKey }: CheckInputChanged) => { + onSelectedChange({ id, value, shiftKey }); + }, + [id, onSelectedChange] + ); + + useEffect(() => { + onSelectedChange({ id, value: true, shiftKey: false }); + }, [id, onSelectedChange]); + + return ( +
+ + +
+
+ + + {existingPath} +
+ +
+ + + {newPath} +
+
+
+ ); +} + +export default OrganizePreviewRow; diff --git a/frontend/src/typings/inputs.ts b/frontend/src/typings/inputs.ts index eb42e316d6..e218abbbd9 100644 --- a/frontend/src/typings/inputs.ts +++ b/frontend/src/typings/inputs.ts @@ -5,4 +5,6 @@ export type InputChanged = { export type InputOnChange = (change: InputChanged) => void; -export type CheckInputChanged = InputChanged; +export interface CheckInputChanged extends InputChanged { + shiftKey: boolean; +} From 779292490ae582099c4e1b845e6281ec33eea449 Mon Sep 17 00:00:00 2001 From: Mark McDowall Date: Sun, 22 Dec 2024 19:04:04 -0800 Subject: [PATCH 242/579] Convert SelectMovieRow to TypeScript (cherry picked from commit 32ce09648cb9eb13c46b060f2665f3ce837261f2) --- .../Movie/SelectMovieModalContent.tsx | 6 +- .../InteractiveImport/Movie/SelectMovieRow.js | 55 ------------------- .../Movie/SelectMovieRow.tsx | 33 +++++++++++ 3 files changed, 35 insertions(+), 59 deletions(-) delete mode 100644 frontend/src/InteractiveImport/Movie/SelectMovieRow.js create mode 100644 frontend/src/InteractiveImport/Movie/SelectMovieRow.tsx diff --git a/frontend/src/InteractiveImport/Movie/SelectMovieModalContent.tsx b/frontend/src/InteractiveImport/Movie/SelectMovieModalContent.tsx index 2248eb183e..2fb0ae6c98 100644 --- a/frontend/src/InteractiveImport/Movie/SelectMovieModalContent.tsx +++ b/frontend/src/InteractiveImport/Movie/SelectMovieModalContent.tsx @@ -65,7 +65,7 @@ interface RowItemData { } function Row({ index, style, data }: ListChildComponentProps) { - const { items, columns, onMovieSelect } = data; + const { items, onMovieSelect } = data; const movie = index >= items.length ? null : items[index]; const handlePress = useCallback(() => { @@ -88,13 +88,11 @@ function Row({ index, style, data }: ListChildComponentProps) { onPress={handlePress} > ); diff --git a/frontend/src/InteractiveImport/Movie/SelectMovieRow.js b/frontend/src/InteractiveImport/Movie/SelectMovieRow.js deleted file mode 100644 index 5fdcc32f2a..0000000000 --- a/frontend/src/InteractiveImport/Movie/SelectMovieRow.js +++ /dev/null @@ -1,55 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Label from 'Components/Label'; -import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; -import styles from './SelectMovieRow.css'; - -class SelectMovieRow extends Component { - - // - // Listeners - - onPress = () => { - this.props.onMovieSelect(this.props.id); - }; - - // - // Render - - render() { - return ( - <> - - {this.props.title} - - - - {this.props.year} - - - - { - this.props.imdbId ? - : - null - } - - - - - - - ); - } -} - -SelectMovieRow.propTypes = { - id: PropTypes.number.isRequired, - title: PropTypes.string.isRequired, - tmdbId: PropTypes.number.isRequired, - imdbId: PropTypes.string, - year: PropTypes.number.isRequired, - onMovieSelect: PropTypes.func.isRequired -}; - -export default SelectMovieRow; diff --git a/frontend/src/InteractiveImport/Movie/SelectMovieRow.tsx b/frontend/src/InteractiveImport/Movie/SelectMovieRow.tsx new file mode 100644 index 0000000000..643262810b --- /dev/null +++ b/frontend/src/InteractiveImport/Movie/SelectMovieRow.tsx @@ -0,0 +1,33 @@ +import React from 'react'; +import Label from 'Components/Label'; +import VirtualTableRowCell from 'Components/Table/Cells/VirtualTableRowCell'; +import styles from './SelectMovieRow.css'; + +interface SelectMovieRowProps { + title: string; + tmdbId: number; + imdbId?: string; + year: number; +} + +function SelectMovieRow({ title, year, tmdbId, imdbId }: SelectMovieRowProps) { + return ( + <> + + {title} + + + {year} + + + {imdbId ? : null} + + + + + + + ); +} + +export default SelectMovieRow; From 6a7ed22b44871dabc4a8ee3c334326666d415b80 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 8 Mar 2025 16:04:08 +0200 Subject: [PATCH 243/579] Convert Movie History to TypeScript Closes #10755 Co-authored-by: Mark McDowall --- .../History/Details/HistoryDetailsModal.tsx | 2 +- frontend/src/App/State/AppState.ts | 3 +- frontend/src/App/State/HistoryAppState.ts | 2 + .../src/App/State/MovieHistoryAppState.ts | 6 - .../src/Movie/History/MovieHistoryModal.js | 33 ---- .../src/Movie/History/MovieHistoryModal.tsx | 28 +++ .../Movie/History/MovieHistoryModalContent.js | 141 -------------- .../History/MovieHistoryModalContent.tsx | 148 ++++++++++++++ .../MovieHistoryModalContentConnector.js | 76 -------- frontend/src/Movie/History/MovieHistoryRow.js | 181 ------------------ .../src/Movie/History/MovieHistoryRow.tsx | 134 +++++++++++++ .../Movie/History/MovieHistoryRowConnector.js | 27 --- src/NzbDrone.Core/Localization/Core/ar.json | 2 +- src/NzbDrone.Core/Localization/Core/bg.json | 2 +- src/NzbDrone.Core/Localization/Core/ca.json | 2 +- src/NzbDrone.Core/Localization/Core/cs.json | 2 +- src/NzbDrone.Core/Localization/Core/da.json | 2 +- src/NzbDrone.Core/Localization/Core/de.json | 2 +- src/NzbDrone.Core/Localization/Core/el.json | 2 +- src/NzbDrone.Core/Localization/Core/en.json | 2 +- src/NzbDrone.Core/Localization/Core/es.json | 2 +- src/NzbDrone.Core/Localization/Core/fi.json | 2 +- src/NzbDrone.Core/Localization/Core/fr.json | 2 +- src/NzbDrone.Core/Localization/Core/he.json | 2 +- src/NzbDrone.Core/Localization/Core/hi.json | 2 +- src/NzbDrone.Core/Localization/Core/hu.json | 2 +- src/NzbDrone.Core/Localization/Core/is.json | 2 +- src/NzbDrone.Core/Localization/Core/it.json | 2 +- src/NzbDrone.Core/Localization/Core/ja.json | 2 +- src/NzbDrone.Core/Localization/Core/ko.json | 2 +- src/NzbDrone.Core/Localization/Core/nl.json | 2 +- src/NzbDrone.Core/Localization/Core/pl.json | 2 +- src/NzbDrone.Core/Localization/Core/pt.json | 2 +- .../Localization/Core/pt_BR.json | 2 +- src/NzbDrone.Core/Localization/Core/ro.json | 2 +- src/NzbDrone.Core/Localization/Core/ru.json | 2 +- src/NzbDrone.Core/Localization/Core/sv.json | 2 +- src/NzbDrone.Core/Localization/Core/th.json | 2 +- src/NzbDrone.Core/Localization/Core/tr.json | 2 +- src/NzbDrone.Core/Localization/Core/uk.json | 2 +- src/NzbDrone.Core/Localization/Core/vi.json | 2 +- .../Localization/Core/zh_CN.json | 2 +- 42 files changed, 344 insertions(+), 497 deletions(-) delete mode 100644 frontend/src/App/State/MovieHistoryAppState.ts delete mode 100644 frontend/src/Movie/History/MovieHistoryModal.js create mode 100644 frontend/src/Movie/History/MovieHistoryModal.tsx delete mode 100644 frontend/src/Movie/History/MovieHistoryModalContent.js create mode 100644 frontend/src/Movie/History/MovieHistoryModalContent.tsx delete mode 100644 frontend/src/Movie/History/MovieHistoryModalContentConnector.js delete mode 100644 frontend/src/Movie/History/MovieHistoryRow.js create mode 100644 frontend/src/Movie/History/MovieHistoryRow.tsx delete mode 100644 frontend/src/Movie/History/MovieHistoryRowConnector.js diff --git a/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx index c54f2654f1..69e4405ea0 100644 --- a/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx +++ b/frontend/src/Activity/History/Details/HistoryDetailsModal.tsx @@ -37,7 +37,7 @@ interface HistoryDetailsModalProps { sourceTitle: string; data: HistoryData; downloadId?: string; - isMarkingAsFailed: boolean; + isMarkingAsFailed?: boolean; onMarkAsFailedPress: () => void; onModalClose: () => void; } diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index 3203fae548..fdee6369bd 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -1,13 +1,12 @@ import BlocklistAppState from './BlocklistAppState'; import CalendarAppState from './CalendarAppState'; import CommandAppState from './CommandAppState'; -import HistoryAppState from './HistoryAppState'; +import HistoryAppState, { MovieHistoryAppState } from './HistoryAppState'; import InteractiveImportAppState from './InteractiveImportAppState'; import MovieBlocklistAppState from './MovieBlocklistAppState'; import MovieCollectionAppState from './MovieCollectionAppState'; import MovieCreditAppState from './MovieCreditAppState'; import MovieFilesAppState from './MovieFilesAppState'; -import MovieHistoryAppState from './MovieHistoryAppState'; import MoviesAppState, { MovieIndexAppState } from './MoviesAppState'; import OrganizePreviewAppState from './OrganizePreviewAppState'; import ParseAppState from './ParseAppState'; diff --git a/frontend/src/App/State/HistoryAppState.ts b/frontend/src/App/State/HistoryAppState.ts index 632b821793..fd2bf01062 100644 --- a/frontend/src/App/State/HistoryAppState.ts +++ b/frontend/src/App/State/HistoryAppState.ts @@ -5,6 +5,8 @@ import AppSectionState, { } from 'App/State/AppSectionState'; import History from 'typings/History'; +export type MovieHistoryAppState = AppSectionState; + interface HistoryAppState extends AppSectionState, AppSectionFilterState, diff --git a/frontend/src/App/State/MovieHistoryAppState.ts b/frontend/src/App/State/MovieHistoryAppState.ts deleted file mode 100644 index 44a024cdf4..0000000000 --- a/frontend/src/App/State/MovieHistoryAppState.ts +++ /dev/null @@ -1,6 +0,0 @@ -import AppSectionState from 'App/State/AppSectionState'; -import History from 'typings/History'; - -type MovieHistoryAppState = AppSectionState; - -export default MovieHistoryAppState; diff --git a/frontend/src/Movie/History/MovieHistoryModal.js b/frontend/src/Movie/History/MovieHistoryModal.js deleted file mode 100644 index c64d82ebe1..0000000000 --- a/frontend/src/Movie/History/MovieHistoryModal.js +++ /dev/null @@ -1,33 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import { sizes } from 'Helpers/Props'; -import MovieHistoryModalContentConnector from './MovieHistoryModalContentConnector'; - -function MovieHistoryModal(props) { - const { - isOpen, - onModalClose, - ...otherProps - } = props; - - return ( - - - - ); -} - -MovieHistoryModal.propTypes = { - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default MovieHistoryModal; diff --git a/frontend/src/Movie/History/MovieHistoryModal.tsx b/frontend/src/Movie/History/MovieHistoryModal.tsx new file mode 100644 index 0000000000..e6f6a07d6a --- /dev/null +++ b/frontend/src/Movie/History/MovieHistoryModal.tsx @@ -0,0 +1,28 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import { sizes } from 'Helpers/Props'; +import MovieHistoryModalContent, { + MovieHistoryModalContentProps, +} from 'Movie/History/MovieHistoryModalContent'; + +interface MovieHistoryModalProps extends MovieHistoryModalContentProps { + isOpen: boolean; +} + +function MovieHistoryModal({ + isOpen, + onModalClose, + ...otherProps +}: MovieHistoryModalProps) { + return ( + + + + ); +} + +export default MovieHistoryModal; diff --git a/frontend/src/Movie/History/MovieHistoryModalContent.js b/frontend/src/Movie/History/MovieHistoryModalContent.js deleted file mode 100644 index 01bec57291..0000000000 --- a/frontend/src/Movie/History/MovieHistoryModalContent.js +++ /dev/null @@ -1,141 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import Alert from 'Components/Alert'; -import Icon from 'Components/Icon'; -import Button from 'Components/Link/Button'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import Table from 'Components/Table/Table'; -import TableBody from 'Components/Table/TableBody'; -import { icons, kinds } from 'Helpers/Props'; -import translate from 'Utilities/String/translate'; -import MovieHistoryRowConnector from './MovieHistoryRowConnector'; - -const columns = [ - { - name: 'eventType', - isVisible: true - }, - { - name: 'sourceTitle', - label: () => translate('SourceTitle'), - isVisible: true - }, - { - name: 'languages', - label: () => translate('Languages'), - isVisible: true - }, - { - name: 'quality', - label: () => translate('Quality'), - isVisible: true - }, - { - name: 'customFormats', - label: () => translate('CustomFormats'), - isSortable: false, - isVisible: true - }, - { - name: 'customFormatScore', - label: React.createElement(Icon, { - name: icons.SCORE, - title: () => translate('CustomFormatScore') - }), - isSortable: true, - isVisible: true - }, - { - name: 'date', - label: () => translate('Date'), - isVisible: true - }, - { - name: 'actions', - isVisible: true - } -]; - -class MovieHistoryModalContent extends Component { - - // - // Render - - render() { - const { - isFetching, - isPopulated, - error, - items, - onMarkAsFailedPress, - onModalClose - } = this.props; - - const hasItems = !!items.length; - - return ( - - - {translate('History')} - - - - { - isFetching && - - } - - { - !isFetching && !!error && - {translate('HistoryLoadError')} - } - - { - isPopulated && !hasItems && !error && -
{translate('NoHistory')}
- } - - { - isPopulated && hasItems && !error && - - - { - items.map((item) => { - return ( - - ); - }) - } - -
- } -
- - - - -
- ); - } -} - -MovieHistoryModalContent.propTypes = { - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - items: PropTypes.arrayOf(PropTypes.object).isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -export default MovieHistoryModalContent; diff --git a/frontend/src/Movie/History/MovieHistoryModalContent.tsx b/frontend/src/Movie/History/MovieHistoryModalContent.tsx new file mode 100644 index 0000000000..fd428196ef --- /dev/null +++ b/frontend/src/Movie/History/MovieHistoryModalContent.tsx @@ -0,0 +1,148 @@ +import React, { useCallback, useEffect } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import Alert from 'Components/Alert'; +import Icon from 'Components/Icon'; +import Button from 'Components/Link/Button'; +import LoadingIndicator from 'Components/Loading/LoadingIndicator'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import Column from 'Components/Table/Column'; +import Table from 'Components/Table/Table'; +import TableBody from 'Components/Table/TableBody'; +import { icons, kinds } from 'Helpers/Props'; +import { + clearMovieHistory, + fetchMovieHistory, + movieHistoryMarkAsFailed, +} from 'Store/Actions/movieHistoryActions'; +import translate from 'Utilities/String/translate'; +import MovieHistoryRow from './MovieHistoryRow'; + +const columns: Column[] = [ + { + name: 'eventType', + label: '', + isVisible: true, + }, + { + name: 'sourceTitle', + label: () => translate('SourceTitle'), + isVisible: true, + }, + { + name: 'languages', + label: () => translate('Languages'), + isVisible: true, + }, + { + name: 'quality', + label: () => translate('Quality'), + isVisible: true, + }, + { + name: 'customFormats', + label: () => translate('CustomFormats'), + isSortable: false, + isVisible: true, + }, + { + name: 'customFormatScore', + label: React.createElement(Icon, { + name: icons.SCORE, + title: () => translate('CustomFormatScore'), + }), + isSortable: true, + isVisible: true, + }, + { + name: 'date', + label: () => translate('Date'), + isVisible: true, + }, + { + name: 'actions', + label: '', + isVisible: true, + }, +]; + +export interface MovieHistoryModalContentProps { + movieId: number; + onModalClose: () => void; +} + +function MovieHistoryModalContent({ + movieId, + onModalClose, +}: MovieHistoryModalContentProps) { + const dispatch = useDispatch(); + + const { isFetching, isPopulated, error, items } = useSelector( + (state: AppState) => state.movieHistory + ); + + const hasItems = !!items.length; + + const handleMarkAsFailedPress = useCallback( + (historyId: number) => { + dispatch( + movieHistoryMarkAsFailed({ + historyId, + movieId, + }) + ); + }, + [movieId, dispatch] + ); + + useEffect(() => { + dispatch(fetchMovieHistory({ movieId })); + + return () => { + dispatch(clearMovieHistory()); + }; + }, [movieId, dispatch]); + + return ( + + {translate('History')} + + + {isFetching && !isPopulated ? : null} + + {!isFetching && !!error ? ( + {translate('HistoryLoadError')} + ) : null} + + {isPopulated && !hasItems && !error ? ( +
{translate('NoHistory')}
+ ) : null} + + {isPopulated && hasItems && !error && ( + + + {items.map((item) => { + return ( + + ); + })} + +
+ )} +
+ + + + +
+ ); +} + +export default MovieHistoryModalContent; diff --git a/frontend/src/Movie/History/MovieHistoryModalContentConnector.js b/frontend/src/Movie/History/MovieHistoryModalContentConnector.js deleted file mode 100644 index ee2dbe20ec..0000000000 --- a/frontend/src/Movie/History/MovieHistoryModalContentConnector.js +++ /dev/null @@ -1,76 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { clearMovieHistory, fetchMovieHistory, movieHistoryMarkAsFailed } from 'Store/Actions/movieHistoryActions'; -import MovieHistoryModalContent from './MovieHistoryModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.movieHistory, - (movieHistory) => { - return movieHistory; - } - ); -} - -const mapDispatchToProps = { - fetchMovieHistory, - clearMovieHistory, - movieHistoryMarkAsFailed -}; - -class MovieHistoryModalContentConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - const { - movieId - } = this.props; - - this.props.fetchMovieHistory({ - movieId - }); - } - - componentWillUnmount() { - this.props.clearMovieHistory(); - } - - // - // Listeners - - onMarkAsFailedPress = (historyId) => { - const { - movieId - } = this.props; - - this.props.movieHistoryMarkAsFailed({ - historyId, - movieId - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -MovieHistoryModalContentConnector.propTypes = { - movieId: PropTypes.number.isRequired, - fetchMovieHistory: PropTypes.func.isRequired, - clearMovieHistory: PropTypes.func.isRequired, - movieHistoryMarkAsFailed: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MovieHistoryModalContentConnector); diff --git a/frontend/src/Movie/History/MovieHistoryRow.js b/frontend/src/Movie/History/MovieHistoryRow.js deleted file mode 100644 index b62a8d6a6a..0000000000 --- a/frontend/src/Movie/History/MovieHistoryRow.js +++ /dev/null @@ -1,181 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import HistoryDetailsModal from 'Activity/History/Details/HistoryDetailsModal'; -import HistoryEventTypeCell from 'Activity/History/HistoryEventTypeCell'; -import IconButton from 'Components/Link/IconButton'; -import ConfirmModal from 'Components/Modal/ConfirmModal'; -import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; -import TableRowCell from 'Components/Table/Cells/TableRowCell'; -import TableRow from 'Components/Table/TableRow'; -import { icons, kinds } from 'Helpers/Props'; -import MovieFormats from 'Movie/MovieFormats'; -import MovieLanguages from 'Movie/MovieLanguages'; -import MovieQuality from 'Movie/MovieQuality'; -import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; -import translate from 'Utilities/String/translate'; -import styles from './MovieHistoryRow.css'; - -class MovieHistoryRow extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isMarkAsFailedModalOpen: false, - isDetailsModalOpen: false - }; - } - - // - // Listeners - - onMarkAsFailedPress = () => { - this.setState({ isMarkAsFailedModalOpen: true }); - }; - - onConfirmMarkAsFailed = () => { - this.props.onMarkAsFailedPress(this.props.id); - this.setState({ isMarkAsFailedModalOpen: false }); - }; - - onMarkAsFailedModalClose = () => { - this.setState({ isMarkAsFailedModalOpen: false }); - }; - - onDetailsPress = () => { - this.setState({ isDetailsModalOpen: true }); - }; - - onDetailsModalClose = () => { - this.setState({ isDetailsModalOpen: false }); - }; - - // - // Render - - render() { - const { - eventType, - sourceTitle, - quality, - customFormats, - customFormatScore, - languages, - qualityCutoffNotMet, - date, - data, - downloadId, - isMarkingAsFailed, - shortDateFormat, - timeFormat - } = this.props; - - const { - isMarkAsFailedModalOpen - } = this.state; - - return ( - - - - - {sourceTitle} - - - - - - - - - - - - - - - - {formatCustomFormatScore(customFormatScore, customFormats.length)} - - - - - - - - { - eventType === 'grabbed' && - - } - - - - - - - ); - } -} - -MovieHistoryRow.propTypes = { - id: PropTypes.number.isRequired, - eventType: PropTypes.string.isRequired, - sourceTitle: PropTypes.string.isRequired, - languages: PropTypes.arrayOf(PropTypes.object).isRequired, - quality: PropTypes.object.isRequired, - customFormats: PropTypes.arrayOf(PropTypes.object), - customFormatScore: PropTypes.number.isRequired, - qualityCutoffNotMet: PropTypes.bool.isRequired, - date: PropTypes.string.isRequired, - data: PropTypes.object.isRequired, - downloadId: PropTypes.string, - isMarkingAsFailed: PropTypes.bool, - movie: PropTypes.object.isRequired, - shortDateFormat: PropTypes.string.isRequired, - timeFormat: PropTypes.string.isRequired, - onMarkAsFailedPress: PropTypes.func.isRequired -}; - -export default MovieHistoryRow; diff --git a/frontend/src/Movie/History/MovieHistoryRow.tsx b/frontend/src/Movie/History/MovieHistoryRow.tsx new file mode 100644 index 0000000000..eff5e78879 --- /dev/null +++ b/frontend/src/Movie/History/MovieHistoryRow.tsx @@ -0,0 +1,134 @@ +import React, { useCallback, useState } from 'react'; +import HistoryDetailsModal from 'Activity/History/Details/HistoryDetailsModal'; +import HistoryEventTypeCell from 'Activity/History/HistoryEventTypeCell'; +import IconButton from 'Components/Link/IconButton'; +import ConfirmModal from 'Components/Modal/ConfirmModal'; +import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell'; +import TableRowCell from 'Components/Table/Cells/TableRowCell'; +import TableRow from 'Components/Table/TableRow'; +import { icons, kinds } from 'Helpers/Props'; +import Language from 'Language/Language'; +import MovieFormats from 'Movie/MovieFormats'; +import MovieLanguages from 'Movie/MovieLanguages'; +import MovieQuality from 'Movie/MovieQuality'; +import { QualityModel } from 'Quality/Quality'; +import CustomFormat from 'typings/CustomFormat'; +import { HistoryData, HistoryEventType } from 'typings/History'; +import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore'; +import translate from 'Utilities/String/translate'; +import styles from './MovieHistoryRow.css'; + +interface MovieHistoryRowProps { + id: number; + eventType: HistoryEventType; + sourceTitle: string; + languages?: Language[]; + quality: QualityModel; + qualityCutoffNotMet: boolean; + customFormats?: CustomFormat[]; + customFormatScore: number; + date: string; + data: HistoryData; + downloadId?: string; + onMarkAsFailedPress: (historyId: number) => void; +} + +function MovieHistoryRow({ + id, + eventType, + sourceTitle, + languages = [], + quality, + qualityCutoffNotMet, + customFormats = [], + customFormatScore, + date, + data, + downloadId, + onMarkAsFailedPress, +}: MovieHistoryRowProps) { + const [isDetailsModalOpen, setIsDetailsModalOpen] = useState(false); + const [isMarkAsFailedModalOpen, setIsMarkAsFailedModalOpen] = useState(false); + + const handleDetailsPress = useCallback(() => { + setIsDetailsModalOpen(true); + }, [setIsDetailsModalOpen]); + + const handleDetailsModalClose = useCallback(() => { + setIsDetailsModalOpen(false); + }, [setIsDetailsModalOpen]); + + const handleMarkAsFailedPress = useCallback(() => { + setIsMarkAsFailedModalOpen(true); + }, []); + + const handleConfirmMarkAsFailed = useCallback(() => { + onMarkAsFailedPress(id); + setIsMarkAsFailedModalOpen(false); + }, [id, onMarkAsFailedPress]); + + const handleMarkAsFailedModalClose = useCallback(() => { + setIsMarkAsFailedModalOpen(false); + }, []); + + return ( + + + + {sourceTitle} + + + + + + + + + + + + + + + {formatCustomFormatScore(customFormatScore, customFormats.length)} + + + + + + + + {eventType === 'grabbed' ? ( + + ) : null} + + + + + + + ); +} + +export default MovieHistoryRow; diff --git a/frontend/src/Movie/History/MovieHistoryRowConnector.js b/frontend/src/Movie/History/MovieHistoryRowConnector.js deleted file mode 100644 index c8f8bb501d..0000000000 --- a/frontend/src/Movie/History/MovieHistoryRowConnector.js +++ /dev/null @@ -1,27 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { fetchHistory, markAsFailed } from 'Store/Actions/historyActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; -import MovieHistoryRow from './MovieHistoryRow'; - -function createMapStateToProps() { - return createSelector( - createMovieSelector(), - createUISettingsSelector(), - (movie, uiSettings) => { - return { - movie, - shortDateFormat: uiSettings.shortDateFormat, - timeFormat: uiSettings.timeFormat - }; - } - ); -} - -const mapDispatchToProps = { - fetchHistory, - markAsFailed -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MovieHistoryRow); diff --git a/src/NzbDrone.Core/Localization/Core/ar.json b/src/NzbDrone.Core/Localization/Core/ar.json index 2e23d80f95..1e9ac3670a 100644 --- a/src/NzbDrone.Core/Localization/Core/ar.json +++ b/src/NzbDrone.Core/Localization/Core/ar.json @@ -879,7 +879,7 @@ "MaximumLimits": "الحدود القصوى", "Max": "ماكس", "MassMovieSearch": "البحث الشامل عن الأفلام", - "MarkAsFailedMessageText": "هل أنت متأكد أنك تريد وضع علامة \"{0}\" على أنه فشل؟", + "MarkAsFailedConfirmation": "هل أنت متأكد أنك تريد وضع علامة \"{0}\" على أنه فشل؟", "MarkAsFailed": "وضع علامة فشل", "MappedNetworkDrivesWindowsService": "لا تتوفر محركات أقراص الشبكة المعينة عند التشغيل كخدمة Windows. يرجى الاطلاع على التعليمات لمزيد من المعلومات", "ManualImportSelectQuality": " استيراد يدوي - حدد الجودة", diff --git a/src/NzbDrone.Core/Localization/Core/bg.json b/src/NzbDrone.Core/Localization/Core/bg.json index 159bcdace9..1f7f485ffb 100644 --- a/src/NzbDrone.Core/Localization/Core/bg.json +++ b/src/NzbDrone.Core/Localization/Core/bg.json @@ -329,7 +329,7 @@ "ManualImportSelectMovie": "Ръчно импортиране - Изберете филм", "ManualImportSelectQuality": " Ръчен импорт - Изберете качество", "MappedNetworkDrivesWindowsService": "Картографираните мрежови устройства не са налични, когато се изпълняват като услуга на Windows. Моля, вижте често задаваните въпроси за повече информация", - "MarkAsFailedMessageText": "Наистина ли искате да маркирате „{0}“ като неуспешен?", + "MarkAsFailedConfirmation": "Наистина ли искате да маркирате „{0}“ като неуспешен?", "MassMovieSearch": "Масово търсене на филми", "MaximumLimits": "Максимални граници", "MaximumSize": "Максимален размер", diff --git a/src/NzbDrone.Core/Localization/Core/ca.json b/src/NzbDrone.Core/Localization/Core/ca.json index 47981f5af9..f9feac3938 100644 --- a/src/NzbDrone.Core/Localization/Core/ca.json +++ b/src/NzbDrone.Core/Localization/Core/ca.json @@ -324,7 +324,7 @@ "EditMovie": "Edita pel·lícula", "EnableColorImpairedModeHelpText": "Estil alterat per a permetre als usuaris amb problemes de color distingir millor la informació codificada per colors", "Folder": "Carpeta", - "MarkAsFailedMessageText": "Esteu segur que voleu marcar '{0}' com a fallat?", + "MarkAsFailedConfirmation": "Esteu segur que voleu marcar '{0}' com a fallat?", "Negated": "Negat", "Profiles": "Perfils", "Real": "Real", diff --git a/src/NzbDrone.Core/Localization/Core/cs.json b/src/NzbDrone.Core/Localization/Core/cs.json index 75cc01ec5f..9241983c80 100644 --- a/src/NzbDrone.Core/Localization/Core/cs.json +++ b/src/NzbDrone.Core/Localization/Core/cs.json @@ -664,7 +664,7 @@ "ManualImportSelectMovie": "Ruční import - vyberte Film", "ManualImportSelectQuality": " Ruční import - vyberte kvalitu", "MappedNetworkDrivesWindowsService": "Mapované síťové jednotky nejsou k dispozici, když běží jako služba Windows. Další informace najdete v [FAQ]({url}).", - "MarkAsFailedMessageText": "Opravdu chcete označit „{0}“ jako neúspěšné?", + "MarkAsFailedConfirmation": "Opravdu chcete označit „{0}“ jako neúspěšné?", "MassMovieSearch": "Hromadné vyhledávání filmů", "MaximumLimits": "Maximální limity", "MaximumSize": "Maximální velikost", diff --git a/src/NzbDrone.Core/Localization/Core/da.json b/src/NzbDrone.Core/Localization/Core/da.json index 920b34036a..743c2e790b 100644 --- a/src/NzbDrone.Core/Localization/Core/da.json +++ b/src/NzbDrone.Core/Localization/Core/da.json @@ -627,7 +627,7 @@ "ManualImportSelectLanguage": "Manuel import - Vælg sprog", "ManualImportSelectMovie": "Manuel import - Vælg film", "ManualImportSelectQuality": " Manuel import - Vælg kvalitet", - "MarkAsFailedMessageText": "Er du sikker på, at du vil markere '{0}' som mislykket?", + "MarkAsFailedConfirmation": "Er du sikker på, at du vil markere '{0}' som mislykket?", "MaximumLimits": "Maksimumgrænser", "MaximumSize": "Maksimal størrelse", "MegabytesPerMinute": "Megabyte pr. Minut", diff --git a/src/NzbDrone.Core/Localization/Core/de.json b/src/NzbDrone.Core/Localization/Core/de.json index 6ea84b59e1..f2b96abf64 100644 --- a/src/NzbDrone.Core/Localization/Core/de.json +++ b/src/NzbDrone.Core/Localization/Core/de.json @@ -601,7 +601,7 @@ "MovieIsMonitored": "Film wird beobachtet", "MovieExcludedFromAutomaticAdd": "Film vom automatischen hinzufügen ausgeschlossen", "MovieAlreadyExcluded": "Film ist schon ausgeschlossen", - "MarkAsFailedMessageText": "'{0}' wirklich als fehlgeschlagen markieren?", + "MarkAsFailedConfirmation": "'{0}' wirklich als fehlgeschlagen markieren?", "Manual": "Manuell", "LogLevelTraceHelpTextWarning": "Die Trace-Protokollierung sollte nur vorübergehend aktiviert werden", "LastDuration": "Letzte Dauer", diff --git a/src/NzbDrone.Core/Localization/Core/el.json b/src/NzbDrone.Core/Localization/Core/el.json index 60010d3eb8..d901c72406 100644 --- a/src/NzbDrone.Core/Localization/Core/el.json +++ b/src/NzbDrone.Core/Localization/Core/el.json @@ -618,7 +618,7 @@ "ManualImportSelectLanguage": "Μη αυτόματη εισαγωγή - Επιλέξτε γλώσσα", "ManualImportSelectQuality": " Μη αυτόματη εισαγωγή - Επιλέξτε Ποιότητα", "MappedNetworkDrivesWindowsService": "Οι αντιστοιχισμένες μονάδες δίσκου δικτύου δεν είναι διαθέσιμες κατά την εκτέλεση ως υπηρεσία Windows. Ανατρέξτε στις Συχνές Ερωτήσεις για περισσότερες πληροφορίες", - "MarkAsFailedMessageText": "Είστε βέβαιοι ότι θέλετε να επισημάνετε \"{0}\" ως αποτυχημένο;", + "MarkAsFailedConfirmation": "Είστε βέβαιοι ότι θέλετε να επισημάνετε \"{0}\" ως αποτυχημένο;", "MassMovieSearch": "Μαζική αναζήτηση ταινιών", "MaximumLimits": "Μέγιστα όρια", "MaximumSize": "Μέγιστο μέγεθος", diff --git a/src/NzbDrone.Core/Localization/Core/en.json b/src/NzbDrone.Core/Localization/Core/en.json index f494268a25..2349f472f7 100644 --- a/src/NzbDrone.Core/Localization/Core/en.json +++ b/src/NzbDrone.Core/Localization/Core/en.json @@ -955,7 +955,7 @@ "ManualImportSetReleaseGroup": "Manual Import - Set Release Group", "MappedNetworkDrivesWindowsService": "Mapped network drives are not available when running as a Windows Service, see the [FAQ]({url}) for more information.", "MarkAsFailed": "Mark as Failed", - "MarkAsFailedMessageText": "Are you sure you want to mark '{0}' as failed?", + "MarkAsFailedConfirmation": "Are you sure you want to mark '{sourceTitle}' as failed?", "MassMovieSearch": "Mass Movie Search", "MassSearchCancelWarning": "This cannot be cancelled once started without restarting {appName} or disabling all of your indexers.", "MatchedToMovie": "Matched to Movie", diff --git a/src/NzbDrone.Core/Localization/Core/es.json b/src/NzbDrone.Core/Localization/Core/es.json index 1212f769b4..a425eaf5b0 100644 --- a/src/NzbDrone.Core/Localization/Core/es.json +++ b/src/NzbDrone.Core/Localization/Core/es.json @@ -602,7 +602,7 @@ "MovieIsMonitored": "La película está monitorizada", "MovieExcludedFromAutomaticAdd": "Película Excluida de Adición Automática", "MovieAlreadyExcluded": "Película ya Excluida", - "MarkAsFailedMessageText": "¿Estás seguro que quieres marcar '{0}' como fallida?", + "MarkAsFailedConfirmation": "¿Estás seguro que quieres marcar '{0}' como fallida?", "Manual": "Manual", "LogLevelTraceHelpTextWarning": "El registro de seguimiento sólo debe activarse temporalmente", "LastDuration": "Última Duración", diff --git a/src/NzbDrone.Core/Localization/Core/fi.json b/src/NzbDrone.Core/Localization/Core/fi.json index bd8a460a12..10d09dc9fa 100644 --- a/src/NzbDrone.Core/Localization/Core/fi.json +++ b/src/NzbDrone.Core/Localization/Core/fi.json @@ -628,7 +628,7 @@ "Lowercase": "Pienet kirjaimet", "ManualImportSelectLanguage": "Manuaalinen tuonti – Valitse kieli", "ManualImportSelectQuality": " Manuaalinen tuonti – Valitse laatu", - "MarkAsFailedMessageText": "Haluatko varmasti merkitä kohteen {0} epäonnistuneeksi?", + "MarkAsFailedConfirmation": "Haluatko varmasti merkitä kohteen {0} epäonnistuneeksi?", "MassMovieSearch": "Elokuvien massahaku", "MaximumLimits": "Enimmäisrajoitukset", "MaximumSize": "Enimmäiskoko", diff --git a/src/NzbDrone.Core/Localization/Core/fr.json b/src/NzbDrone.Core/Localization/Core/fr.json index 40c1a7032d..c14a7a4343 100644 --- a/src/NzbDrone.Core/Localization/Core/fr.json +++ b/src/NzbDrone.Core/Localization/Core/fr.json @@ -653,7 +653,7 @@ "RemovingTag": "Supprimer la balise", "RadarrTags": "Étiquettes {appName}", "Paused": "En pause", - "MarkAsFailedMessageText": "Voulez-vous vraiment marquer '{0}' comme échoué ?", + "MarkAsFailedConfirmation": "Voulez-vous vraiment marquer '{0}' comme échoué ?", "ExistingTag": "Balise existante", "DownloadPropersAndRepacksHelpTextWarning": "Utilisez des formats personnalisés pour les mises à niveau automatiques vers Propers/Repacks", "DownloadPropersAndRepacksHelpTextCustomFormat": "Utiliser 'Ne pas préférer' pour trier par score de mot préféré par rapport aux propres/repacks", diff --git a/src/NzbDrone.Core/Localization/Core/he.json b/src/NzbDrone.Core/Localization/Core/he.json index ef95361f48..3f71fceeb1 100644 --- a/src/NzbDrone.Core/Localization/Core/he.json +++ b/src/NzbDrone.Core/Localization/Core/he.json @@ -628,7 +628,7 @@ "ManualImportSelectMovie": "ייבוא ידני - בחר סרט", "ManualImportSelectQuality": " יבוא ידני - בחר איכות", "MappedNetworkDrivesWindowsService": "כונני רשת ממופים אינם זמינים כאשר הם פועלים כשירות Windows. אנא עיין בשאלות הנפוצות למידע נוסף", - "MarkAsFailedMessageText": "האם אתה בטוח שברצונך לסמן את '{0}' ככושל?", + "MarkAsFailedConfirmation": "האם אתה בטוח שברצונך לסמן את '{0}' ככושל?", "MassMovieSearch": "חיפוש סרטים המוני", "MaximumLimits": "מגבלות מקסימליות", "MaximumSize": "גודל מקסימלי", diff --git a/src/NzbDrone.Core/Localization/Core/hi.json b/src/NzbDrone.Core/Localization/Core/hi.json index 0fd269074a..d49464b84b 100644 --- a/src/NzbDrone.Core/Localization/Core/hi.json +++ b/src/NzbDrone.Core/Localization/Core/hi.json @@ -747,7 +747,7 @@ "LookingForReleaseProfiles2": "बजाय।", "Lowercase": "लोअर केस", "ManualImportSelectQuality": " मैनुअल आयात - गुणवत्ता का चयन करें", - "MarkAsFailedMessageText": "क्या आप वाकई '{0}' को चिह्नित करना चाहते हैं?", + "MarkAsFailedConfirmation": "क्या आप वाकई '{0}' को चिह्नित करना चाहते हैं?", "MassMovieSearch": "मास मूवी सर्च", "MaximumLimits": "अधिकतम सीमा", "Message": "संदेश", diff --git a/src/NzbDrone.Core/Localization/Core/hu.json b/src/NzbDrone.Core/Localization/Core/hu.json index 4515108fe0..04c0db6216 100644 --- a/src/NzbDrone.Core/Localization/Core/hu.json +++ b/src/NzbDrone.Core/Localization/Core/hu.json @@ -544,7 +544,7 @@ "MaximumSize": "Maximális méret", "MaximumLimits": "Maximális korlátok", "MassMovieSearch": "Tömeges filmkeresés", - "MarkAsFailedMessageText": "Biztosan sikertelennek szeretnéd jelölni a (z) „{0}”-t?", + "MarkAsFailedConfirmation": "Biztosan sikertelennek szeretnéd jelölni a (z) „{0}”-t?", "MarkAsFailed": "Megjelölés sikertelenként", "ManualImport": "Kézi importálás", "Manual": "Kézi", diff --git a/src/NzbDrone.Core/Localization/Core/is.json b/src/NzbDrone.Core/Localization/Core/is.json index 77e2ba2f23..0b31ab610b 100644 --- a/src/NzbDrone.Core/Localization/Core/is.json +++ b/src/NzbDrone.Core/Localization/Core/is.json @@ -663,7 +663,7 @@ "ManualImportSelectMovie": "Handvirkur innflutningur - Veldu kvikmynd", "ManualImportSelectQuality": " Handvirkur innflutningur - Veldu gæði", "MappedNetworkDrivesWindowsService": "Kortlagðar netdrif eru ekki fáanlegar þegar þær eru keyrðar sem Windows þjónusta. Vinsamlegast skoðaðu algengar spurningar fyrir frekari upplýsingar", - "MarkAsFailedMessageText": "Ertu viss um að þú viljir merkja '{0}' sem mistókst?", + "MarkAsFailedConfirmation": "Ertu viss um að þú viljir merkja '{0}' sem mistókst?", "MaximumLimits": "Hámarksmörk", "MaximumSize": "Hámarksstærð", "MegabytesPerMinute": "Megabæti á mínútu", diff --git a/src/NzbDrone.Core/Localization/Core/it.json b/src/NzbDrone.Core/Localization/Core/it.json index 9dfac63ac1..fa8f8230e3 100644 --- a/src/NzbDrone.Core/Localization/Core/it.json +++ b/src/NzbDrone.Core/Localization/Core/it.json @@ -502,7 +502,7 @@ "MaximumSizeHelpText": "La dimensione massima in MB di una release affinchè sia presa, imposta zero per illimitata", "MaximumSize": "Dimensione Massima", "MaximumLimits": "Limiti massimi", - "MarkAsFailedMessageText": "Sei sicuro di voler segnare '{0}' come fallito?", + "MarkAsFailedConfirmation": "Sei sicuro di voler segnare '{0}' come fallito?", "MarkAsFailed": "Segna come fallito", "Manual": "Manuale", "MaintenanceRelease": "Release di Manutenzione: correzione di bug e altri miglioramenti. Vedi la storia dei Commit su Github per maggiori dettagli", diff --git a/src/NzbDrone.Core/Localization/Core/ja.json b/src/NzbDrone.Core/Localization/Core/ja.json index 74a1267eda..debb45a44a 100644 --- a/src/NzbDrone.Core/Localization/Core/ja.json +++ b/src/NzbDrone.Core/Localization/Core/ja.json @@ -615,7 +615,7 @@ "ManualImportSelectMovie": "手動インポート-ムービーを選択", "ManualImportSelectQuality": " 手動インポート-品質を選択", "MappedNetworkDrivesWindowsService": "マップされたネットワークドライブは、Windowsサービスとして実行している場合は使用できません。詳細については、FAQを参照してください", - "MarkAsFailedMessageText": "'{0}'を失敗としてマークしてもよろしいですか?", + "MarkAsFailedConfirmation": "'{0}'を失敗としてマークしてもよろしいですか?", "MassMovieSearch": "マスムービー検索", "MaximumLimits": "最大制限", "MaximumSize": "最大サイズ", diff --git a/src/NzbDrone.Core/Localization/Core/ko.json b/src/NzbDrone.Core/Localization/Core/ko.json index d687e33cc8..d02bf7f4bd 100644 --- a/src/NzbDrone.Core/Localization/Core/ko.json +++ b/src/NzbDrone.Core/Localization/Core/ko.json @@ -625,7 +625,7 @@ "ManualImportSelectMovie": "수동 가져오기 - 동영상 선택", "ManualImportSelectQuality": " 수동 가져오기-품질 선택", "MappedNetworkDrivesWindowsService": "윈도우 서비스로 실행할 때는 매핑 된 네트워크 드라이브를 사용할 수 없습니다, 상세 내용은 FAQ를 참조하세요.", - "MarkAsFailedMessageText": "'{0}'을(를) 실패한 것으로 표시 하시겠습니까?", + "MarkAsFailedConfirmation": "'{0}'을(를) 실패한 것으로 표시 하시겠습니까?", "MassMovieSearch": "대량 영화 검색", "MaximumLimits": "최대 한도", "MaximumSize": "최대 크기", diff --git a/src/NzbDrone.Core/Localization/Core/nl.json b/src/NzbDrone.Core/Localization/Core/nl.json index 21412ef094..12fceb527f 100644 --- a/src/NzbDrone.Core/Localization/Core/nl.json +++ b/src/NzbDrone.Core/Localization/Core/nl.json @@ -608,7 +608,7 @@ "MovieIsMonitored": "Film wordt gemonitord", "MovieExcludedFromAutomaticAdd": "Film Uitgesloten Van Automatisch Toevoegen", "MovieAlreadyExcluded": "Film werd al Uitgesloten", - "MarkAsFailedMessageText": "Bent u zeker dat u '{0}' als mislukt wilt markeren?", + "MarkAsFailedConfirmation": "Bent u zeker dat u '{0}' als mislukt wilt markeren?", "Manual": "Manueel", "LogLevelTraceHelpTextWarning": "Trace log niveau moet enkel tijdelijk worden gebruikt", "LastDuration": "Laatste Looptijd", diff --git a/src/NzbDrone.Core/Localization/Core/pl.json b/src/NzbDrone.Core/Localization/Core/pl.json index fcee1b44e5..5755946288 100644 --- a/src/NzbDrone.Core/Localization/Core/pl.json +++ b/src/NzbDrone.Core/Localization/Core/pl.json @@ -100,7 +100,7 @@ "KeyboardShortcuts": "Skróty klawiszowe", "LinkHere": "tutaj", "ManualImportSelectQuality": " Import ręczny - wybierz Jakość", - "MarkAsFailedMessageText": "Czy na pewno chcesz oznaczyć „{0}” jako nieudany?", + "MarkAsFailedConfirmation": "Czy na pewno chcesz oznaczyć „{0}” jako nieudany?", "MinimumAvailability": "Minimalna dostępność", "Months": "Miesięcy", "PreferIndexerFlagsHelpText": "Nadaj priorytet wydaniom za pomocą specjalnych flag", diff --git a/src/NzbDrone.Core/Localization/Core/pt.json b/src/NzbDrone.Core/Localization/Core/pt.json index d8cb89a6e1..6981ec108d 100644 --- a/src/NzbDrone.Core/Localization/Core/pt.json +++ b/src/NzbDrone.Core/Localization/Core/pt.json @@ -544,7 +544,7 @@ "MinutesNinety": "90 minutos: {0}", "MinutesHundredTwenty": "120 minutos: {0}", "MIA": "Desaparecidos", - "MarkAsFailedMessageText": "Tem a certeza que quer marcar \"{0}\" como falhado?", + "MarkAsFailedConfirmation": "Tem a certeza que quer marcar \"{0}\" como falhado?", "MarkAsFailed": "Marcar como falhado", "Manual": "Manual", "LoadingMovieFilesFailed": "Falha no carregamento dos ficheiros do filme", diff --git a/src/NzbDrone.Core/Localization/Core/pt_BR.json b/src/NzbDrone.Core/Localization/Core/pt_BR.json index d8ab1f31a5..a8f40b07f2 100644 --- a/src/NzbDrone.Core/Localization/Core/pt_BR.json +++ b/src/NzbDrone.Core/Localization/Core/pt_BR.json @@ -388,7 +388,7 @@ "Max": "Máx.", "MassMovieSearch": "Pesquisar filmes em massa", "MarkAsFailed": "Marcar como falha", - "MarkAsFailedMessageText": "Tem certeza que deseja marcar \"{0}\" como falhado?", + "MarkAsFailedConfirmation": "Tem certeza que deseja marcar \"{0}\" como falhado?", "MappedNetworkDrivesWindowsService": "As unidades de rede mapeadas não estão disponíveis quando executadas como um serviço do Windows. Consulte as [FAQ]({url}) para obter mais informações.", "ManualImportSelectQuality": " Importação manual - Selecionar qualidade", "ManualImportSelectMovie": "Importação manual - Selecionar filme", diff --git a/src/NzbDrone.Core/Localization/Core/ro.json b/src/NzbDrone.Core/Localization/Core/ro.json index c8ef326ad2..3f5a009f2d 100644 --- a/src/NzbDrone.Core/Localization/Core/ro.json +++ b/src/NzbDrone.Core/Localization/Core/ro.json @@ -735,7 +735,7 @@ "ManualImportSelectLanguage": "Import manual - Selectați limba", "ManualImportSelectMovie": "Import manual - Selectați film", "ManualImportSelectQuality": " Import manual - Selectați calitatea", - "MarkAsFailedMessageText": "Sigur doriți să marcați „{0}” ca eșuat?", + "MarkAsFailedConfirmation": "Sigur doriți să marcați „{0}” ca eșuat?", "MaximumLimits": "Limite maxime", "MaximumSize": "Dimensiune maximă", "MegabytesPerMinute": "Megaocteți pe minut", diff --git a/src/NzbDrone.Core/Localization/Core/ru.json b/src/NzbDrone.Core/Localization/Core/ru.json index a165bae602..4c0ab50675 100644 --- a/src/NzbDrone.Core/Localization/Core/ru.json +++ b/src/NzbDrone.Core/Localization/Core/ru.json @@ -330,7 +330,7 @@ "LogLevel": "Уровень журналирования", "LogLevelTraceHelpTextWarning": "Включение трассировки журнала должно быть временным", "Manual": "Ручной", - "MarkAsFailedMessageText": "Вы уверены, что хотите отметить '{0}' как неудачный?", + "MarkAsFailedConfirmation": "Вы уверены, что хотите отметить '{0}' как неудачный?", "CustomFilters": "Настраиваемые фильтры", "CustomFormats": "Пользовательский формат", "ConnectSettingsSummary": "Уведомления, подключения к серверам/проигрывателям и настраиваемые скрипты", diff --git a/src/NzbDrone.Core/Localization/Core/sv.json b/src/NzbDrone.Core/Localization/Core/sv.json index 2a73ac825e..482095d556 100644 --- a/src/NzbDrone.Core/Localization/Core/sv.json +++ b/src/NzbDrone.Core/Localization/Core/sv.json @@ -599,7 +599,7 @@ "InteractiveSearch": "Interaktiv sökning", "LookingForReleaseProfiles1": "Letar du efter utgåvorsprofiler? Prova", "ManualImportSelectQuality": " Manuell import - Välj kvalitet", - "MarkAsFailedMessageText": "Är du säker på att du vill markera \"{0}\" som misslyckad?", + "MarkAsFailedConfirmation": "Är du säker på att du vill markera \"{0}\" som misslyckad?", "MinimumAgeHelpText": "Endast Usenet: Lägsta ålder i minuter av NZB innan de tas. Använd detta för att ge nya utgåvor tid att sprida sig till din usenet-leverantör.", "RecyclingBinCleanupHelpText": "Ställ in på 0 för att inaktivera automatisk rensning", "RemoveHelpTextWarning": "Om du tar bort tas nedladdningen och filen (filerna) bort från nedladdningsklienten.", diff --git a/src/NzbDrone.Core/Localization/Core/th.json b/src/NzbDrone.Core/Localization/Core/th.json index 99a409c559..aa745a889d 100644 --- a/src/NzbDrone.Core/Localization/Core/th.json +++ b/src/NzbDrone.Core/Localization/Core/th.json @@ -695,7 +695,7 @@ "Lowercase": "ตัวพิมพ์เล็ก", "ManualImportSelectLanguage": "นำเข้าด้วยตนเอง - เลือกภาษา", "ManualImportSelectQuality": " นำเข้าด้วยตนเอง - เลือกคุณภาพ", - "MarkAsFailedMessageText": "แน่ใจหรือไม่ว่าต้องการทำเครื่องหมาย \"{0}\" ว่าล้มเหลว", + "MarkAsFailedConfirmation": "แน่ใจหรือไม่ว่าต้องการทำเครื่องหมาย \"{0}\" ว่าล้มเหลว", "MaximumLimits": "ขีด จำกัด สูงสุด", "MaximumSize": "ขนาดสูงสุด", "MegabytesPerMinute": "เมกะไบต์ต่อนาที", diff --git a/src/NzbDrone.Core/Localization/Core/tr.json b/src/NzbDrone.Core/Localization/Core/tr.json index 943a525349..74adf3e626 100644 --- a/src/NzbDrone.Core/Localization/Core/tr.json +++ b/src/NzbDrone.Core/Localization/Core/tr.json @@ -801,7 +801,7 @@ "ManualImportSelectMovie": "Manuel İçe Aktar - Film Seç", "ManualImportSelectQuality": " Manuel İçe Aktar - Kalite Seç", "MappedNetworkDrivesWindowsService": "Windows Hizmeti olarak çalıştırıldığında eşlenen ağ sürücüleri kullanılamaz, daha fazla bilgi için [SSS]({url}) bölümüne bakın.", - "MarkAsFailedMessageText": "'{0}' başarısız olarak işaretlemek istediğinizden emin misiniz?", + "MarkAsFailedConfirmation": "'{0}' başarısız olarak işaretlemek istediğinizden emin misiniz?", "MaximumLimits": "Maksimum Sınırlar", "MaximumSize": "Maksimum Boyut", "MegabytesPerMinute": "Dakika Başına Megabayt", diff --git a/src/NzbDrone.Core/Localization/Core/uk.json b/src/NzbDrone.Core/Localization/Core/uk.json index 439d4c282e..cf7e025aef 100644 --- a/src/NzbDrone.Core/Localization/Core/uk.json +++ b/src/NzbDrone.Core/Localization/Core/uk.json @@ -667,7 +667,7 @@ "ManualImportSetReleaseGroup": "Імпорт вручну - встановити групу випуску", "MappedNetworkDrivesWindowsService": "Підключені мережеві диски недоступні під час роботи як служби Windows. Щоб отримати додаткову інформацію, перегляньте FAQ", "MarkAsFailed": "Позначити як помилку", - "MarkAsFailedMessageText": "Ви впевнені, що бажаєте позначити \"{0}\" як невдале?", + "MarkAsFailedConfirmation": "Ви впевнені, що бажаєте позначити \"{0}\" як невдале?", "MassMovieSearch": "Масовий пошук фільмів", "Max": "Максимальний", "MaximumSize": "Максимальний розмір", diff --git a/src/NzbDrone.Core/Localization/Core/vi.json b/src/NzbDrone.Core/Localization/Core/vi.json index 048d7a2903..31eb5f86a1 100644 --- a/src/NzbDrone.Core/Localization/Core/vi.json +++ b/src/NzbDrone.Core/Localization/Core/vi.json @@ -92,7 +92,7 @@ "ManualImportSelectMovie": "Nhập thủ công - Chọn phim", "ManualImportSelectQuality": " Nhập thủ công - Chọn chất lượng", "MappedNetworkDrivesWindowsService": "Các ổ đĩa mạng được ánh xạ không khả dụng khi chạy dưới dạng Dịch vụ Windows. Vui lòng xem Câu hỏi thường gặp để biết thêm thông tin", - "MarkAsFailedMessageText": "Bạn có chắc chắn muốn đánh dấu '{0}' là không thành công không?", + "MarkAsFailedConfirmation": "Bạn có chắc chắn muốn đánh dấu '{0}' là không thành công không?", "MassMovieSearch": "Tìm kiếm phim hàng loạt", "MaximumLimits": "Giới hạn tối đa", "MaximumSize": "Kích thước tối đa", diff --git a/src/NzbDrone.Core/Localization/Core/zh_CN.json b/src/NzbDrone.Core/Localization/Core/zh_CN.json index 778987a55f..18418e5bfa 100644 --- a/src/NzbDrone.Core/Localization/Core/zh_CN.json +++ b/src/NzbDrone.Core/Localization/Core/zh_CN.json @@ -568,7 +568,7 @@ "MaximumSizeHelpText": "抓取发布资源的最大大小(MB)。设置为零则不限制", "Max": "最大的", "MassMovieSearch": "批量搜索电影", - "MarkAsFailedMessageText": "您确定要标记'{0}'为已失败?", + "MarkAsFailedConfirmation": "您确定要标记'{0}'为已失败?", "ManualImportSelectQuality": " 手动导入 - 选择质量", "ManualImportSelectMovie": "手动导入 - 选择电影", "ManualImportSelectLanguage": "手动导入 - 选择语言", From 653b358fd3baa72954d6a7df3f5f71ef4668f386 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sat, 8 Mar 2025 16:36:12 +0200 Subject: [PATCH 244/579] Convert Delete Movie Modal to TypeScript Co-authored-by: Mark McDowall --- frontend/src/Movie/Delete/DeleteMovieModal.js | 37 ---- .../src/Movie/Delete/DeleteMovieModal.tsx | 24 +++ .../Movie/Delete/DeleteMovieModalContent.js | 163 ------------------ .../Movie/Delete/DeleteMovieModalContent.tsx | 149 ++++++++++++++++ .../DeleteMovieModalContentConnector.js | 45 ----- frontend/src/Movie/Details/MovieDetails.js | 1 - frontend/src/Movie/Movie.ts | 3 +- 7 files changed, 175 insertions(+), 247 deletions(-) delete mode 100644 frontend/src/Movie/Delete/DeleteMovieModal.js create mode 100644 frontend/src/Movie/Delete/DeleteMovieModal.tsx delete mode 100644 frontend/src/Movie/Delete/DeleteMovieModalContent.js create mode 100644 frontend/src/Movie/Delete/DeleteMovieModalContent.tsx delete mode 100644 frontend/src/Movie/Delete/DeleteMovieModalContentConnector.js diff --git a/frontend/src/Movie/Delete/DeleteMovieModal.js b/frontend/src/Movie/Delete/DeleteMovieModal.js deleted file mode 100644 index 5497e39527..0000000000 --- a/frontend/src/Movie/Delete/DeleteMovieModal.js +++ /dev/null @@ -1,37 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import Modal from 'Components/Modal/Modal'; -import { sizes } from 'Helpers/Props'; -import DeleteMovieModalContentConnector from './DeleteMovieModalContentConnector'; - -function DeleteMovieModal(props) { - const { - isOpen, - onModalClose, - previousMovie, - ...otherProps - } = props; - - return ( - - - - ); -} - -DeleteMovieModal.propTypes = { - ...DeleteMovieModalContentConnector.propTypes, - isOpen: PropTypes.bool.isRequired, - onModalClose: PropTypes.func.isRequired, - previousMovie: PropTypes.string -}; - -export default DeleteMovieModal; diff --git a/frontend/src/Movie/Delete/DeleteMovieModal.tsx b/frontend/src/Movie/Delete/DeleteMovieModal.tsx new file mode 100644 index 0000000000..6daffefb49 --- /dev/null +++ b/frontend/src/Movie/Delete/DeleteMovieModal.tsx @@ -0,0 +1,24 @@ +import React from 'react'; +import Modal from 'Components/Modal/Modal'; +import { sizes } from 'Helpers/Props'; +import DeleteMovieModalContent, { + DeleteMovieModalContentProps, +} from './DeleteMovieModalContent'; + +interface DeleteMovieModalProps extends DeleteMovieModalContentProps { + isOpen: boolean; +} + +function DeleteMovieModal({ + isOpen, + onModalClose, + ...otherProps +}: DeleteMovieModalProps) { + return ( + + + + ); +} + +export default DeleteMovieModal; diff --git a/frontend/src/Movie/Delete/DeleteMovieModalContent.js b/frontend/src/Movie/Delete/DeleteMovieModalContent.js deleted file mode 100644 index 68ee5d00bd..0000000000 --- a/frontend/src/Movie/Delete/DeleteMovieModalContent.js +++ /dev/null @@ -1,163 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import FormGroup from 'Components/Form/FormGroup'; -import FormInputGroup from 'Components/Form/FormInputGroup'; -import FormLabel from 'Components/Form/FormLabel'; -import Icon from 'Components/Icon'; -import Button from 'Components/Link/Button'; -import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; -import ModalBody from 'Components/Modal/ModalBody'; -import ModalContent from 'Components/Modal/ModalContent'; -import ModalFooter from 'Components/Modal/ModalFooter'; -import ModalHeader from 'Components/Modal/ModalHeader'; -import { icons, inputTypes, kinds } from 'Helpers/Props'; -import formatBytes from 'Utilities/Number/formatBytes'; -import translate from 'Utilities/String/translate'; -import styles from './DeleteMovieModalContent.css'; - -class DeleteMovieModalContent extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - deleteFiles: false - }; - } - - // - // Listeners - - onDeleteFilesChange = ({ value }) => { - this.setState({ deleteFiles: value }); - }; - - onDeleteMovieConfirmed = () => { - const deleteFiles = this.state.deleteFiles; - const addImportExclusion = this.props.deleteOptions.addImportExclusion; - - this.setState({ deleteFiles: false }); - this.props.onDeletePress(deleteFiles, addImportExclusion); - }; - - // - // Render - - render() { - const { - title, - path, - statistics = {}, - deleteOptions, - onModalClose, - onDeleteOptionChange - } = this.props; - - const { - movieFileCount = 0, - sizeOnDisk = 0 - } = statistics; - - const deleteFiles = this.state.deleteFiles; - const addImportExclusion = deleteOptions.addImportExclusion; - - return ( - - - {translate('DeleteHeader', { title })} - - - -
- - - {path} -
- - - - {translate('AddListExclusion')} - - - - - - - {movieFileCount === 0 ? translate('DeleteMovieFolder') : translate('DeleteMovieFiles', { movieFileCount })} - - - - - { - deleteFiles ? -
-
- - { - movieFileCount ? -
- {translate('DeleteMovieFolderMovieCount', { movieFileCount, size: formatBytes(sizeOnDisk) })} -
: - null - } -
: - null - } - -
- - - - - - -
- ); - } -} - -DeleteMovieModalContent.propTypes = { - title: PropTypes.string.isRequired, - path: PropTypes.string.isRequired, - statistics: PropTypes.object.isRequired, - hasFile: PropTypes.bool.isRequired, - deleteOptions: PropTypes.object.isRequired, - onDeleteOptionChange: PropTypes.func.isRequired, - onDeletePress: PropTypes.func.isRequired, - onModalClose: PropTypes.func.isRequired -}; - -DeleteMovieModalContent.defaultProps = { - statistics: {} -}; - -export default DeleteMovieModalContent; diff --git a/frontend/src/Movie/Delete/DeleteMovieModalContent.tsx b/frontend/src/Movie/Delete/DeleteMovieModalContent.tsx new file mode 100644 index 0000000000..ebd850d8aa --- /dev/null +++ b/frontend/src/Movie/Delete/DeleteMovieModalContent.tsx @@ -0,0 +1,149 @@ +import React, { useCallback, useState } from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import AppState from 'App/State/AppState'; +import FormGroup from 'Components/Form/FormGroup'; +import FormInputGroup from 'Components/Form/FormInputGroup'; +import FormLabel from 'Components/Form/FormLabel'; +import Icon from 'Components/Icon'; +import Button from 'Components/Link/Button'; +import InlineMarkdown from 'Components/Markdown/InlineMarkdown'; +import ModalBody from 'Components/Modal/ModalBody'; +import ModalContent from 'Components/Modal/ModalContent'; +import ModalFooter from 'Components/Modal/ModalFooter'; +import ModalHeader from 'Components/Modal/ModalHeader'; +import { icons, inputTypes, kinds } from 'Helpers/Props'; +import { Statistics } from 'Movie/Movie'; +import useMovie from 'Movie/useMovie'; +import { deleteMovie, setDeleteOption } from 'Store/Actions/movieActions'; +import { CheckInputChanged } from 'typings/inputs'; +import formatBytes from 'Utilities/Number/formatBytes'; +import translate from 'Utilities/String/translate'; +import styles from './DeleteMovieModalContent.css'; + +export interface DeleteMovieModalContentProps { + movieId: number; + onModalClose: () => void; +} + +function DeleteMovieModalContent({ + movieId, + onModalClose, +}: DeleteMovieModalContentProps) { + const dispatch = useDispatch(); + const { + title, + path, + collection, + statistics = {} as Statistics, + } = useMovie(movieId)!; + const { addImportExclusion } = useSelector( + (state: AppState) => state.movies.deleteOptions + ); + + const { movieFileCount = 0, sizeOnDisk = 0 } = statistics; + + const [deleteFiles, setDeleteFiles] = useState(false); + + const handleDeleteFilesChange = useCallback( + ({ value }: CheckInputChanged) => { + setDeleteFiles(value); + }, + [] + ); + + const handleDeleteMovieConfirmed = useCallback(() => { + dispatch( + deleteMovie({ + id: movieId, + collectionTmdbId: collection?.tmdbId, + deleteFiles, + addImportExclusion, + }) + ); + }, [movieId, collection, addImportExclusion, deleteFiles, dispatch]); + + const handleDeleteOptionChange = useCallback( + ({ name, value }: CheckInputChanged) => { + dispatch(setDeleteOption({ [name]: value })); + }, + [dispatch] + ); + + return ( + + {translate('DeleteHeader', { title })} + + +
+ + + {path} +
+ + + {translate('AddListExclusion')} + + + + + + + {movieFileCount === 0 + ? translate('DeleteMovieFolder') + : translate('DeleteMovieFiles', { movieFileCount })} + + + + + + {deleteFiles ? ( +
+
+ +
+ + {movieFileCount ? ( +
+ {translate('DeleteMovieFolderMovieCount', { + movieFileCount, + size: formatBytes(sizeOnDisk), + })} +
+ ) : null} +
+ ) : null} +
+ + + + + + +
+ ); +} + +export default DeleteMovieModalContent; diff --git a/frontend/src/Movie/Delete/DeleteMovieModalContentConnector.js b/frontend/src/Movie/Delete/DeleteMovieModalContentConnector.js deleted file mode 100644 index 93cc3928ca..0000000000 --- a/frontend/src/Movie/Delete/DeleteMovieModalContentConnector.js +++ /dev/null @@ -1,45 +0,0 @@ -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import { deleteMovie, setDeleteOption } from 'Store/Actions/movieActions'; -import createMovieSelector from 'Store/Selectors/createMovieSelector'; -import DeleteMovieModalContent from './DeleteMovieModalContent'; - -function createMapStateToProps() { - return createSelector( - (state) => state.movies.deleteOptions, - createMovieSelector(), - (deleteOptions, movie) => { - return { - ...movie, - deleteOptions - }; - } - ); -} - -function createMapDispatchToProps(dispatch, props) { - return { - onDeleteOptionChange(option) { - dispatch( - setDeleteOption({ - [option.name]: option.value - }) - ); - }, - - onDeletePress(deleteFiles, addImportExclusion) { - dispatch( - deleteMovie({ - id: props.movieId, - collectionTmdbId: this.collection?.tmdbId, - deleteFiles, - addImportExclusion - }) - ); - - props.onModalClose(true); - } - }; -} - -export default connect(createMapStateToProps, createMapDispatchToProps)(DeleteMovieModalContent); diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js index 6b23dee7e3..1b01f93d93 100644 --- a/frontend/src/Movie/Details/MovieDetails.js +++ b/frontend/src/Movie/Details/MovieDetails.js @@ -747,7 +747,6 @@ class MovieDetails extends Component { isOpen={isDeleteMovieModalOpen} movieId={id} onModalClose={this.onDeleteMovieModalClose} - nextMovieRelativePath={`/movie/${nextMovie.titleSlug}`} /> Date: Sun, 9 Mar 2025 11:53:09 +0200 Subject: [PATCH 245/579] Bump version to 5.20.1 --- azure-pipelines.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 5243a66c9f..18d6887e83 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -9,7 +9,7 @@ variables: testsFolder: './_tests' yarnCacheFolder: $(Pipeline.Workspace)/.yarn nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages - majorVersion: '5.20.0' + majorVersion: '5.20.1' minorVersion: $[counter('minorVersion', 2000)] radarrVersion: '$(majorVersion).$(minorVersion)' buildName: '$(Build.SourceBranchName).$(radarrVersion)' From f815b31c339ee0ac0453e84970e1452f1202aa43 Mon Sep 17 00:00:00 2001 From: Bogdan Date: Sun, 9 Mar 2025 14:08:20 +0200 Subject: [PATCH 246/579] Convert Movie Details to TypeScript Co-authored-by: Mark McDowall --- .../src/AddMovie/AddNewMovie/AddNewMovie.js | 7 +- .../AddNewMovie/AddNewMovieConnector.js | 7 +- .../AddNewMovie/AddNewMovieSearchResult.js | 14 +- .../AddNewMovieSearchResultConnector.js | 5 +- frontend/src/App/AppRoutes.tsx | 4 +- frontend/src/App/State/AppState.ts | 3 + frontend/src/App/State/ExtraFilesAppState.ts | 6 + frontend/src/Components/Icon.tsx | 9 +- frontend/src/Components/InfoLabel.css | 4 + frontend/src/Components/InfoLabel.css.d.ts | 1 + frontend/src/Components/InfoLabel.js | 54 - frontend/src/Components/InfoLabel.tsx | 41 + frontend/src/Components/Marquee.js | 48 +- .../Page/Toolbar/PageToolbarButton.js | 58 -- .../Page/Toolbar/PageToolbarButton.tsx | 49 + frontend/src/Helpers/Props/kinds.ts | 3 +- .../InteractiveImportModalContent.tsx | 5 +- .../InteractiveImportModal.tsx | 7 +- frontend/src/Movie/Details/MovieDetails.css | 3 +- frontend/src/Movie/Details/MovieDetails.js | 835 --------------- frontend/src/Movie/Details/MovieDetails.tsx | 956 ++++++++++++++++++ .../Movie/Details/MovieDetailsConnector.js | 334 ------ .../src/Movie/Details/MovieDetailsPage.tsx | 39 + .../Details/MovieDetailsPageConnector.js | 125 --- ...vieStatusLabel.js => MovieStatusLabel.tsx} | 83 +- frontend/src/Movie/Details/MovieTags.js | 30 - frontend/src/Movie/Details/MovieTags.tsx | 35 + .../src/Movie/Details/MovieTagsConnector.js | 26 - .../Movie/Index/Menus/MovieIndexSearchMenu.js | 53 - .../Index/createMovieIndexItemSelector.ts | 6 +- .../{movieEntities.js => movieEntities.ts} | 4 +- frontend/src/MovieFile/ExtraFile.ts | 10 + .../Selectors/createHealthCheckSelector.js | 25 - frontend/src/Tags/useTags.ts | 8 + src/NzbDrone.Core/Localization/Core/ar.json | 4 +- src/NzbDrone.Core/Localization/Core/bg.json | 4 +- src/NzbDrone.Core/Localization/Core/ca.json | 4 +- src/NzbDrone.Core/Localization/Core/cs.json | 4 +- src/NzbDrone.Core/Localization/Core/da.json | 4 +- src/NzbDrone.Core/Localization/Core/de.json | 4 +- src/NzbDrone.Core/Localization/Core/el.json | 4 +- src/NzbDrone.Core/Localization/Core/en.json | 5 +- src/NzbDrone.Core/Localization/Core/es.json | 4 +- src/NzbDrone.Core/Localization/Core/fi.json | 4 +- src/NzbDrone.Core/Localization/Core/fr.json | 4 +- src/NzbDrone.Core/Localization/Core/he.json | 4 +- src/NzbDrone.Core/Localization/Core/hi.json | 4 +- src/NzbDrone.Core/Localization/Core/hu.json | 4 +- src/NzbDrone.Core/Localization/Core/is.json | 4 +- src/NzbDrone.Core/Localization/Core/it.json | 4 +- src/NzbDrone.Core/Localization/Core/ja.json | 4 +- src/NzbDrone.Core/Localization/Core/ko.json | 4 +- src/NzbDrone.Core/Localization/Core/nl.json | 4 +- src/NzbDrone.Core/Localization/Core/pl.json | 4 +- src/NzbDrone.Core/Localization/Core/pt.json | 4 +- .../Localization/Core/pt_BR.json | 4 +- src/NzbDrone.Core/Localization/Core/ro.json | 4 +- src/NzbDrone.Core/Localization/Core/ru.json | 4 +- src/NzbDrone.Core/Localization/Core/sv.json | 4 +- src/NzbDrone.Core/Localization/Core/th.json | 4 +- src/NzbDrone.Core/Localization/Core/tr.json | 4 +- src/NzbDrone.Core/Localization/Core/uk.json | 4 +- src/NzbDrone.Core/Localization/Core/vi.json | 4 +- .../Localization/Core/zh_CN.json | 4 +- 64 files changed, 1317 insertions(+), 1701 deletions(-) create mode 100644 frontend/src/App/State/ExtraFilesAppState.ts delete mode 100644 frontend/src/Components/InfoLabel.js create mode 100644 frontend/src/Components/InfoLabel.tsx delete mode 100644 frontend/src/Components/Page/Toolbar/PageToolbarButton.js create mode 100644 frontend/src/Components/Page/Toolbar/PageToolbarButton.tsx delete mode 100644 frontend/src/Movie/Details/MovieDetails.js create mode 100644 frontend/src/Movie/Details/MovieDetails.tsx delete mode 100644 frontend/src/Movie/Details/MovieDetailsConnector.js create mode 100644 frontend/src/Movie/Details/MovieDetailsPage.tsx delete mode 100644 frontend/src/Movie/Details/MovieDetailsPageConnector.js rename frontend/src/Movie/Details/{MovieStatusLabel.js => MovieStatusLabel.tsx} (60%) delete mode 100644 frontend/src/Movie/Details/MovieTags.js create mode 100644 frontend/src/Movie/Details/MovieTags.tsx delete mode 100644 frontend/src/Movie/Details/MovieTagsConnector.js delete mode 100644 frontend/src/Movie/Index/Menus/MovieIndexSearchMenu.js rename frontend/src/Movie/{movieEntities.js => movieEntities.ts} (91%) delete mode 100644 frontend/src/Store/Selectors/createHealthCheckSelector.js create mode 100644 frontend/src/Tags/useTags.ts diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js index c49a50a4e2..85ff4dd7da 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovie.js @@ -82,8 +82,7 @@ class AddNewMovie extends Component { const { error, items, - hasExistingMovies, - colorImpairedMode + hasExistingMovies } = this.props; const term = this.state.term; @@ -150,7 +149,6 @@ class AddNewMovie extends Component { return ( ); @@ -223,8 +221,7 @@ AddNewMovie.propTypes = { items: PropTypes.arrayOf(PropTypes.object).isRequired, hasExistingMovies: PropTypes.bool.isRequired, onMovieLookupChange: PropTypes.func.isRequired, - onClearMovieLookup: PropTypes.func.isRequired, - colorImpairedMode: PropTypes.bool.isRequired + onClearMovieLookup: PropTypes.func.isRequired }; export default AddNewMovie; diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovieConnector.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovieConnector.js index 448fc18675..5a05865790 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovieConnector.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovieConnector.js @@ -6,7 +6,6 @@ import { clearAddMovie, lookupMovie } from 'Store/Actions/addMovieActions'; import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions'; import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions'; import { fetchRootFolders } from 'Store/Actions/rootFolderActions'; -import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; import hasDifferentItems from 'Utilities/Object/hasDifferentItems'; import selectUniqueIds from 'Utilities/Object/selectUniqueIds'; import parseUrl from 'Utilities/String/parseUrl'; @@ -17,15 +16,13 @@ function createMapStateToProps() { (state) => state.addMovie, (state) => state.movies.items.length, (state) => state.router.location, - createUISettingsSelector(), - (addMovie, existingMoviesCount, location, uiSettings) => { + (addMovie, existingMoviesCount, location) => { const { params } = parseUrl(location.search); return { ...addMovie, term: params.term, - hasExistingMovies: existingMoviesCount > 0, - colorImpairedMode: uiSettings.enableColorImpairedMode + hasExistingMovies: existingMoviesCount > 0 }; } ); diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js index 5a97ad0eb9..e77cc189c7 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResult.js @@ -74,12 +74,9 @@ class AddNewMovieSearchResult extends Component { isExistingMovie, isExcluded, isSmallScreen, - colorImpairedMode, - id, monitored, isAvailable, movieFile, - queueItem, runtime, movieRuntimeFormat, certification @@ -285,14 +282,12 @@ class AddNewMovieSearchResult extends Component { { isExistingMovie && isSmallScreen && }
@@ -337,12 +332,9 @@ AddNewMovieSearchResult.propTypes = { isExistingMovie: PropTypes.bool.isRequired, isExcluded: PropTypes.bool, isSmallScreen: PropTypes.bool.isRequired, - id: PropTypes.number, monitored: PropTypes.bool.isRequired, isAvailable: PropTypes.bool.isRequired, movieFile: PropTypes.object, - queueItem: PropTypes.object, - colorImpairedMode: PropTypes.bool, runtime: PropTypes.number.isRequired, movieRuntimeFormat: PropTypes.string.isRequired, certification: PropTypes.string diff --git a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResultConnector.js b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResultConnector.js index 6e22256bce..ad3a5a3b0f 100644 --- a/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResultConnector.js +++ b/frontend/src/AddMovie/AddNewMovie/AddNewMovieSearchResultConnector.js @@ -8,19 +8,16 @@ function createMapStateToProps() { return createSelector( createExistingMovieSelector(), createDimensionsSelector(), - (state) => state.queue.details.items, (state) => state.movieFiles.items, (state, { internalId }) => internalId, (state) => state.settings.ui.item.movieRuntimeFormat, - (isExistingMovie, dimensions, queueItems, movieFiles, internalId, movieRuntimeFormat) => { - const queueItem = queueItems.find((item) => internalId > 0 && item.movieId === internalId); + (isExistingMovie, dimensions, movieFiles, internalId, movieRuntimeFormat) => { const movieFile = movieFiles.find((item) => internalId > 0 && item.movieId === internalId); return { existingMovieId: internalId, isExistingMovie, isSmallScreen: dimensions.isSmallScreen, - queueItem, movieFile, movieRuntimeFormat }; diff --git a/frontend/src/App/AppRoutes.tsx b/frontend/src/App/AppRoutes.tsx index e1b2d2e11f..6f660c045c 100644 --- a/frontend/src/App/AppRoutes.tsx +++ b/frontend/src/App/AppRoutes.tsx @@ -10,7 +10,7 @@ import CollectionConnector from 'Collection/CollectionConnector'; import NotFound from 'Components/NotFound'; import Switch from 'Components/Router/Switch'; import DiscoverMovieConnector from 'DiscoverMovie/DiscoverMovieConnector'; -import MovieDetailsPageConnector from 'Movie/Details/MovieDetailsPageConnector'; +import MovieDetailsPage from 'Movie/Details/MovieDetailsPage'; import MovieIndex from 'Movie/Index/MovieIndex'; import CustomFormatSettingsPage from 'Settings/CustomFormats/CustomFormatSettingsPage'; import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector'; @@ -67,7 +67,7 @@ function AppRoutes() { - + {/* Calendar diff --git a/frontend/src/App/State/AppState.ts b/frontend/src/App/State/AppState.ts index fdee6369bd..638c94da0a 100644 --- a/frontend/src/App/State/AppState.ts +++ b/frontend/src/App/State/AppState.ts @@ -1,6 +1,7 @@ import BlocklistAppState from './BlocklistAppState'; import CalendarAppState from './CalendarAppState'; import CommandAppState from './CommandAppState'; +import ExtraFilesAppState from './ExtraFilesAppState'; import HistoryAppState, { MovieHistoryAppState } from './HistoryAppState'; import InteractiveImportAppState from './InteractiveImportAppState'; import MovieBlocklistAppState from './MovieBlocklistAppState'; @@ -53,6 +54,7 @@ export interface CustomFilter { export interface AppSectionState { isConnected: boolean; isReconnecting: boolean; + isSidebarVisible: boolean; version: string; prevVersion?: string; dimensions: { @@ -67,6 +69,7 @@ interface AppState { blocklist: BlocklistAppState; calendar: CalendarAppState; commands: CommandAppState; + extraFiles: ExtraFilesAppState; history: HistoryAppState; interactiveImport: InteractiveImportAppState; movieBlocklist: MovieBlocklistAppState; diff --git a/frontend/src/App/State/ExtraFilesAppState.ts b/frontend/src/App/State/ExtraFilesAppState.ts new file mode 100644 index 0000000000..ef1aff9cd9 --- /dev/null +++ b/frontend/src/App/State/ExtraFilesAppState.ts @@ -0,0 +1,6 @@ +import AppSectionState from 'App/State/AppSectionState'; +import { ExtraFile } from 'MovieFile/ExtraFile'; + +type ExtraFilesAppState = AppSectionState; + +export default ExtraFilesAppState; diff --git a/frontend/src/Components/Icon.tsx b/frontend/src/Components/Icon.tsx index ea52798402..ff1597bcf3 100644 --- a/frontend/src/Components/Icon.tsx +++ b/frontend/src/Components/Icon.tsx @@ -8,17 +8,20 @@ import { kinds } from 'Helpers/Props'; import { Kind } from 'Helpers/Props/kinds'; import styles from './Icon.css'; +export type IconName = FontAwesomeIconProps['icon']; +export type IconKind = Extract; + export interface IconProps extends Omit< FontAwesomeIconProps, 'icon' | 'spin' | 'name' | 'title' | 'size' > { containerClassName?: ComponentProps<'span'>['className']; - name: FontAwesomeIconProps['icon']; - kind?: Extract; + name: IconName; + kind?: IconKind; size?: number; isSpinning?: FontAwesomeIconProps['spin']; - title?: string | (() => string); + title?: string | (() => string) | null; } export default function Icon({ diff --git a/frontend/src/Components/InfoLabel.css b/frontend/src/Components/InfoLabel.css index 7edc667c8f..cae10be4f7 100644 --- a/frontend/src/Components/InfoLabel.css +++ b/frontend/src/Components/InfoLabel.css @@ -16,6 +16,10 @@ /** Kinds **/ +.default { + color: inherit; +} + /** Sizes **/ .small { diff --git a/frontend/src/Components/InfoLabel.css.d.ts b/frontend/src/Components/InfoLabel.css.d.ts index b5664ee83e..2dd14e33b2 100644 --- a/frontend/src/Components/InfoLabel.css.d.ts +++ b/frontend/src/Components/InfoLabel.css.d.ts @@ -1,6 +1,7 @@ // This file is automatically generated. // Please do not change this file! interface CssExports { + 'default': string; 'label': string; 'large': string; 'medium': string; diff --git a/frontend/src/Components/InfoLabel.js b/frontend/src/Components/InfoLabel.js deleted file mode 100644 index cdcdff377f..0000000000 --- a/frontend/src/Components/InfoLabel.js +++ /dev/null @@ -1,54 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import { kinds, sizes } from 'Helpers/Props'; -import styles from './InfoLabel.css'; - -function InfoLabel(props) { - const { - className, - name, - kind, - size, - outline, - children, - ...otherProps - } = props; - - return ( - -
- {name} -
-
- {children} -
-
- ); -} - -InfoLabel.propTypes = { - className: PropTypes.string.isRequired, - name: PropTypes.string.isRequired, - kind: PropTypes.oneOf(kinds.all).isRequired, - size: PropTypes.oneOf(sizes.all).isRequired, - outline: PropTypes.bool.isRequired, - children: PropTypes.node.isRequired -}; - -InfoLabel.defaultProps = { - className: styles.label, - kind: kinds.DEFAULT, - size: sizes.SMALL, - outline: false -}; - -export default InfoLabel; diff --git a/frontend/src/Components/InfoLabel.tsx b/frontend/src/Components/InfoLabel.tsx new file mode 100644 index 0000000000..dadf5e4b6a --- /dev/null +++ b/frontend/src/Components/InfoLabel.tsx @@ -0,0 +1,41 @@ +import classNames from 'classnames'; +import React, { ComponentProps, ReactNode } from 'react'; +import { Kind } from 'Helpers/Props/kinds'; +import { Size } from 'Helpers/Props/sizes'; +import styles from './InfoLabel.css'; + +interface InfoLabelProps extends ComponentProps<'span'> { + className?: string; + name: string; + kind?: Extract; + size?: Extract; + outline?: boolean; + children: ReactNode; +} + +function InfoLabel({ + className = styles.label, + name, + kind = 'default', + size = 'small', + outline = false, + children, + ...otherProps +}: InfoLabelProps) { + return ( + +
{name}
+
{children}
+
+ ); +} + +export default InfoLabel; diff --git a/frontend/src/Components/Marquee.js b/frontend/src/Components/Marquee.js index c0c7ec30c6..c6195dca62 100644 --- a/frontend/src/Components/Marquee.js +++ b/frontend/src/Components/Marquee.js @@ -1,3 +1,4 @@ +import classNames from 'classnames'; import PropTypes from 'prop-types'; import React, { Component } from 'react'; @@ -7,26 +8,15 @@ const TIMEOUT = 1 / FPS * 1000; class Marquee extends Component { - static propTypes = { - text: PropTypes.string, - title: PropTypes.string, - hoverToStop: PropTypes.bool, - loop: PropTypes.bool, - className: PropTypes.string - }; + constructor(props, context) { + super(props, context); - static defaultProps = { - text: '', - title: '', - hoverToStop: true, - loop: false - }; - - state = { - animatedWidth: 0, - overflowWidth: 0, - direction: 0 - }; + this.state = { + animatedWidth: 0, + overflowWidth: 0, + direction: 0 + }; + } componentDidMount() { this.measureText(); @@ -138,7 +128,7 @@ class Marquee extends Component { ref={(el) => { this.container = el; }} - className={`ui-marquee ${this.props.className}`} + className={classNames('ui-marquee', this.props.className)} style={{ overflow: 'hidden' }} > { this.container = el; }} - className={`ui-marquee ${this.props.className}`.trim()} + className={classNames('ui-marquee', this.props.className)} style={{ overflow: 'hidden' }} onMouseEnter={this.onHandleMouseEnter} onMouseLeave={this.onHandleMouseLeave} @@ -178,4 +168,20 @@ class Marquee extends Component { } } +Marquee.propTypes = { + text: PropTypes.string, + title: PropTypes.string, + hoverToStop: PropTypes.bool, + loop: PropTypes.bool, + className: PropTypes.string +}; + +Marquee.defaultProps = { + text: '', + title: '', + hoverToStop: true, + loop: false, + className: '' +}; + export default Marquee; diff --git a/frontend/src/Components/Page/Toolbar/PageToolbarButton.js b/frontend/src/Components/Page/Toolbar/PageToolbarButton.js deleted file mode 100644 index c93603aa94..0000000000 --- a/frontend/src/Components/Page/Toolbar/PageToolbarButton.js +++ /dev/null @@ -1,58 +0,0 @@ -import classNames from 'classnames'; -import PropTypes from 'prop-types'; -import React from 'react'; -import Icon from 'Components/Icon'; -import Link from 'Components/Link/Link'; -import { icons } from 'Helpers/Props'; -import styles from './PageToolbarButton.css'; - -function PageToolbarButton(props) { - const { - label, - iconName, - spinningName, - isDisabled, - isSpinning, - ...otherProps - } = props; - - return ( - - - -
-
- {label} -
-
- - ); -} - -PageToolbarButton.propTypes = { - label: PropTypes.string.isRequired, - iconName: PropTypes.object.isRequired, - spinningName: PropTypes.object, - isSpinning: PropTypes.bool, - isDisabled: PropTypes.bool, - onPress: PropTypes.func -}; - -PageToolbarButton.defaultProps = { - spinningName: icons.SPINNER, - isDisabled: false, - isSpinning: false -}; - -export default PageToolbarButton; diff --git a/frontend/src/Components/Page/Toolbar/PageToolbarButton.tsx b/frontend/src/Components/Page/Toolbar/PageToolbarButton.tsx new file mode 100644 index 0000000000..1b87c09fa2 --- /dev/null +++ b/frontend/src/Components/Page/Toolbar/PageToolbarButton.tsx @@ -0,0 +1,49 @@ +import classNames from 'classnames'; +import React from 'react'; +import Icon, { IconName } from 'Components/Icon'; +import Link, { LinkProps } from 'Components/Link/Link'; +import { icons } from 'Helpers/Props'; +import styles from './PageToolbarButton.css'; + +export interface PageToolbarButtonProps extends LinkProps { + label: string; + iconName: IconName; + spinningName?: IconName; + isSpinning?: boolean; + isDisabled?: boolean; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + overflowComponent?: React.ComponentType; +} + +function PageToolbarButton({ + label, + iconName, + spinningName = icons.SPINNER, + isDisabled = false, + isSpinning = false, + overflowComponent, + ...otherProps +}: PageToolbarButtonProps) { + return ( + + + +
+
{label}
+
+ + ); +} + +export default PageToolbarButton; diff --git a/frontend/src/Helpers/Props/kinds.ts b/frontend/src/Helpers/Props/kinds.ts index fc94defbbb..cb699eab09 100644 --- a/frontend/src/Helpers/Props/kinds.ts +++ b/frontend/src/Helpers/Props/kinds.ts @@ -36,4 +36,5 @@ export type Kind = | 'primary' | 'purple' | 'success' - | 'warning'; + | 'warning' + | 'queue'; diff --git a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx index ef99019692..8a014fbca8 100644 --- a/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx +++ b/frontend/src/InteractiveImport/Interactive/InteractiveImportModalContent.tsx @@ -192,10 +192,9 @@ const importModeSelector = createSelector( } ); -interface InteractiveImportModalContentProps { +export interface InteractiveImportModalContentProps { downloadId?: string; movieId?: number; - seasonNumber?: number; showMovie?: boolean; allowMovieChange?: boolean; showDelete?: boolean; @@ -217,7 +216,6 @@ function InteractiveImportModalContent( const { downloadId, movieId, - seasonNumber, allowMovieChange = true, showMovie = true, showFilterExistingFiles = false, @@ -343,7 +341,6 @@ function InteractiveImportModalContent( fetchInteractiveImportItems({ downloadId, movieId, - seasonNumber, folder, filterExistingFiles, }) diff --git a/frontend/src/InteractiveImport/InteractiveImportModal.tsx b/frontend/src/InteractiveImport/InteractiveImportModal.tsx index 37b26012e9..28f8a823e7 100644 --- a/frontend/src/InteractiveImport/InteractiveImportModal.tsx +++ b/frontend/src/InteractiveImport/InteractiveImportModal.tsx @@ -4,9 +4,12 @@ import usePrevious from 'Helpers/Hooks/usePrevious'; import { sizes } from 'Helpers/Props'; import translate from 'Utilities/String/translate'; import InteractiveImportSelectFolderModalContent from './Folder/InteractiveImportSelectFolderModalContent'; -import InteractiveImportModalContent from './Interactive/InteractiveImportModalContent'; +import InteractiveImportModalContent, { + InteractiveImportModalContentProps, +} from './Interactive/InteractiveImportModalContent'; -interface InteractiveImportModalProps { +interface InteractiveImportModalProps + extends Omit { isOpen: boolean; folder?: string; downloadId?: string; diff --git a/frontend/src/Movie/Details/MovieDetails.css b/frontend/src/Movie/Details/MovieDetails.css index 1c8f955fc9..36a23987ae 100644 --- a/frontend/src/Movie/Details/MovieDetails.css +++ b/frontend/src/Movie/Details/MovieDetails.css @@ -160,9 +160,8 @@ } .overview { - flex: 1 0 auto; + flex: 1 0 0; margin-top: 8px; - padding-left: 7px; min-height: 0; font-size: $intermediateFontSize; } diff --git a/frontend/src/Movie/Details/MovieDetails.js b/frontend/src/Movie/Details/MovieDetails.js deleted file mode 100644 index 1b01f93d93..0000000000 --- a/frontend/src/Movie/Details/MovieDetails.js +++ /dev/null @@ -1,835 +0,0 @@ -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import TextTruncate from 'react-text-truncate'; -import Alert from 'Components/Alert'; -import FieldSet from 'Components/FieldSet'; -import Icon from 'Components/Icon'; -import ImdbRating from 'Components/ImdbRating'; -import InfoLabel from 'Components/InfoLabel'; -import IconButton from 'Components/Link/IconButton'; -import Marquee from 'Components/Marquee'; -import Measure from 'Components/Measure'; -import MonitorToggleButton from 'Components/MonitorToggleButton'; -import PageContent from 'Components/Page/PageContent'; -import PageContentBody from 'Components/Page/PageContentBody'; -import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; -import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; -import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; -import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; -import RottenTomatoRating from 'Components/RottenTomatoRating'; -import TmdbRating from 'Components/TmdbRating'; -import Popover from 'Components/Tooltip/Popover'; -import Tooltip from 'Components/Tooltip/Tooltip'; -import TraktRating from 'Components/TraktRating'; -import { icons, kinds, sizes, sortDirections, tooltipPositions } from 'Helpers/Props'; -import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; -import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; -import EditMovieModal from 'Movie/Edit/EditMovieModal'; -import getMovieStatusDetails from 'Movie/getMovieStatusDetails'; -import MovieHistoryModal from 'Movie/History/MovieHistoryModal'; -import MovieCollectionLabel from 'Movie/MovieCollectionLabel'; -import MovieGenres from 'Movie/MovieGenres'; -import MoviePoster from 'Movie/MoviePoster'; -import MovieInteractiveSearchModal from 'Movie/Search/MovieInteractiveSearchModal'; -import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable'; -import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable'; -import OrganizePreviewModal from 'Organize/OrganizePreviewModal'; -import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; -import fonts from 'Styles/Variables/fonts'; -import * as keyCodes from 'Utilities/Constants/keyCodes'; -import formatRuntime from 'Utilities/Date/formatRuntime'; -import formatBytes from 'Utilities/Number/formatBytes'; -import translate from 'Utilities/String/translate'; -import MovieCastPosters from './Credits/Cast/MovieCastPosters'; -import MovieCrewPosters from './Credits/Crew/MovieCrewPosters'; -import MovieDetailsLinks from './MovieDetailsLinks'; -import MovieReleaseDates from './MovieReleaseDates'; -import MovieStatusLabel from './MovieStatusLabel'; -import MovieTagsConnector from './MovieTagsConnector'; -import MovieTitlesTable from './Titles/MovieTitlesTable'; -import styles from './MovieDetails.css'; - -const defaultFontSize = parseInt(fonts.defaultFontSize); -const lineHeight = parseFloat(fonts.lineHeight); - -function getFanartUrl(images) { - const image = images.find((img) => img.coverType === 'fanart'); - return image?.url ?? image?.remoteUrl; -} - -class MovieDetails extends Component { - - // - // Lifecycle - - constructor(props, context) { - super(props, context); - - this.state = { - isOrganizeModalOpen: false, - isEditMovieModalOpen: false, - isDeleteMovieModalOpen: false, - isInteractiveImportModalOpen: false, - isInteractiveSearchModalOpen: false, - isMovieHistoryModalOpen: false, - overviewHeight: 0, - titleWidth: 0 - }; - } - - componentDidMount() { - window.addEventListener('touchstart', this.onTouchStart); - window.addEventListener('touchend', this.onTouchEnd); - window.addEventListener('touchcancel', this.onTouchCancel); - window.addEventListener('touchmove', this.onTouchMove); - window.addEventListener('keyup', this.onKeyUp); - } - - componentWillUnmount() { - window.removeEventListener('touchstart', this.onTouchStart); - window.removeEventListener('touchend', this.onTouchEnd); - window.removeEventListener('touchcancel', this.onTouchCancel); - window.removeEventListener('touchmove', this.onTouchMove); - window.removeEventListener('keyup', this.onKeyUp); - } - - // - // Listeners - - onOrganizePress = () => { - this.setState({ isOrganizeModalOpen: true }); - }; - - onOrganizeModalClose = () => { - this.setState({ isOrganizeModalOpen: false }); - }; - - onInteractiveImportPress = () => { - this.setState({ isInteractiveImportModalOpen: true }); - }; - - onInteractiveImportModalClose = () => { - this.setState({ isInteractiveImportModalOpen: false }); - }; - - onEditMoviePress = () => { - this.setState({ isEditMovieModalOpen: true }); - }; - - onEditMovieModalClose = () => { - this.setState({ isEditMovieModalOpen: false }); - }; - - onInteractiveSearchPress = () => { - this.setState({ isInteractiveSearchModalOpen: true }); - }; - - onInteractiveSearchModalClose = () => { - this.setState({ isInteractiveSearchModalOpen: false }); - }; - - onDeleteMoviePress = () => { - this.setState({ - isEditMovieModalOpen: false, - isDeleteMovieModalOpen: true - }); - }; - - onDeleteMovieModalClose = () => { - this.setState({ isDeleteMovieModalOpen: false }); - }; - - onMovieHistoryPress = () => { - this.setState({ isMovieHistoryModalOpen: true }); - }; - - onMovieHistoryModalClose = () => { - this.setState({ isMovieHistoryModalOpen: false }); - }; - - onMeasure = ({ height }) => { - this.setState({ overviewHeight: height }); - }; - - onTitleMeasure = ({ width }) => { - this.setState({ titleWidth: width }); - }; - - onKeyUp = (event) => { - if (event.composedPath && event.composedPath().length === 4) { - if (event.keyCode === keyCodes.LEFT_ARROW) { - this.props.onGoToMovie(this.props.previousMovie.titleSlug); - } - if (event.keyCode === keyCodes.RIGHT_ARROW) { - this.props.onGoToMovie(this.props.nextMovie.titleSlug); - } - } - }; - - onTouchStart = (event) => { - const touches = event.touches; - const touchStart = touches[0].pageX; - const touchY = touches[0].pageY; - - // Only change when swipe is on header, we need horizontal scroll on tables - if (touchY > 470) { - return; - } - - if (touches.length !== 1) { - return; - } - - if ( - touchStart < 50 || - this.props.isSidebarVisible || - this.state.isOrganizeModalOpen || - this.state.isEditMovieModalOpen || - this.state.isDeleteMovieModalOpen || - this.state.isInteractiveImportModalOpen || - this.state.isInteractiveSearchModalOpen || - this.state.isMovieHistoryModalOpen - ) { - return; - } - - this._touchStart = touchStart; - }; - - onTouchEnd = (event) => { - const touches = event.changedTouches; - const currentTouch = touches[0].pageX; - - if (!this._touchStart) { - return; - } - - if (currentTouch > this._touchStart && currentTouch - this._touchStart > 100) { - this.props.onGoToMovie(this.props.previousMovie.titleSlug); - } else if (currentTouch < this._touchStart && this._touchStart - currentTouch > 100) { - this.props.onGoToMovie(this.props.nextMovie.titleSlug); - } - - this._touchStart = null; - }; - - onTouchCancel = (event) => { - this._touchStart = null; - }; - - onTouchMove = (event) => { - if (!this._touchStart) { - return; - } - }; - - // - // Render - - render() { - const { - id, - tmdbId, - imdbId, - title, - originalTitle, - year, - inCinemas, - physicalRelease, - digitalRelease, - runtime, - certification, - ratings, - path, - statistics, - qualityProfileId, - monitored, - studio, - originalLanguage, - genres, - collection, - overview, - status, - youTubeTrailerId, - isAvailable, - images, - tags, - isSaving, - isRefreshing, - isSearching, - isFetching, - isSmallScreen, - movieFilesError, - movieCreditsError, - extraFilesError, - hasMovieFiles, - previousMovie, - nextMovie, - onMonitorTogglePress, - onRefreshPress, - onSearchPress, - queueItem, - movieRuntimeFormat - } = this.props; - - const { - sizeOnDisk = 0 - } = statistics; - - const { - isOrganizeModalOpen, - isEditMovieModalOpen, - isDeleteMovieModalOpen, - isInteractiveImportModalOpen, - isInteractiveSearchModalOpen, - isMovieHistoryModalOpen, - overviewHeight, - titleWidth - } = this.state; - - const statusDetails = getMovieStatusDetails(status); - - const fanartUrl = getFanartUrl(images); - const marqueeWidth = isSmallScreen ? titleWidth : (titleWidth - 150); - - const titleWithYear = `${title}${year > 0 ? ` (${year})` : ''}`; - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-
-
- -
- - -
- -
-
-
- -
- -
- - - - -
- - - -
- - - -
-
- { - certification ? - - {certification} - : - null - } - - - 0 ? ( - year - ) : ( - - ) - } - title={translate('ReleaseDates')} - body={ - - } - position={tooltipPositions.BOTTOM} - /> - - - { - runtime ? - - {formatRuntime(runtime, movieRuntimeFormat)} - : - null - } - - { - - - } - tooltip={ - - } - position={tooltipPositions.BOTTOM} - /> - - } - - { - !!tags.length && - - - } - tooltip={ - - } - position={tooltipPositions.BOTTOM} - /> - - } -
-
- -
- { - ratings.tmdb ? - - - : - null - } - { - ratings.imdb ? - - - : - null - } - { - ratings.rottenTomatoes ? - - - : - null - } - { - ratings.trakt ? - - - : - null - } -
- -
- - - {path} - - - - - - - - - - - - { - - } - - - - - - {formatBytes(sizeOnDisk)} - - - - { - collection ? - -
- -
-
: - null - } - - { - originalLanguage?.name && !isSmallScreen ? - - - {originalLanguage.name} - - : - null - } - - { - studio && !isSmallScreen ? - - - {studio} - - : - null - } - - { - genres.length && !isSmallScreen ? - - - : - null - } -
- - -
- -
-
- - - - -
- { - !isFetching && movieFilesError ? - - {translate('LoadingMovieFilesFailed')} - : - null - } - - { - !isFetching && movieCreditsError ? - - {translate('LoadingMovieCreditsFailed')} - : - null - } - - { - !isFetching && extraFilesError ? - - {translate('LoadingMovieExtraFilesFailed')} - : - null - } - -
- - - -
- -
- -
- -
- -
- -
- -
-
- - - - - - - - - - - - - - - ); - } -} - -MovieDetails.propTypes = { - id: PropTypes.number.isRequired, - tmdbId: PropTypes.number.isRequired, - imdbId: PropTypes.string, - title: PropTypes.string.isRequired, - originalTitle: PropTypes.string, - year: PropTypes.number.isRequired, - runtime: PropTypes.number.isRequired, - certification: PropTypes.string, - ratings: PropTypes.object.isRequired, - path: PropTypes.string.isRequired, - statistics: PropTypes.object.isRequired, - qualityProfileId: PropTypes.number.isRequired, - monitored: PropTypes.bool.isRequired, - status: PropTypes.string.isRequired, - studio: PropTypes.string, - originalLanguage: PropTypes.object, - genres: PropTypes.arrayOf(PropTypes.string).isRequired, - collection: PropTypes.object, - youTubeTrailerId: PropTypes.string, - isAvailable: PropTypes.bool.isRequired, - inCinemas: PropTypes.string, - physicalRelease: PropTypes.string, - digitalRelease: PropTypes.string, - overview: PropTypes.string.isRequired, - images: PropTypes.arrayOf(PropTypes.object).isRequired, - alternateTitles: PropTypes.arrayOf(PropTypes.string).isRequired, - tags: PropTypes.arrayOf(PropTypes.number).isRequired, - isSaving: PropTypes.bool.isRequired, - isRefreshing: PropTypes.bool.isRequired, - isSearching: PropTypes.bool.isRequired, - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - isSmallScreen: PropTypes.bool.isRequired, - isSidebarVisible: PropTypes.bool.isRequired, - movieFilesError: PropTypes.object, - movieCreditsError: PropTypes.object, - extraFilesError: PropTypes.object, - hasMovieFiles: PropTypes.bool.isRequired, - previousMovie: PropTypes.object.isRequired, - nextMovie: PropTypes.object.isRequired, - onMonitorTogglePress: PropTypes.func.isRequired, - onRefreshPress: PropTypes.func.isRequired, - onSearchPress: PropTypes.func.isRequired, - onGoToMovie: PropTypes.func.isRequired, - queueItem: PropTypes.object, - movieRuntimeFormat: PropTypes.string.isRequired -}; - -MovieDetails.defaultProps = { - genres: [], - statistics: {}, - tags: [], - isSaving: false -}; - -export default MovieDetails; diff --git a/frontend/src/Movie/Details/MovieDetails.tsx b/frontend/src/Movie/Details/MovieDetails.tsx new file mode 100644 index 0000000000..c1b615670f --- /dev/null +++ b/frontend/src/Movie/Details/MovieDetails.tsx @@ -0,0 +1,956 @@ +import React, { + useCallback, + useEffect, + useMemo, + useRef, + useState, +} from 'react'; +import { useDispatch, useSelector } from 'react-redux'; +import { useHistory } from 'react-router'; +import TextTruncate from 'react-text-truncate'; +import { createSelector } from 'reselect'; +import AppState from 'App/State/AppState'; +import * as commandNames from 'Commands/commandNames'; +import Alert from 'Components/Alert'; +import FieldSet from 'Components/FieldSet'; +import Icon from 'Components/Icon'; +import ImdbRating from 'Components/ImdbRating'; +import InfoLabel from 'Components/InfoLabel'; +import IconButton from 'Components/Link/IconButton'; +import Marquee from 'Components/Marquee'; +import MonitorToggleButton from 'Components/MonitorToggleButton'; +import PageContent from 'Components/Page/PageContent'; +import PageContentBody from 'Components/Page/PageContentBody'; +import PageToolbar from 'Components/Page/Toolbar/PageToolbar'; +import PageToolbarButton from 'Components/Page/Toolbar/PageToolbarButton'; +import PageToolbarSection from 'Components/Page/Toolbar/PageToolbarSection'; +import PageToolbarSeparator from 'Components/Page/Toolbar/PageToolbarSeparator'; +import RottenTomatoRating from 'Components/RottenTomatoRating'; +import TmdbRating from 'Components/TmdbRating'; +import Popover from 'Components/Tooltip/Popover'; +import Tooltip from 'Components/Tooltip/Tooltip'; +import TraktRating from 'Components/TraktRating'; +import useMeasure from 'Helpers/Hooks/useMeasure'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import { + icons, + kinds, + sizes, + sortDirections, + tooltipPositions, +} from 'Helpers/Props'; +import InteractiveImportModal from 'InteractiveImport/InteractiveImportModal'; +import DeleteMovieModal from 'Movie/Delete/DeleteMovieModal'; +import EditMovieModal from 'Movie/Edit/EditMovieModal'; +import getMovieStatusDetails from 'Movie/getMovieStatusDetails'; +import MovieHistoryModal from 'Movie/History/MovieHistoryModal'; +import { Image, Statistics } from 'Movie/Movie'; +import MovieCollectionLabel from 'Movie/MovieCollectionLabel'; +import MovieGenres from 'Movie/MovieGenres'; +import MoviePoster from 'Movie/MoviePoster'; +import MovieInteractiveSearchModal from 'Movie/Search/MovieInteractiveSearchModal'; +import MovieFileEditorTable from 'MovieFile/Editor/MovieFileEditorTable'; +import ExtraFileTable from 'MovieFile/Extras/ExtraFileTable'; +import OrganizePreviewModal from 'Organize/OrganizePreviewModal'; +import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector'; +import { executeCommand } from 'Store/Actions/commandActions'; +import { + clearExtraFiles, + fetchExtraFiles, +} from 'Store/Actions/extraFileActions'; +import { toggleMovieMonitored } from 'Store/Actions/movieActions'; +import { + clearMovieCredits, + fetchMovieCredits, +} from 'Store/Actions/movieCreditsActions'; +import { + clearMovieFiles, + fetchMovieFiles, +} from 'Store/Actions/movieFileActions'; +import { + clearQueueDetails, + fetchQueueDetails, +} from 'Store/Actions/queueActions'; +import { fetchRootFolders } from 'Store/Actions/rootFolderActions'; +import { fetchImportListSchema } from 'Store/Actions/Settings/importLists'; +import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector'; +import createCommandsSelector from 'Store/Selectors/createCommandsSelector'; +import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; +import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector'; +import fonts from 'Styles/Variables/fonts'; +import sortByProp from 'Utilities/Array/sortByProp'; +import { findCommand, isCommandExecuting } from 'Utilities/Command'; +import formatRuntime from 'Utilities/Date/formatRuntime'; +import getPathWithUrlBase from 'Utilities/getPathWithUrlBase'; +import formatBytes from 'Utilities/Number/formatBytes'; +import { + registerPagePopulator, + unregisterPagePopulator, +} from 'Utilities/pagePopulator'; +import translate from 'Utilities/String/translate'; +import MovieCastPosters from './Credits/Cast/MovieCastPosters'; +import MovieCrewPosters from './Credits/Crew/MovieCrewPosters'; +import MovieDetailsLinks from './MovieDetailsLinks'; +import MovieReleaseDates from './MovieReleaseDates'; +import MovieStatusLabel from './MovieStatusLabel'; +import MovieTags from './MovieTags'; +import MovieTitlesTable from './Titles/MovieTitlesTable'; +import styles from './MovieDetails.css'; + +const defaultFontSize = parseInt(fonts.defaultFontSize); +const lineHeight = parseFloat(fonts.lineHeight); + +function getFanartUrl(images: Image[]) { + const image = images.find((image) => image.coverType === 'fanart'); + return image?.url ?? image?.remoteUrl; +} + +function createMovieFilesSelector() { + return createSelector( + (state: AppState) => state.movieFiles, + ({ items, isFetching, isPopulated, error }) => { + const hasMovieFiles = !!items.length; + + return { + isMovieFilesFetching: isFetching, + isMovieFilesPopulated: isPopulated, + movieFilesError: error, + hasMovieFiles, + }; + } + ); +} + +function createExtraFilesSelector() { + return createSelector( + (state: AppState) => state.extraFiles, + ({ isFetching, isPopulated, error }) => { + return { + isExtraFilesFetching: isFetching, + isExtraFilesPopulated: isPopulated, + extraFilesError: error, + }; + } + ); +} + +function createMovieCreditsSelector() { + return createSelector( + (state: AppState) => state.movieCredits, + ({ isFetching, isPopulated, error }) => { + return { + isMovieCreditsFetching: isFetching, + isMovieCreditsPopulated: isPopulated, + movieCreditsError: error, + }; + } + ); +} + +function createMovieSelector(movieId: number) { + return createSelector(createAllMoviesSelector(), (allMovies) => { + const sortedMovies = [...allMovies].sort(sortByProp('sortTitle')); + const movieIndex = sortedMovies.findIndex((movie) => movie.id === movieId); + + if (movieIndex === -1) { + return { + movie: undefined, + nextMovie: undefined, + previousMovie: undefined, + }; + } + + const movie = sortedMovies[movieIndex]; + const nextMovie = sortedMovies[movieIndex + 1] ?? sortedMovies[0]; + const previousMovie = + sortedMovies[movieIndex - 1] ?? sortedMovies[sortedMovies.length - 1]; + + return { + movie, + nextMovie: { + title: nextMovie.title, + titleSlug: nextMovie.titleSlug, + }, + previousMovie: { + title: previousMovie.title, + titleSlug: previousMovie.titleSlug, + }, + }; + }); +} + +interface MovieDetailsProps { + movieId: number; +} + +function MovieDetails({ movieId }: MovieDetailsProps) { + const dispatch = useDispatch(); + const history = useHistory(); + + const { movie, nextMovie, previousMovie } = useSelector( + createMovieSelector(movieId) + ); + const { isMovieFilesFetching, movieFilesError, hasMovieFiles } = useSelector( + createMovieFilesSelector() + ); + const { isExtraFilesFetching, extraFilesError } = useSelector( + createExtraFilesSelector() + ); + const { isMovieCreditsFetching, movieCreditsError } = useSelector( + createMovieCreditsSelector() + ); + const { movieRuntimeFormat } = useSelector(createUISettingsSelector()); + const isSidebarVisible = useSelector( + (state: AppState) => state.app.isSidebarVisible + ); + const { isSmallScreen } = useSelector(createDimensionsSelector()); + + const commands = useSelector(createCommandsSelector()); + const isSaving = useSelector((state: AppState) => state.movies.isSaving); + + const { isRefreshing, isRenaming, isSearching } = useMemo(() => { + const movieRefreshingCommand = findCommand(commands, { + name: commandNames.REFRESH_MOVIE, + }); + + const isMovieRefreshingCommandExecuting = isCommandExecuting( + movieRefreshingCommand + ); + + const allMoviesRefreshing = + isMovieRefreshingCommandExecuting && + !movieRefreshingCommand?.body.movieIds?.length; + + const isMovieRefreshing = + isMovieRefreshingCommandExecuting && + movieRefreshingCommand?.body.movieIds?.includes(movieId); + + const isSearchingExecuting = isCommandExecuting( + findCommand(commands, { + name: commandNames.MOVIE_SEARCH, + movieIds: [movieId], + }) + ); + + const isRenamingFiles = isCommandExecuting( + findCommand(commands, { + name: commandNames.RENAME_FILES, + movieId, + }) + ); + + const isRenamingMovieCommand = findCommand(commands, { + name: commandNames.RENAME_MOVIE, + }); + + const isRenamingMovie = + isCommandExecuting(isRenamingMovieCommand) && + isRenamingMovieCommand?.body?.movieIds?.includes(movieId); + + return { + isRefreshing: isMovieRefreshing || allMoviesRefreshing, + isRenaming: isRenamingFiles || isRenamingMovie, + isSearching: isSearchingExecuting, + }; + }, [movieId, commands]); + + const touchStart = useRef(null); + const [isOrganizeModalOpen, setIsOrganizeModalOpen] = useState(false); + const [isManageMoviesModalOpen, setIsManageMoviesModalOpen] = useState(false); + const [isInteractiveSearchModalOpen, setIsInteractiveSearchModalOpen] = + useState(false); + const [isEditMovieModalOpen, setIsEditMovieModalOpen] = useState(false); + const [isDeleteMovieModalOpen, setIsDeleteMovieModalOpen] = useState(false); + const [isMovieHistoryModalOpen, setIsMovieHistoryModalOpen] = useState(false); + const [titleRef, { width: titleWidth }] = useMeasure(); + const [overviewRef, { height: overviewHeight }] = useMeasure(); + const wasRefreshing = usePrevious(isRefreshing); + const wasRenaming = usePrevious(isRenaming); + + const handleOrganizePress = useCallback(() => { + setIsOrganizeModalOpen(true); + }, []); + + const handleOrganizeModalClose = useCallback(() => { + setIsOrganizeModalOpen(false); + }, []); + + const handleManageMoviesPress = useCallback(() => { + setIsManageMoviesModalOpen(true); + }, []); + + const handleManageMoviesModalClose = useCallback(() => { + setIsManageMoviesModalOpen(false); + }, []); + + const handleInteractiveSearchPress = useCallback(() => { + setIsInteractiveSearchModalOpen(true); + }, []); + + const handleInteractiveSearchModalClose = useCallback(() => { + setIsInteractiveSearchModalOpen(false); + }, []); + + const handleEditMoviePress = useCallback(() => { + setIsEditMovieModalOpen(true); + }, []); + + const handleEditMovieModalClose = useCallback(() => { + setIsEditMovieModalOpen(false); + }, []); + + const handleDeleteMoviePress = useCallback(() => { + setIsEditMovieModalOpen(false); + setIsDeleteMovieModalOpen(true); + }, []); + + const handleDeleteMovieModalClose = useCallback(() => { + setIsDeleteMovieModalOpen(false); + }, []); + + const handleMovieHistoryPress = useCallback(() => { + setIsMovieHistoryModalOpen(true); + }, []); + + const handleMovieHistoryModalClose = useCallback(() => { + setIsMovieHistoryModalOpen(false); + }, []); + + const handleMonitorTogglePress = useCallback( + (value: boolean) => { + dispatch( + toggleMovieMonitored({ + movieId, + monitored: value, + }) + ); + }, + [movieId, dispatch] + ); + + const handleRefreshPress = useCallback(() => { + dispatch( + executeCommand({ + name: commandNames.REFRESH_MOVIE, + movieIds: [movieId], + }) + ); + }, [movieId, dispatch]); + + const handleSearchPress = useCallback(() => { + dispatch( + executeCommand({ + name: commandNames.MOVIE_SEARCH, + movieIds: [movieId], + }) + ); + }, [movieId, dispatch]); + + const handleTouchStart = useCallback( + (event: TouchEvent) => { + const touches = event.touches; + const currentTouch = touches[0].pageX; + const touchY = touches[0].pageY; + + // Only change when swipe is on header, we need horizontal scroll on tables + if (touchY > 470) { + return; + } + + if (touches.length !== 1) { + return; + } + + if ( + currentTouch < 50 || + isSidebarVisible || + isOrganizeModalOpen || + isEditMovieModalOpen || + isDeleteMovieModalOpen || + isManageMoviesModalOpen || + isInteractiveSearchModalOpen || + isMovieHistoryModalOpen + ) { + return; + } + + touchStart.current = currentTouch; + }, + [ + isSidebarVisible, + isOrganizeModalOpen, + isEditMovieModalOpen, + isDeleteMovieModalOpen, + isManageMoviesModalOpen, + isInteractiveSearchModalOpen, + isMovieHistoryModalOpen, + ] + ); + + const handleTouchEnd = useCallback( + (event: TouchEvent) => { + const touches = event.changedTouches; + const currentTouch = touches[0].pageX; + + if (!touchStart.current) { + return; + } + + if ( + currentTouch > touchStart.current && + currentTouch - touchStart.current > 100 && + previousMovie !== undefined + ) { + history.push(getPathWithUrlBase(`/movie/${previousMovie.titleSlug}`)); + } else if ( + currentTouch < touchStart.current && + touchStart.current - currentTouch > 100 && + nextMovie !== undefined + ) { + history.push(getPathWithUrlBase(`/movie/${nextMovie.titleSlug}`)); + } + + touchStart.current = null; + }, + [previousMovie, nextMovie, history] + ); + + const handleTouchCancel = useCallback(() => { + touchStart.current = null; + }, []); + + const handleTouchMove = useCallback(() => { + if (!touchStart.current) { + return; + } + }, []); + + const handleKeyUp = useCallback( + (event: KeyboardEvent) => { + if (event.composedPath && event.composedPath().length === 4) { + if (event.key === 'ArrowLeft' && previousMovie !== undefined) { + history.push(getPathWithUrlBase(`/movie/${previousMovie.titleSlug}`)); + } + + if (event.key === 'ArrowRight' && nextMovie !== undefined) { + history.push(getPathWithUrlBase(`/movie/${nextMovie.titleSlug}`)); + } + } + }, + [previousMovie, nextMovie, history] + ); + + const populate = useCallback(() => { + dispatch(fetchMovieFiles({ movieId })); + dispatch(fetchExtraFiles({ movieId })); + dispatch(fetchMovieCredits({ movieId })); + dispatch(fetchQueueDetails({ movieId })); + dispatch(fetchImportListSchema()); + dispatch(fetchRootFolders()); + }, [movieId, dispatch]); + + useEffect(() => { + populate(); + }, [populate]); + + useEffect(() => { + registerPagePopulator(populate, ['movieUpdated']); + + return () => { + unregisterPagePopulator(populate); + dispatch(clearMovieFiles()); + dispatch(clearExtraFiles()); + dispatch(clearMovieCredits()); + dispatch(clearQueueDetails()); + }; + }, [populate, dispatch]); + + useEffect(() => { + if ((!isRefreshing && wasRefreshing) || (!isRenaming && wasRenaming)) { + populate(); + } + }, [isRefreshing, wasRefreshing, isRenaming, wasRenaming, populate]); + + useEffect(() => { + window.addEventListener('touchstart', handleTouchStart); + window.addEventListener('touchend', handleTouchEnd); + window.addEventListener('touchcancel', handleTouchCancel); + window.addEventListener('touchmove', handleTouchMove); + window.addEventListener('keyup', handleKeyUp); + + return () => { + window.removeEventListener('touchstart', handleTouchStart); + window.removeEventListener('touchend', handleTouchEnd); + window.removeEventListener('touchcancel', handleTouchCancel); + window.removeEventListener('touchmove', handleTouchMove); + window.removeEventListener('keyup', handleKeyUp); + }; + }, [ + handleTouchStart, + handleTouchEnd, + handleTouchCancel, + handleTouchMove, + handleKeyUp, + ]); + + if (!movie) { + return null; + } + + const { + id, + tmdbId, + imdbId, + title, + originalTitle, + year, + inCinemas, + physicalRelease, + digitalRelease, + runtime, + certification, + ratings, + path, + statistics = {} as Statistics, + qualityProfileId, + monitored, + studio, + originalLanguage, + genres = [], + collection, + overview, + status, + youTubeTrailerId, + isAvailable, + images, + tags, + } = movie; + + const { sizeOnDisk = 0 } = statistics; + + const statusDetails = getMovieStatusDetails(status); + + const fanartUrl = getFanartUrl(images); + const isFetching = + isMovieFilesFetching || isExtraFilesFetching || isMovieCreditsFetching; + + const marqueeWidth = isSmallScreen ? titleWidth : titleWidth - 150; + + const titleWithYear = `${title}${year > 0 ? ` (${year})` : ''}`; + + return ( + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+
+
+ +
+ + +
+
+
+
+ +
+ +
+ + + + +
+ + + +
+ + +
+
+ {certification ? ( + + {certification} + + ) : null} + + + 0 ? ( + year + ) : ( + + ) + } + title={translate('ReleaseDates')} + body={ + + } + position={tooltipPositions.BOTTOM} + /> + + + {runtime ? ( + + {formatRuntime(runtime, movieRuntimeFormat)} + + ) : null} + + + } + tooltip={ + + } + position={tooltipPositions.BOTTOM} + /> + + + {!!tags.length && ( + + } + tooltip={} + position={tooltipPositions.BOTTOM} + /> + + )} +
+
+ +
+ {ratings.tmdb ? ( + + + + ) : null} + {ratings.imdb ? ( + + + + ) : null} + {ratings.rottenTomatoes ? ( + + + + ) : null} + {ratings.trakt ? ( + + + + ) : null} +
+ +
+ + {path} + + + + + + + + + + + + + + + + + {formatBytes(sizeOnDisk)} + + + + {collection ? ( + +
+ +
+
+ ) : null} + + {originalLanguage?.name && !isSmallScreen ? ( + + + {originalLanguage.name} + + + ) : null} + + {studio && !isSmallScreen ? ( + + {studio} + + ) : null} + + {genres.length && !isSmallScreen ? ( + + + + ) : null} +
+ +
+ +
+ + + + +
+ {!isFetching && movieFilesError ? ( + + {translate('LoadingMovieFilesFailed')} + + ) : null} + + {!isFetching && extraFilesError ? ( + + {translate('LoadingMovieExtraFilesFailed')} + + ) : null} + + {!isFetching && movieCreditsError ? ( + + {translate('LoadingMovieCreditsFailed')} + + ) : null} + +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ +
+
+ + + + + + + + + + + + + + + ); +} + +export default MovieDetails; diff --git a/frontend/src/Movie/Details/MovieDetailsConnector.js b/frontend/src/Movie/Details/MovieDetailsConnector.js deleted file mode 100644 index a3af095f9b..0000000000 --- a/frontend/src/Movie/Details/MovieDetailsConnector.js +++ /dev/null @@ -1,334 +0,0 @@ -import { push } from 'connected-react-router'; -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import * as commandNames from 'Commands/commandNames'; -import { executeCommand } from 'Store/Actions/commandActions'; -import { clearExtraFiles, fetchExtraFiles } from 'Store/Actions/extraFileActions'; -import { toggleMovieMonitored } from 'Store/Actions/movieActions'; -import { clearMovieCredits, fetchMovieCredits } from 'Store/Actions/movieCreditsActions'; -import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions'; -import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions'; -import { fetchImportListSchema } from 'Store/Actions/settingsActions'; -import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector'; -import createCommandsSelector from 'Store/Selectors/createCommandsSelector'; -import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector'; -import { findCommand, isCommandExecuting } from 'Utilities/Command'; -import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator'; -import MovieDetails from './MovieDetails'; - -const selectMovieFiles = createSelector( - (state) => state.movieFiles, - (movieFiles) => { - const { - items, - isFetching, - isPopulated, - error - } = movieFiles; - - const hasMovieFiles = !!items.length; - - return { - isMovieFilesFetching: isFetching, - isMovieFilesPopulated: isPopulated, - movieFilesError: error, - hasMovieFiles - }; - } -); - -const selectMovieCredits = createSelector( - (state) => state.movieCredits, - (movieCredits) => { - const { - isFetching, - isPopulated, - error - } = movieCredits; - - return { - isMovieCreditsFetching: isFetching, - isMovieCreditsPopulated: isPopulated, - movieCreditsError: error - }; - } -); - -const selectExtraFiles = createSelector( - (state) => state.extraFiles, - (extraFiles) => { - const { - isFetching, - isPopulated, - error - } = extraFiles; - - return { - isExtraFilesFetching: isFetching, - isExtraFilesPopulated: isPopulated, - extraFilesError: error - }; - } -); - -function createMapStateToProps() { - return createSelector( - (state, { titleSlug }) => titleSlug, - selectMovieFiles, - selectMovieCredits, - selectExtraFiles, - createAllMoviesSelector(), - createCommandsSelector(), - createDimensionsSelector(), - (state) => state.queue.details.items, - (state) => state.app.isSidebarVisible, - (state) => state.settings.ui.item.movieRuntimeFormat, - (titleSlug, movieFiles, movieCredits, extraFiles, allMovies, commands, dimensions, queueItems, isSidebarVisible, movieRuntimeFormat) => { - const sortedMovies = _.orderBy(allMovies, 'sortTitle'); - const movieIndex = _.findIndex(sortedMovies, { titleSlug }); - const movie = sortedMovies[movieIndex]; - - if (!movie) { - return {}; - } - - const { - isMovieFilesFetching, - isMovieFilesPopulated, - movieFilesError, - hasMovieFiles - } = movieFiles; - - const { - isMovieCreditsFetching, - isMovieCreditsPopulated, - movieCreditsError - } = movieCredits; - - const { - isExtraFilesFetching, - isExtraFilesPopulated, - extraFilesError - } = extraFiles; - - const previousMovie = sortedMovies[movieIndex - 1] || _.last(sortedMovies); - const nextMovie = sortedMovies[movieIndex + 1] || _.first(sortedMovies); - const isMovieRefreshing = isCommandExecuting(findCommand(commands, { name: commandNames.REFRESH_MOVIE, movieIds: [movie.id] })); - const movieRefreshingCommand = findCommand(commands, { name: commandNames.REFRESH_MOVIE }); - const allMoviesRefreshing = ( - isCommandExecuting(movieRefreshingCommand) && - !movieRefreshingCommand.body.movieId - ); - const isRefreshing = isMovieRefreshing || allMoviesRefreshing; - const isSearching = isCommandExecuting(findCommand(commands, { name: commandNames.MOVIE_SEARCH, movieIds: [movie.id] })); - const isRenamingFiles = isCommandExecuting(findCommand(commands, { name: commandNames.RENAME_FILES, movieId: movie.id })); - const isRenamingMovieCommand = findCommand(commands, { name: commandNames.RENAME_MOVIE }); - const isRenamingMovie = ( - isCommandExecuting(isRenamingMovieCommand) && - isRenamingMovieCommand.body.movieIds.indexOf(movie.id) > -1 - ); - - const isFetching = isMovieFilesFetching || isMovieCreditsFetching || isExtraFilesFetching; - const isPopulated = isMovieFilesPopulated && isMovieCreditsPopulated && isExtraFilesPopulated; - const alternateTitles = _.reduce(movie.alternateTitles, (acc, alternateTitle) => { - acc.push(alternateTitle.title); - return acc; - }, []); - - const queueItem = queueItems.find((item) => item.movieId === movie.id); - - return { - ...movie, - alternateTitles, - isMovieRefreshing, - allMoviesRefreshing, - isRefreshing, - isSearching, - isRenamingFiles, - isRenamingMovie, - isFetching, - isPopulated, - movieFilesError, - movieCreditsError, - extraFilesError, - hasMovieFiles, - previousMovie, - nextMovie, - isSmallScreen: dimensions.isSmallScreen, - isSidebarVisible, - queueItem, - movieRuntimeFormat - }; - } - ); -} - -function createMapDispatchToProps(dispatch, props) { - return { - dispatchFetchMovieFiles({ movieId }) { - dispatch(fetchMovieFiles({ movieId })); - }, - dispatchClearMovieFiles() { - dispatch(clearMovieFiles()); - }, - dispatchFetchMovieCredits({ movieId }) { - dispatch(fetchMovieCredits({ movieId })); - }, - dispatchClearMovieCredits() { - dispatch(clearMovieCredits()); - }, - dispatchFetchExtraFiles({ movieId }) { - dispatch(fetchExtraFiles({ movieId })); - }, - dispatchClearExtraFiles() { - dispatch(clearExtraFiles()); - }, - dispatchFetchQueueDetails({ movieId }) { - dispatch(fetchQueueDetails({ movieId })); - }, - dispatchClearQueueDetails() { - dispatch(clearQueueDetails()); - }, - dispatchFetchImportListSchema() { - dispatch(fetchImportListSchema()); - }, - dispatchToggleMovieMonitored(payload) { - dispatch(toggleMovieMonitored(payload)); - }, - dispatchExecuteCommand(payload) { - dispatch(executeCommand(payload)); - }, - onGoToMovie(titleSlug) { - dispatch(push(`${window.Radarr.urlBase}/movie/${titleSlug}`)); - } - }; -} - -class MovieDetailsConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - registerPagePopulator(this.populate, ['movieUpdated']); - this.populate(); - } - - componentDidUpdate(prevProps) { - const { - id, - isMovieRefreshing, - allMoviesRefreshing, - isRenamingFiles, - isRenamingMovie - } = this.props; - - if ( - (prevProps.isMovieRefreshing && !isMovieRefreshing) || - (prevProps.allMoviesRefreshing && !allMoviesRefreshing) || - (prevProps.isRenamingFiles && !isRenamingFiles) || - (prevProps.isRenamingMovie && !isRenamingMovie) - ) { - this.populate(); - } - - // If the id has changed we need to clear the episodes/episode - // files and fetch from the server. - - if (prevProps.id !== id) { - this.unpopulate(); - this.populate(); - } - } - - componentWillUnmount() { - unregisterPagePopulator(this.populate); - this.unpopulate(); - } - - // - // Control - - populate = () => { - const movieId = this.props.id; - - this.props.dispatchFetchMovieFiles({ movieId }); - this.props.dispatchFetchExtraFiles({ movieId }); - this.props.dispatchFetchMovieCredits({ movieId }); - this.props.dispatchFetchQueueDetails({ movieId }); - this.props.dispatchFetchImportListSchema(); - }; - - unpopulate = () => { - this.props.dispatchClearMovieFiles(); - this.props.dispatchClearExtraFiles(); - this.props.dispatchClearMovieCredits(); - this.props.dispatchClearQueueDetails(); - }; - - // - // Listeners - - onMonitorTogglePress = (monitored) => { - this.props.dispatchToggleMovieMonitored({ - movieId: this.props.id, - monitored - }); - }; - - onRefreshPress = () => { - this.props.dispatchExecuteCommand({ - name: commandNames.REFRESH_MOVIE, - movieIds: [this.props.id] - }); - }; - - onSearchPress = () => { - this.props.dispatchExecuteCommand({ - name: commandNames.MOVIE_SEARCH, - movieIds: [this.props.id] - }); - }; - - // - // Render - - render() { - return ( - - ); - } -} - -MovieDetailsConnector.propTypes = { - id: PropTypes.number.isRequired, - titleSlug: PropTypes.string.isRequired, - isMovieRefreshing: PropTypes.bool.isRequired, - allMoviesRefreshing: PropTypes.bool.isRequired, - isRefreshing: PropTypes.bool.isRequired, - isRenamingFiles: PropTypes.bool.isRequired, - isRenamingMovie: PropTypes.bool.isRequired, - isSmallScreen: PropTypes.bool.isRequired, - dispatchFetchMovieFiles: PropTypes.func.isRequired, - dispatchClearMovieFiles: PropTypes.func.isRequired, - dispatchFetchExtraFiles: PropTypes.func.isRequired, - dispatchClearExtraFiles: PropTypes.func.isRequired, - dispatchFetchMovieCredits: PropTypes.func.isRequired, - dispatchClearMovieCredits: PropTypes.func.isRequired, - dispatchToggleMovieMonitored: PropTypes.func.isRequired, - dispatchFetchQueueDetails: PropTypes.func.isRequired, - dispatchClearQueueDetails: PropTypes.func.isRequired, - dispatchFetchImportListSchema: PropTypes.func.isRequired, - dispatchExecuteCommand: PropTypes.func.isRequired, - onGoToMovie: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, createMapDispatchToProps)(MovieDetailsConnector); diff --git a/frontend/src/Movie/Details/MovieDetailsPage.tsx b/frontend/src/Movie/Details/MovieDetailsPage.tsx new file mode 100644 index 0000000000..acfea2ab27 --- /dev/null +++ b/frontend/src/Movie/Details/MovieDetailsPage.tsx @@ -0,0 +1,39 @@ +import React, { useEffect } from 'react'; +import { useSelector } from 'react-redux'; +import { useParams } from 'react-router'; +import { useHistory } from 'react-router-dom'; +import NotFound from 'Components/NotFound'; +import usePrevious from 'Helpers/Hooks/usePrevious'; +import createAllMoviesSelector from 'Store/Selectors/createAllMoviesSelector'; +import translate from 'Utilities/String/translate'; +import MovieDetails from './MovieDetails'; + +function MovieDetailsPage() { + const allMovies = useSelector(createAllMoviesSelector()); + const { titleSlug } = useParams<{ titleSlug: string }>(); + const history = useHistory(); + + const movieIndex = allMovies.findIndex( + (movie) => movie.titleSlug === titleSlug + ); + + const previousIndex = usePrevious(movieIndex); + + useEffect(() => { + if ( + movieIndex === -1 && + previousIndex !== -1 && + previousIndex !== undefined + ) { + history.push(`${window.Radarr.urlBase}/`); + } + }, [movieIndex, previousIndex, history]); + + if (movieIndex === -1) { + return ; + } + + return ; +} + +export default MovieDetailsPage; diff --git a/frontend/src/Movie/Details/MovieDetailsPageConnector.js b/frontend/src/Movie/Details/MovieDetailsPageConnector.js deleted file mode 100644 index e324031876..0000000000 --- a/frontend/src/Movie/Details/MovieDetailsPageConnector.js +++ /dev/null @@ -1,125 +0,0 @@ -import { push } from 'connected-react-router'; -import _ from 'lodash'; -import PropTypes from 'prop-types'; -import React, { Component } from 'react'; -import { connect } from 'react-redux'; -import { createSelector } from 'reselect'; -import LoadingIndicator from 'Components/Loading/LoadingIndicator'; -import NotFound from 'Components/NotFound'; -import PageContent from 'Components/Page/PageContent'; -import PageContentBody from 'Components/Page/PageContentBody'; -import { fetchRootFolders } from 'Store/Actions/rootFolderActions'; -import getErrorMessage from 'Utilities/Object/getErrorMessage'; -import translate from 'Utilities/String/translate'; -import MovieDetailsConnector from './MovieDetailsConnector'; -import styles from './MovieDetails.css'; - -function createMapStateToProps() { - return createSelector( - (state, { match }) => match, - (state) => state.movies, - (match, movies) => { - const titleSlug = match.params.titleSlug; - const { - isFetching, - isPopulated, - error, - items - } = movies; - - const movieIndex = _.findIndex(items, { titleSlug }); - - if (movieIndex > -1) { - return { - isFetching, - isPopulated, - titleSlug - }; - } - - return { - isFetching, - isPopulated, - error - }; - } - ); -} - -const mapDispatchToProps = { - push, - fetchRootFolders -}; - -class MovieDetailsPageConnector extends Component { - - // - // Lifecycle - - componentDidMount() { - this.props.fetchRootFolders(); - } - - componentDidUpdate(prevProps) { - if (!this.props.titleSlug) { - this.props.push(`${window.Radarr.urlBase}/`); - return; - } - } - - // - // Render - - render() { - const { - titleSlug, - isFetching, - isPopulated, - error - } = this.props; - - if (isFetching && !isPopulated) { - return ( - - - - - - ); - } - - if (!isFetching && !!error) { - return ( -
- {getErrorMessage(error, translate('FailedToLoadMovieFromAPI'))} -
- ); - } - - if (!titleSlug) { - return ( - - ); - } - - return ( - - ); - } -} - -MovieDetailsPageConnector.propTypes = { - titleSlug: PropTypes.string, - isFetching: PropTypes.bool.isRequired, - isPopulated: PropTypes.bool.isRequired, - error: PropTypes.object, - match: PropTypes.shape({ params: PropTypes.shape({ titleSlug: PropTypes.string.isRequired }).isRequired }).isRequired, - push: PropTypes.func.isRequired, - fetchRootFolders: PropTypes.func.isRequired -}; - -export default connect(createMapStateToProps, mapDispatchToProps)(MovieDetailsPageConnector); diff --git a/frontend/src/Movie/Details/MovieStatusLabel.js b/frontend/src/Movie/Details/MovieStatusLabel.tsx similarity index 60% rename from frontend/src/Movie/Details/MovieStatusLabel.js rename to frontend/src/Movie/Details/MovieStatusLabel.tsx index cde6f1a77e..21aa0e78c7 100644 --- a/frontend/src/Movie/Details/MovieStatusLabel.js +++ b/frontend/src/Movie/Details/MovieStatusLabel.tsx @@ -1,13 +1,23 @@ -import PropTypes from 'prop-types'; import React from 'react'; +import { useSelector } from 'react-redux'; import Label from 'Components/Label'; import { kinds, sizes } from 'Helpers/Props'; +import { Kind } from 'Helpers/Props/kinds'; +import { MovieStatus } from 'Movie/Movie'; +import { createQueueItemSelectorForHook } from 'Store/Selectors/createQueueItemSelector'; +import Queue from 'typings/Queue'; import getQueueStatusText from 'Utilities/Movie/getQueueStatusText'; import firstCharToUpper from 'Utilities/String/firstCharToUpper'; import translate from 'Utilities/String/translate'; import styles from './MovieStatusLabel.css'; -function getMovieStatus(status, hasFile, isMonitored, isAvailable, queueItem = false) { +function getMovieStatus( + status: MovieStatus, + isMonitored: boolean, + isAvailable: boolean, + hasFiles: boolean, + queueItem: Queue | null = null +) { if (queueItem) { const queueStatus = queueItem.status; const queueState = queueItem.trackedDownloadStatus; @@ -18,11 +28,11 @@ function getMovieStatus(status, hasFile, isMonitored, isAvailable, queueItem = f } } - if (hasFile && !isMonitored) { + if (hasFiles && !isMonitored) { return 'availNotMonitored'; } - if (hasFile) { + if (hasFiles) { return 'ended'; } @@ -30,34 +40,52 @@ function getMovieStatus(status, hasFile, isMonitored, isAvailable, queueItem = f return 'deleted'; } - if (isAvailable && !isMonitored && !hasFile) { + if (isAvailable && !isMonitored && !hasFiles) { return 'missingUnmonitored'; } - if (isAvailable && !hasFile) { + if (isAvailable && !hasFiles) { return 'missingMonitored'; } return 'continuing'; } -function MovieStatusLabel(props) { - const { +interface MovieStatusLabelProps { + movieId: number; + monitored: boolean; + isAvailable: boolean; + hasMovieFiles: boolean; + status: MovieStatus; + useLabel?: boolean; +} + +function MovieStatusLabel({ + movieId, + monitored, + isAvailable, + hasMovieFiles, + status, + useLabel = false, +}: MovieStatusLabelProps) { + const queueItem = useSelector(createQueueItemSelectorForHook(movieId)); + + let movieStatus = getMovieStatus( status, - hasMovieFiles, monitored, isAvailable, - queueItem, - useLabel, - colorImpairedMode - } = props; + hasMovieFiles, + queueItem + ); - let movieStatus = getMovieStatus(status, hasMovieFiles, monitored, isAvailable, queueItem); let statusClass = movieStatus; if (movieStatus === 'availNotMonitored' || movieStatus === 'ended') { movieStatus = 'downloaded'; - } else if (movieStatus === 'missingMonitored' || movieStatus === 'missingUnmonitored') { + } else if ( + movieStatus === 'missingMonitored' || + movieStatus === 'missingUnmonitored' + ) { movieStatus = 'missing'; } else if (movieStatus === 'continuing') { movieStatus = 'notAvailable'; @@ -68,7 +96,7 @@ function MovieStatusLabel(props) { } if (useLabel) { - let kind = kinds.SUCCESS; + let kind: Kind = kinds.SUCCESS; switch (statusClass) { case 'queue': @@ -93,11 +121,7 @@ function MovieStatusLabel(props) { } return ( -