qBitrr2 5.8.4__tar.gz → 5.8.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {qbitrr2-5.8.4/qBitrr2.egg-info → qbitrr2-5.8.6}/PKG-INFO +1 -1
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/pyproject.toml +1 -1
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/arss.py +100 -40
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/bundled_data.py +2 -2
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/webui.py +17 -7
- {qbitrr2-5.8.4 → qbitrr2-5.8.6/qBitrr2.egg-info}/PKG-INFO +1 -1
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/setup.cfg +1 -1
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/LICENSE +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/MANIFEST.in +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/README.md +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/config.example.toml +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/__init__.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/auto_update.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/config.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/config_version.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/database.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/db_lock.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/db_recovery.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/env_config.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/errors.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/ffprobe.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/gen_config.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/home_path.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/logger.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/main.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/search_activity_store.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ArrView.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ArrView.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ConfigView.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ConfigView.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/LogsView.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/LogsView.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ProcessesView.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/ProcessesView.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/app.css +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/app.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/app.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/build.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/check-mark.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/close.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/download.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/gear.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/lidarr.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/live-streaming.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/log.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/logo.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/plus.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/process.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/react-select.esm.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/react-select.esm.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/refresh-arrow.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/table.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/table.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/trash.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/up-arrow.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/useInterval.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/useInterval.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/vendor.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/vendor.js.map +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/assets/visibility.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/favicon-16x16.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/favicon-32x32.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/favicon-48x48.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/favicon.ico +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/icon-192.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/icon-512.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/index.html +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/logov2-clean.png +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/logov2-clean.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/manifest.json +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/sw.js +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/static/vite.svg +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/tables.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/utils.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr/versioning.py +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr2.egg-info/SOURCES.txt +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr2.egg-info/dependency_links.txt +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr2.egg-info/entry_points.txt +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr2.egg-info/requires.txt +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/qBitrr2.egg-info/top_level.txt +0 -0
- {qbitrr2-5.8.4 → qbitrr2-5.8.6}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qBitrr2
|
|
3
|
-
Version: 5.8.
|
|
3
|
+
Version: 5.8.6
|
|
4
4
|
Summary: Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration
|
|
5
5
|
Home-page: https://github.com/Feramance/qBitrr
|
|
6
6
|
Author: Feramance
|
|
@@ -28,7 +28,7 @@ target-version = ['py311']
|
|
|
28
28
|
|
|
29
29
|
[tool.poetry]
|
|
30
30
|
name = "pypi-public"
|
|
31
|
-
version = "5.8.
|
|
31
|
+
version = "5.8.6"
|
|
32
32
|
description = "Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration"
|
|
33
33
|
authors = ["Drapersniper", "Feramance"]
|
|
34
34
|
readme = "README.md"
|
|
@@ -1835,7 +1835,10 @@ class Arr:
|
|
|
1835
1835
|
# Create a series entry for searching
|
|
1836
1836
|
series_model = (
|
|
1837
1837
|
self.series_file_model.select()
|
|
1838
|
-
.where(
|
|
1838
|
+
.where(
|
|
1839
|
+
(self.series_file_model.EntryId == series_id)
|
|
1840
|
+
& (self.series_file_model.ArrInstance == self._name)
|
|
1841
|
+
)
|
|
1839
1842
|
.first()
|
|
1840
1843
|
)
|
|
1841
1844
|
if series_model:
|
|
@@ -1885,7 +1888,8 @@ class Arr:
|
|
|
1885
1888
|
self.loop_completed and self.reset_on_completion and self.series_search
|
|
1886
1889
|
): # Only wipe if a loop completed was tagged
|
|
1887
1890
|
self.series_file_model.update(Searched=False, Upgrade=False).where(
|
|
1888
|
-
self.series_file_model.Searched == True
|
|
1891
|
+
(self.series_file_model.Searched == True)
|
|
1892
|
+
& (self.series_file_model.ArrInstance == self._name)
|
|
1889
1893
|
).execute()
|
|
1890
1894
|
while True:
|
|
1891
1895
|
try:
|
|
@@ -1901,7 +1905,8 @@ class Arr:
|
|
|
1901
1905
|
):
|
|
1902
1906
|
continue
|
|
1903
1907
|
self.series_file_model.delete().where(
|
|
1904
|
-
self.series_file_model.EntryId.not_in(ids)
|
|
1908
|
+
(self.series_file_model.EntryId.not_in(ids))
|
|
1909
|
+
& (self.series_file_model.ArrInstance == self._name)
|
|
1905
1910
|
).execute()
|
|
1906
1911
|
self.loop_completed = False
|
|
1907
1912
|
|
|
@@ -1929,7 +1934,9 @@ class Arr:
|
|
|
1929
1934
|
JSONDecodeError,
|
|
1930
1935
|
) as e:
|
|
1931
1936
|
continue
|
|
1932
|
-
self.model_file.delete().where(
|
|
1937
|
+
self.model_file.delete().where(
|
|
1938
|
+
(self.model_file.EntryId.not_in(ids)) & (self.model_file.ArrInstance == self._name)
|
|
1939
|
+
).execute()
|
|
1933
1940
|
self.loop_completed = False
|
|
1934
1941
|
|
|
1935
1942
|
def db_reset__movie_searched_state(self):
|
|
@@ -1939,7 +1946,7 @@ class Arr:
|
|
|
1939
1946
|
self.loop_completed is True and self.reset_on_completion
|
|
1940
1947
|
): # Only wipe if a loop completed was tagged
|
|
1941
1948
|
self.model_file.update(Searched=False, Upgrade=False).where(
|
|
1942
|
-
self.model_file.Searched == True
|
|
1949
|
+
(self.model_file.Searched == True) & (self.model_file.ArrInstance == self._name)
|
|
1943
1950
|
).execute()
|
|
1944
1951
|
while True:
|
|
1945
1952
|
try:
|
|
@@ -1954,7 +1961,9 @@ class Arr:
|
|
|
1954
1961
|
JSONDecodeError,
|
|
1955
1962
|
):
|
|
1956
1963
|
continue
|
|
1957
|
-
self.model_file.delete().where(
|
|
1964
|
+
self.model_file.delete().where(
|
|
1965
|
+
(self.model_file.EntryId.not_in(ids)) & (self.model_file.ArrInstance == self._name)
|
|
1966
|
+
).execute()
|
|
1958
1967
|
self.loop_completed = False
|
|
1959
1968
|
|
|
1960
1969
|
def db_reset__album_searched_state(self):
|
|
@@ -1964,7 +1973,7 @@ class Arr:
|
|
|
1964
1973
|
self.loop_completed is True and self.reset_on_completion
|
|
1965
1974
|
): # Only wipe if a loop completed was tagged
|
|
1966
1975
|
self.model_file.update(Searched=False, Upgrade=False).where(
|
|
1967
|
-
self.model_file.Searched == True
|
|
1976
|
+
(self.model_file.Searched == True) & (self.model_file.ArrInstance == self._name)
|
|
1968
1977
|
).execute()
|
|
1969
1978
|
while True:
|
|
1970
1979
|
try:
|
|
@@ -1981,7 +1990,9 @@ class Arr:
|
|
|
1981
1990
|
JSONDecodeError,
|
|
1982
1991
|
):
|
|
1983
1992
|
continue
|
|
1984
|
-
self.model_file.delete().where(
|
|
1993
|
+
self.model_file.delete().where(
|
|
1994
|
+
(self.model_file.EntryId.not_in(ids)) & (self.model_file.ArrInstance == self._name)
|
|
1995
|
+
).execute()
|
|
1985
1996
|
self.loop_completed = False
|
|
1986
1997
|
|
|
1987
1998
|
def db_get_files_series(self) -> list[list[SeriesFilesModel, bool, bool]] | None:
|
|
@@ -2037,9 +2048,13 @@ class Arr:
|
|
|
2037
2048
|
if i1 is not None:
|
|
2038
2049
|
entries.append([i1, i2, i3])
|
|
2039
2050
|
if not self.do_upgrade_search:
|
|
2040
|
-
condition = self.series_file_model.Searched == False
|
|
2051
|
+
condition = (self.series_file_model.Searched == False) & (
|
|
2052
|
+
self.series_file_model.ArrInstance == self._name
|
|
2053
|
+
)
|
|
2041
2054
|
else:
|
|
2042
|
-
condition = self.series_file_model.Upgrade == False
|
|
2055
|
+
condition = (self.series_file_model.Upgrade == False) & (
|
|
2056
|
+
self.series_file_model.ArrInstance == self._name
|
|
2057
|
+
)
|
|
2043
2058
|
|
|
2044
2059
|
# Collect series entries with their priority based on episode reasons
|
|
2045
2060
|
# Missing > CustomFormat > Quality > Upgrade
|
|
@@ -2079,7 +2094,9 @@ class Arr:
|
|
|
2079
2094
|
if not (self.search_missing or self.do_upgrade_search):
|
|
2080
2095
|
return None
|
|
2081
2096
|
elif self.type == "sonarr":
|
|
2082
|
-
condition = self.model_file.AirDateUtc.is_null(False)
|
|
2097
|
+
condition = (self.model_file.AirDateUtc.is_null(False)) & (
|
|
2098
|
+
self.model_file.ArrInstance == self._name
|
|
2099
|
+
)
|
|
2083
2100
|
if not self.search_specials:
|
|
2084
2101
|
condition &= self.model_file.SeasonNumber != 0
|
|
2085
2102
|
if self.do_upgrade_search:
|
|
@@ -2160,7 +2177,9 @@ class Arr:
|
|
|
2160
2177
|
if not (self.search_missing or self.do_upgrade_search):
|
|
2161
2178
|
return None
|
|
2162
2179
|
if self.type == "radarr":
|
|
2163
|
-
condition = self.model_file.Year.is_null(False)
|
|
2180
|
+
condition = (self.model_file.Year.is_null(False)) & (
|
|
2181
|
+
self.model_file.ArrInstance == self._name
|
|
2182
|
+
)
|
|
2164
2183
|
if self.do_upgrade_search:
|
|
2165
2184
|
condition &= self.model_file.Upgrade == False
|
|
2166
2185
|
else:
|
|
@@ -2211,7 +2230,7 @@ class Arr:
|
|
|
2211
2230
|
entries.append([entry, False, False])
|
|
2212
2231
|
return entries
|
|
2213
2232
|
elif self.type == "lidarr":
|
|
2214
|
-
condition =
|
|
2233
|
+
condition = self.model_file.ArrInstance == self._name
|
|
2215
2234
|
if self.do_upgrade_search:
|
|
2216
2235
|
condition &= self.model_file.Upgrade == False
|
|
2217
2236
|
else:
|
|
@@ -2264,7 +2283,9 @@ class Arr:
|
|
|
2264
2283
|
entries = []
|
|
2265
2284
|
self.logger.trace("Getting request files")
|
|
2266
2285
|
if self.type == "sonarr":
|
|
2267
|
-
condition = self.model_file.IsRequest == True
|
|
2286
|
+
condition = (self.model_file.IsRequest == True) & (
|
|
2287
|
+
self.model_file.ArrInstance == self._name
|
|
2288
|
+
)
|
|
2268
2289
|
condition &= self.model_file.AirDateUtc.is_null(False)
|
|
2269
2290
|
condition &= self.model_file.EpisodeFileId == 0
|
|
2270
2291
|
condition &= self.model_file.Searched == False
|
|
@@ -2282,7 +2303,9 @@ class Arr:
|
|
|
2282
2303
|
.execute()
|
|
2283
2304
|
)
|
|
2284
2305
|
elif self.type == "radarr":
|
|
2285
|
-
condition = self.model_file.IsRequest == True
|
|
2306
|
+
condition = (self.model_file.IsRequest == True) & (
|
|
2307
|
+
self.model_file.ArrInstance == self._name
|
|
2308
|
+
)
|
|
2286
2309
|
condition &= self.model_file.Year.is_null(False)
|
|
2287
2310
|
condition &= self.model_file.MovieFileId == 0
|
|
2288
2311
|
condition &= self.model_file.Searched == False
|
|
@@ -2826,7 +2849,8 @@ class Arr:
|
|
|
2826
2849
|
if not series:
|
|
2827
2850
|
self.model_file: EpisodeFilesModel
|
|
2828
2851
|
episodeData = self.model_file.get_or_none(
|
|
2829
|
-
self.model_file.EntryId == db_entry["id"]
|
|
2852
|
+
(self.model_file.EntryId == db_entry["id"])
|
|
2853
|
+
& (self.model_file.ArrInstance == self._name)
|
|
2830
2854
|
)
|
|
2831
2855
|
while True:
|
|
2832
2856
|
try:
|
|
@@ -2945,7 +2969,8 @@ class Arr:
|
|
|
2945
2969
|
):
|
|
2946
2970
|
searched = True
|
|
2947
2971
|
self.model_queue.update(Completed=True).where(
|
|
2948
|
-
self.model_queue.EntryId == episode["id"]
|
|
2972
|
+
(self.model_queue.EntryId == episode["id"])
|
|
2973
|
+
& (self.model_queue.ArrInstance == self._name)
|
|
2949
2974
|
).execute()
|
|
2950
2975
|
|
|
2951
2976
|
if self.use_temp_for_missing:
|
|
@@ -3154,14 +3179,16 @@ class Arr:
|
|
|
3154
3179
|
db_commands.execute()
|
|
3155
3180
|
else:
|
|
3156
3181
|
db_commands = self.model_file.delete().where(
|
|
3157
|
-
self.model_file.EntryId == episode["id"]
|
|
3182
|
+
(self.model_file.EntryId == episode["id"])
|
|
3183
|
+
& (self.model_file.ArrInstance == self._name)
|
|
3158
3184
|
)
|
|
3159
3185
|
db_commands.execute()
|
|
3160
3186
|
else:
|
|
3161
3187
|
self.series_file_model: SeriesFilesModel
|
|
3162
3188
|
EntryId = db_entry["id"]
|
|
3163
3189
|
seriesData = self.series_file_model.get_or_none(
|
|
3164
|
-
self.series_file_model.EntryId == EntryId
|
|
3190
|
+
(self.series_file_model.EntryId == EntryId)
|
|
3191
|
+
& (self.series_file_model.ArrInstance == self._name)
|
|
3165
3192
|
)
|
|
3166
3193
|
if db_entry["monitored"] or self.search_unmonitored:
|
|
3167
3194
|
while True:
|
|
@@ -3339,14 +3366,18 @@ class Arr:
|
|
|
3339
3366
|
# No need to recursively process episodes here to avoid duplication
|
|
3340
3367
|
else:
|
|
3341
3368
|
db_commands = self.series_file_model.delete().where(
|
|
3342
|
-
self.series_file_model.EntryId == EntryId
|
|
3369
|
+
(self.series_file_model.EntryId == EntryId)
|
|
3370
|
+
& (self.series_file_model.ArrInstance == self._name)
|
|
3343
3371
|
)
|
|
3344
3372
|
db_commands.execute()
|
|
3345
3373
|
|
|
3346
3374
|
elif self.type == "radarr":
|
|
3347
3375
|
self.model_file: MoviesFilesModel
|
|
3348
3376
|
searched = False
|
|
3349
|
-
movieData = self.model_file.get_or_none(
|
|
3377
|
+
movieData = self.model_file.get_or_none(
|
|
3378
|
+
(self.model_file.EntryId == db_entry["id"])
|
|
3379
|
+
& (self.model_file.ArrInstance == self._name)
|
|
3380
|
+
)
|
|
3350
3381
|
if self.minimum_availability_check(db_entry) and (
|
|
3351
3382
|
db_entry["monitored"] or self.search_unmonitored
|
|
3352
3383
|
):
|
|
@@ -3406,7 +3437,8 @@ class Arr:
|
|
|
3406
3437
|
):
|
|
3407
3438
|
searched = True
|
|
3408
3439
|
self.model_queue.update(Completed=True).where(
|
|
3409
|
-
self.model_queue.EntryId == db_entry["id"]
|
|
3440
|
+
(self.model_queue.EntryId == db_entry["id"])
|
|
3441
|
+
& (self.model_queue.ArrInstance == self._name)
|
|
3410
3442
|
).execute()
|
|
3411
3443
|
|
|
3412
3444
|
profile_switch_timestamp = None
|
|
@@ -3575,7 +3607,8 @@ class Arr:
|
|
|
3575
3607
|
db_commands.execute()
|
|
3576
3608
|
else:
|
|
3577
3609
|
db_commands = self.model_file.delete().where(
|
|
3578
|
-
self.model_file.EntryId == db_entry["id"]
|
|
3610
|
+
(self.model_file.EntryId == db_entry["id"])
|
|
3611
|
+
& (self.model_file.ArrInstance == self._name)
|
|
3579
3612
|
)
|
|
3580
3613
|
db_commands.execute()
|
|
3581
3614
|
elif self.type == "lidarr":
|
|
@@ -3584,7 +3617,8 @@ class Arr:
|
|
|
3584
3617
|
self.model_file: AlbumFilesModel
|
|
3585
3618
|
searched = False
|
|
3586
3619
|
albumData = self.model_file.get_or_none(
|
|
3587
|
-
self.model_file.EntryId == db_entry["id"]
|
|
3620
|
+
(self.model_file.EntryId == db_entry["id"])
|
|
3621
|
+
& (self.model_file.ArrInstance == self._name)
|
|
3588
3622
|
)
|
|
3589
3623
|
if db_entry["monitored"] or self.search_unmonitored:
|
|
3590
3624
|
while True:
|
|
@@ -3927,20 +3961,23 @@ class Arr:
|
|
|
3927
3961
|
)
|
|
3928
3962
|
else:
|
|
3929
3963
|
db_commands = self.model_file.delete().where(
|
|
3930
|
-
self.model_file.EntryId == db_entry["id"]
|
|
3964
|
+
(self.model_file.EntryId == db_entry["id"])
|
|
3965
|
+
& (self.model_file.ArrInstance == self._name)
|
|
3931
3966
|
)
|
|
3932
3967
|
db_commands.execute()
|
|
3933
3968
|
# Also delete tracks for this album (Lidarr only)
|
|
3934
3969
|
if self.track_file_model:
|
|
3935
3970
|
self.track_file_model.delete().where(
|
|
3936
|
-
self.track_file_model.AlbumId == db_entry["id"]
|
|
3971
|
+
(self.track_file_model.AlbumId == db_entry["id"])
|
|
3972
|
+
& (self.track_file_model.ArrInstance == self._name)
|
|
3937
3973
|
).execute()
|
|
3938
3974
|
else:
|
|
3939
3975
|
# Artist handling
|
|
3940
3976
|
self.artists_file_model: ArtistFilesModel
|
|
3941
3977
|
EntryId = db_entry["id"]
|
|
3942
3978
|
artistData = self.artists_file_model.get_or_none(
|
|
3943
|
-
self.artists_file_model.EntryId == EntryId
|
|
3979
|
+
(self.artists_file_model.EntryId == EntryId)
|
|
3980
|
+
& (self.artists_file_model.ArrInstance == self._name)
|
|
3944
3981
|
)
|
|
3945
3982
|
if db_entry["monitored"] or self.search_unmonitored:
|
|
3946
3983
|
while True:
|
|
@@ -4328,7 +4365,8 @@ class Arr:
|
|
|
4328
4365
|
file_model.AirDateUtc,
|
|
4329
4366
|
)
|
|
4330
4367
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4331
|
-
|
|
4368
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4369
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4332
4370
|
).execute()
|
|
4333
4371
|
return True
|
|
4334
4372
|
active_commands = self.arr_db_query_commands_count()
|
|
@@ -4371,7 +4409,8 @@ class Arr:
|
|
|
4371
4409
|
):
|
|
4372
4410
|
continue
|
|
4373
4411
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4374
|
-
|
|
4412
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4413
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4375
4414
|
).execute()
|
|
4376
4415
|
reason_text = getattr(file_model, "Reason", None) or None
|
|
4377
4416
|
if reason_text:
|
|
@@ -4442,7 +4481,8 @@ class Arr:
|
|
|
4442
4481
|
):
|
|
4443
4482
|
continue
|
|
4444
4483
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4445
|
-
|
|
4484
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4485
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4446
4486
|
).execute()
|
|
4447
4487
|
self.logger.hnotice(
|
|
4448
4488
|
"%sSearching for: %s | %s | [id=%s]",
|
|
@@ -4482,7 +4522,8 @@ class Arr:
|
|
|
4482
4522
|
file_model.EntryId,
|
|
4483
4523
|
)
|
|
4484
4524
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4485
|
-
|
|
4525
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4526
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4486
4527
|
).execute()
|
|
4487
4528
|
return True
|
|
4488
4529
|
active_commands = self.arr_db_query_commands_count()
|
|
@@ -4514,7 +4555,8 @@ class Arr:
|
|
|
4514
4555
|
):
|
|
4515
4556
|
continue
|
|
4516
4557
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4517
|
-
|
|
4558
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4559
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4518
4560
|
).execute()
|
|
4519
4561
|
reason_text = getattr(file_model, "Reason", None)
|
|
4520
4562
|
if reason_text:
|
|
@@ -4567,7 +4609,8 @@ class Arr:
|
|
|
4567
4609
|
file_model.EntryId,
|
|
4568
4610
|
)
|
|
4569
4611
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4570
|
-
|
|
4612
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4613
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4571
4614
|
).execute()
|
|
4572
4615
|
return True
|
|
4573
4616
|
active_commands = self.arr_db_query_commands_count()
|
|
@@ -4600,7 +4643,8 @@ class Arr:
|
|
|
4600
4643
|
):
|
|
4601
4644
|
continue
|
|
4602
4645
|
self.model_file.update(Searched=True, Upgrade=True).where(
|
|
4603
|
-
|
|
4646
|
+
(self.model_file.EntryId == file_model.EntryId)
|
|
4647
|
+
& (self.model_file.ArrInstance == self._name)
|
|
4604
4648
|
).execute()
|
|
4605
4649
|
reason_text = getattr(file_model, "Reason", None)
|
|
4606
4650
|
if reason_text:
|
|
@@ -6195,7 +6239,12 @@ class Arr:
|
|
|
6195
6239
|
|
|
6196
6240
|
# Retrieve the model entry from the database
|
|
6197
6241
|
model_entry = (
|
|
6198
|
-
self.model_file.select()
|
|
6242
|
+
self.model_file.select()
|
|
6243
|
+
.where(
|
|
6244
|
+
(self.model_file.EntryId == entry_id)
|
|
6245
|
+
& (self.model_file.ArrInstance == self._name)
|
|
6246
|
+
)
|
|
6247
|
+
.first()
|
|
6199
6248
|
)
|
|
6200
6249
|
if not model_entry:
|
|
6201
6250
|
return False
|
|
@@ -6268,7 +6317,10 @@ class Arr:
|
|
|
6268
6317
|
if self.model_queue:
|
|
6269
6318
|
with_database_retry(
|
|
6270
6319
|
lambda: self.model_queue.delete()
|
|
6271
|
-
.where(
|
|
6320
|
+
.where(
|
|
6321
|
+
(self.model_queue.EntryId.not_in(list(self.queue_file_ids)))
|
|
6322
|
+
& (self.model_queue.ArrInstance == self._name)
|
|
6323
|
+
)
|
|
6272
6324
|
.execute(),
|
|
6273
6325
|
logger=self.logger,
|
|
6274
6326
|
)
|
|
@@ -6282,7 +6334,10 @@ class Arr:
|
|
|
6282
6334
|
if self.model_queue:
|
|
6283
6335
|
with_database_retry(
|
|
6284
6336
|
lambda: self.model_queue.delete()
|
|
6285
|
-
.where(
|
|
6337
|
+
.where(
|
|
6338
|
+
(self.model_queue.EntryId.not_in(list(self.queue_file_ids)))
|
|
6339
|
+
& (self.model_queue.ArrInstance == self._name)
|
|
6340
|
+
)
|
|
6286
6341
|
.execute(),
|
|
6287
6342
|
logger=self.logger,
|
|
6288
6343
|
)
|
|
@@ -6567,7 +6622,8 @@ class Arr:
|
|
|
6567
6622
|
|
|
6568
6623
|
# Find items with temp profiles that have exceeded timeout
|
|
6569
6624
|
expired_items = model.select().where(
|
|
6570
|
-
(model.
|
|
6625
|
+
(model.ArrInstance == self._name)
|
|
6626
|
+
& (model.LastProfileSwitchTime.is_null(False))
|
|
6571
6627
|
& (model.LastProfileSwitchTime < timeout_threshold)
|
|
6572
6628
|
& (model.CurrentProfileId.is_null(False))
|
|
6573
6629
|
& (model.OriginalProfileId.is_null(False))
|
|
@@ -6583,7 +6639,9 @@ class Arr:
|
|
|
6583
6639
|
# Not a temp profile anymore, clear tracking
|
|
6584
6640
|
model.update(
|
|
6585
6641
|
LastProfileSwitchTime=None, CurrentProfileId=None, OriginalProfileId=None
|
|
6586
|
-
).where(
|
|
6642
|
+
).where(
|
|
6643
|
+
(model.EntryId == entry_id) & (model.ArrInstance == self._name)
|
|
6644
|
+
).execute()
|
|
6587
6645
|
continue
|
|
6588
6646
|
|
|
6589
6647
|
# Reset to original profile via Arr API
|
|
@@ -6606,7 +6664,9 @@ class Arr:
|
|
|
6606
6664
|
# Clear tracking fields in database
|
|
6607
6665
|
model.update(
|
|
6608
6666
|
LastProfileSwitchTime=None, CurrentProfileId=None, OriginalProfileId=None
|
|
6609
|
-
).where(
|
|
6667
|
+
).where(
|
|
6668
|
+
(model.EntryId == entry_id) & (model.ArrInstance == self._name)
|
|
6669
|
+
).execute()
|
|
6610
6670
|
|
|
6611
6671
|
reset_count += 1
|
|
6612
6672
|
self.logger.info(
|
|
@@ -461,7 +461,8 @@ class WebUI:
|
|
|
461
461
|
if is_request is not None:
|
|
462
462
|
query = query.where(model.IsRequest == is_request)
|
|
463
463
|
|
|
464
|
-
|
|
464
|
+
# Total should be ALL items for this instance, not filtered results
|
|
465
|
+
total = base_query.count()
|
|
465
466
|
page_items = query.order_by(model.Title.asc()).paginate(page + 1, page_size).iterator()
|
|
466
467
|
movies = []
|
|
467
468
|
for movie in page_items:
|
|
@@ -622,6 +623,9 @@ class WebUI:
|
|
|
622
623
|
|
|
623
624
|
albums = []
|
|
624
625
|
|
|
626
|
+
# Total should be ALL albums for this instance, not filtered results
|
|
627
|
+
total = base_query.count()
|
|
628
|
+
|
|
625
629
|
if group_by_artist:
|
|
626
630
|
# Paginate by artists: Two-pass approach with Peewee
|
|
627
631
|
# First, get all distinct artist names from the filtered query
|
|
@@ -632,7 +636,7 @@ class WebUI:
|
|
|
632
636
|
|
|
633
637
|
# Convert to list to avoid multiple iterations
|
|
634
638
|
all_artists = [row.ArtistTitle for row in artists_subquery]
|
|
635
|
-
|
|
639
|
+
len(all_artists)
|
|
636
640
|
|
|
637
641
|
# Paginate the artist list in Python
|
|
638
642
|
start_idx = page * page_size
|
|
@@ -650,7 +654,7 @@ class WebUI:
|
|
|
650
654
|
album_results = []
|
|
651
655
|
else:
|
|
652
656
|
# Flat mode: paginate by albums as before
|
|
653
|
-
total
|
|
657
|
+
# Note: total is already set to base_query.count() above
|
|
654
658
|
album_results = list(query.order_by(model.Title).paginate(page + 1, page_size))
|
|
655
659
|
|
|
656
660
|
for album in album_results:
|
|
@@ -982,16 +986,22 @@ class WebUI:
|
|
|
982
986
|
total_series = 0
|
|
983
987
|
|
|
984
988
|
if series_model is not None:
|
|
985
|
-
|
|
989
|
+
# Base query for ALL series in this instance (unfiltered)
|
|
990
|
+
base_series_query = series_model.select().where(
|
|
986
991
|
series_model.ArrInstance == arr_instance
|
|
987
992
|
)
|
|
993
|
+
# Total should be ALL series for this instance, not filtered results
|
|
994
|
+
total_series = base_series_query.count()
|
|
995
|
+
|
|
996
|
+
# Now build the filtered query for pagination
|
|
997
|
+
series_query = base_series_query
|
|
988
998
|
if search:
|
|
989
999
|
series_query = series_query.where(series_model.Title.contains(search))
|
|
990
1000
|
if missing_only and missing_series_ids:
|
|
991
1001
|
series_query = series_query.where(series_model.EntryId.in_(missing_series_ids))
|
|
992
|
-
|
|
993
|
-
if
|
|
994
|
-
max_pages = (
|
|
1002
|
+
filtered_series_count = series_query.count()
|
|
1003
|
+
if filtered_series_count:
|
|
1004
|
+
max_pages = (filtered_series_count + page_size - 1) // page_size
|
|
995
1005
|
if max_pages:
|
|
996
1006
|
resolved_page = min(resolved_page, max_pages - 1)
|
|
997
1007
|
resolved_page = max(resolved_page, 0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: qBitrr2
|
|
3
|
-
Version: 5.8.
|
|
3
|
+
Version: 5.8.6
|
|
4
4
|
Summary: Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration
|
|
5
5
|
Home-page: https://github.com/Feramance/qBitrr
|
|
6
6
|
Author: Feramance
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[metadata]
|
|
2
2
|
name = qBitrr2
|
|
3
|
-
version = 5.8.
|
|
3
|
+
version = 5.8.6
|
|
4
4
|
description = Intelligent automation for qBittorrent and *Arr apps (Radarr/Sonarr/Lidarr) - health monitoring, instant imports, quality upgrades, request integration
|
|
5
5
|
long_description = file: README.md
|
|
6
6
|
long_description_content_type = text/markdown
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|