qBitrr2 5.8.1__py3-none-any.whl → 5.8.3__py3-none-any.whl

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.
qBitrr/arss.py CHANGED
@@ -1434,7 +1434,9 @@ class Arr:
1434
1434
  ):
1435
1435
  continue
1436
1436
  if self.persistent_queue:
1437
- self.persistent_queue.insert(EntryId=series_id).on_conflict_ignore()
1437
+ self.persistent_queue.insert(
1438
+ EntryId=series_id, ArrInstance=self._name
1439
+ ).on_conflict_ignore()
1438
1440
  else:
1439
1441
  for object_id in object_ids:
1440
1442
  episode_found = False
@@ -1503,7 +1505,7 @@ class Arr:
1503
1505
  continue
1504
1506
  if self.persistent_queue:
1505
1507
  self.persistent_queue.insert(
1506
- EntryId=object_id
1508
+ EntryId=object_id, ArrInstance=self._name
1507
1509
  ).on_conflict_ignore()
1508
1510
  elif self.type == "radarr":
1509
1511
  self.logger.trace("Requeue cache entry: %s", object_id)
@@ -1554,7 +1556,9 @@ class Arr:
1554
1556
  ):
1555
1557
  continue
1556
1558
  if self.persistent_queue:
1557
- self.persistent_queue.insert(EntryId=object_id).on_conflict_ignore()
1559
+ self.persistent_queue.insert(
1560
+ EntryId=object_id, ArrInstance=self._name
1561
+ ).on_conflict_ignore()
1558
1562
  elif self.type == "lidarr":
1559
1563
  self.logger.trace("Requeue cache entry: %s", object_id)
1560
1564
  album_found = False
@@ -1604,7 +1608,9 @@ class Arr:
1604
1608
  ):
1605
1609
  continue
1606
1610
  if self.persistent_queue:
1607
- self.persistent_queue.insert(EntryId=object_id).on_conflict_ignore()
1611
+ self.persistent_queue.insert(
1612
+ EntryId=object_id, ArrInstance=self._name
1613
+ ).on_conflict_ignore()
1608
1614
 
1609
1615
  def _process_errored(self) -> None:
1610
1616
  # Recheck all torrents marked for rechecking.
@@ -3146,6 +3152,7 @@ class Arr:
3146
3152
  CustomFormatScore=customFormat,
3147
3153
  CustomFormatMet=customFormatMet,
3148
3154
  Reason=reason,
3155
+ ArrInstance=self._name,
3149
3156
  ).on_conflict(conflict_target=[self.model_file.EntryId], update=to_update)
3150
3157
  db_commands.execute()
3151
3158
  else:
@@ -3325,6 +3332,7 @@ class Arr:
3325
3332
  MinCustomFormatScore=minCustomFormat,
3326
3333
  QualityProfileId=quality_profile_id,
3327
3334
  QualityProfileName=qualityProfileName,
3335
+ ArrInstance=self._name,
3328
3336
  ).on_conflict(
3329
3337
  conflict_target=[self.series_file_model.EntryId], update=to_update
3330
3338
  )
@@ -3565,6 +3573,7 @@ class Arr:
3565
3573
  Reason=reason,
3566
3574
  QualityProfileId=qualityProfileId,
3567
3575
  QualityProfileName=qualityProfileName,
3576
+ ArrInstance=self._name,
3568
3577
  ).on_conflict(conflict_target=[self.model_file.EntryId], update=to_update)
3569
3578
  db_commands.execute()
3570
3579
  else:
@@ -3866,6 +3875,7 @@ class Arr:
3866
3875
  Reason=reason,
3867
3876
  QualityProfileId=qualityProfileId,
3868
3877
  QualityProfileName=qualityProfileName,
3878
+ ArrInstance=self._name,
3869
3879
  ).on_conflict(conflict_target=[self.model_file.EntryId], update=to_update)
3870
3880
  db_commands.execute()
3871
3881
 
@@ -3902,6 +3912,7 @@ class Arr:
3902
3912
  HasFile=track.get("hasFile", False),
3903
3913
  TrackFileId=track.get("trackFileId", 0),
3904
3914
  Monitored=track_monitored,
3915
+ ArrInstance=self._name,
3905
3916
  ).execute()
3906
3917
  track_insert_count += 1
3907
3918
 
@@ -4045,6 +4056,7 @@ class Arr:
4045
4056
  Monitored=Monitored,
4046
4057
  Upgrade=False,
4047
4058
  MinCustomFormatScore=minCustomFormat,
4059
+ ArrInstance=self._name,
4048
4060
  ).on_conflict(
4049
4061
  conflict_target=[self.artists_file_model.EntryId], update=to_update
4050
4062
  )
@@ -4342,10 +4354,10 @@ class Arr:
4342
4354
  )
4343
4355
  return False
4344
4356
  self.persistent_queue.insert(
4345
- EntryId=file_model.EntryId
4357
+ EntryId=file_model.EntryId, ArrInstance=self._name
4346
4358
  ).on_conflict_ignore().execute()
4347
4359
  self.model_queue.insert(
4348
- Completed=False, EntryId=file_model.EntryId
4360
+ Completed=False, EntryId=file_model.EntryId, ArrInstance=self._name
4349
4361
  ).on_conflict_replace().execute()
4350
4362
  if file_model.EntryId not in self.queue_file_ids:
4351
4363
  while True:
@@ -4414,10 +4426,10 @@ class Arr:
4414
4426
  )
4415
4427
  return False
4416
4428
  self.persistent_queue.insert(
4417
- EntryId=file_model.EntryId
4429
+ EntryId=file_model.EntryId, ArrInstance=self._name
4418
4430
  ).on_conflict_ignore().execute()
4419
4431
  self.model_queue.insert(
4420
- Completed=False, EntryId=file_model.EntryId
4432
+ Completed=False, EntryId=file_model.EntryId, ArrInstance=self._name
4421
4433
  ).on_conflict_replace().execute()
4422
4434
  while True:
4423
4435
  try:
@@ -4485,10 +4497,12 @@ class Arr:
4485
4497
  file_model.EntryId,
4486
4498
  )
4487
4499
  return False
4488
- self.persistent_queue.insert(EntryId=file_model.EntryId).on_conflict_ignore().execute()
4500
+ self.persistent_queue.insert(
4501
+ EntryId=file_model.EntryId, ArrInstance=self._name
4502
+ ).on_conflict_ignore().execute()
4489
4503
 
4490
4504
  self.model_queue.insert(
4491
- Completed=False, EntryId=file_model.EntryId
4505
+ Completed=False, EntryId=file_model.EntryId, ArrInstance=self._name
4492
4506
  ).on_conflict_replace().execute()
4493
4507
  if file_model.EntryId:
4494
4508
  while True:
@@ -4569,10 +4583,12 @@ class Arr:
4569
4583
  file_model.EntryId,
4570
4584
  )
4571
4585
  return False
4572
- self.persistent_queue.insert(EntryId=file_model.EntryId).on_conflict_ignore().execute()
4586
+ self.persistent_queue.insert(
4587
+ EntryId=file_model.EntryId, ArrInstance=self._name
4588
+ ).on_conflict_ignore().execute()
4573
4589
 
4574
4590
  self.model_queue.insert(
4575
- Completed=False, EntryId=file_model.EntryId
4591
+ Completed=False, EntryId=file_model.EntryId, ArrInstance=self._name
4576
4592
  ).on_conflict_replace().execute()
4577
4593
  if file_model.EntryId:
4578
4594
  while True:
qBitrr/bundled_data.py CHANGED
@@ -1,5 +1,5 @@
1
- version = "5.8.1"
2
- git_hash = "8cc293b9"
1
+ version = "5.8.3"
2
+ git_hash = "48b8e83c"
3
3
  license_text = (
4
4
  "Licence can be found on:\n\nhttps://github.com/Feramance/qBitrr/blob/master/LICENSE"
5
5
  )
qBitrr/database.py CHANGED
@@ -74,6 +74,77 @@ def get_database() -> SqliteDatabase:
74
74
  # Create all tables
75
75
  _db.create_tables(models, safe=True)
76
76
 
77
+ # Run migrations
78
+ _migrate_arrinstance_field(models)
79
+ _create_arrinstance_indexes(_db, models)
80
+
77
81
  logger.info("Initialized single database: %s", db_path)
78
82
 
79
83
  return _db
84
+
85
+
86
+ def _migrate_arrinstance_field(models: list) -> None:
87
+ """
88
+ Migration: Remove records with empty ArrInstance field.
89
+
90
+ After database consolidation, old records don't have ArrInstance set.
91
+ Since we can't reliably determine which instance they belong to,
92
+ we delete them and let the application repopulate with correct values.
93
+ """
94
+ try:
95
+ deleted_count = 0
96
+ for model in models:
97
+ # Check if model has ArrInstance field
98
+ if hasattr(model, "ArrInstance"):
99
+ # Delete records where ArrInstance is NULL or empty string
100
+ query = model.delete().where(
101
+ (model.ArrInstance.is_null()) | (model.ArrInstance == "")
102
+ )
103
+ count = query.execute()
104
+ if count > 0:
105
+ logger.info(
106
+ "Migrated %s: deleted %d records with empty ArrInstance",
107
+ model.__name__,
108
+ count,
109
+ )
110
+ deleted_count += count
111
+
112
+ if deleted_count > 0:
113
+ logger.warning(
114
+ "Database migration: Removed %d old records without ArrInstance. "
115
+ "qBitrr will repopulate data from Arr instances.",
116
+ deleted_count,
117
+ )
118
+ except Exception as e:
119
+ logger.error("Error during ArrInstance migration: %s", e)
120
+
121
+
122
+ def _create_arrinstance_indexes(db: SqliteDatabase, models: list) -> None:
123
+ """
124
+ Create database indexes on ArrInstance field for performance.
125
+
126
+ Indexes improve query performance when filtering by ArrInstance,
127
+ which is done on every WebUI page load.
128
+ """
129
+ try:
130
+ cursor = db.cursor()
131
+ for model in models:
132
+ if hasattr(model, "ArrInstance"):
133
+ table_name = model._meta.table_name
134
+ index_name = f"idx_arrinstance_{table_name}"
135
+
136
+ # Check if index already exists
137
+ cursor.execute(
138
+ "SELECT name FROM sqlite_master WHERE type='index' AND name=?",
139
+ (index_name,),
140
+ )
141
+ if cursor.fetchone():
142
+ continue # Index already exists
143
+
144
+ # Create index
145
+ cursor.execute(f"CREATE INDEX {index_name} ON {table_name}(ArrInstance)")
146
+ logger.info("Created index: %s on %s.ArrInstance", index_name, table_name)
147
+
148
+ db.commit()
149
+ except Exception as e:
150
+ logger.error("Error creating ArrInstance indexes: %s", e)
qBitrr/webui.py CHANGED
@@ -394,20 +394,25 @@ class WebUI:
394
394
  }
395
395
  page = max(page, 0)
396
396
  page_size = max(page_size, 1)
397
+ arr_instance = getattr(arr, "_name", "")
397
398
  with db.connection_context():
398
- base_query = model.select()
399
+ # Filter by ArrInstance
400
+ base_query = model.select().where(model.ArrInstance == arr_instance)
399
401
 
400
402
  # Calculate counts
401
403
  monitored_count = (
402
404
  model.select(fn.COUNT(model.EntryId))
403
- .where(model.Monitored == True) # noqa: E712
405
+ .where(
406
+ (model.ArrInstance == arr_instance) & (model.Monitored == True)
407
+ ) # noqa: E712
404
408
  .scalar()
405
409
  or 0
406
410
  )
407
411
  available_count = (
408
412
  model.select(fn.COUNT(model.EntryId))
409
413
  .where(
410
- (model.Monitored == True) # noqa: E712
414
+ (model.ArrInstance == arr_instance)
415
+ & (model.Monitored == True) # noqa: E712
411
416
  & (model.MovieFileId.is_null(False))
412
417
  & (model.MovieFileId != 0)
413
418
  )
@@ -417,13 +422,17 @@ class WebUI:
417
422
  missing_count = max(monitored_count - available_count, 0)
418
423
  quality_met_count = (
419
424
  model.select(fn.COUNT(model.EntryId))
420
- .where(model.QualityMet == True) # noqa: E712
425
+ .where(
426
+ (model.ArrInstance == arr_instance) & (model.QualityMet == True)
427
+ ) # noqa: E712
421
428
  .scalar()
422
429
  or 0
423
430
  )
424
431
  request_count = (
425
432
  model.select(fn.COUNT(model.EntryId))
426
- .where(model.IsRequest == True) # noqa: E712
433
+ .where(
434
+ (model.ArrInstance == arr_instance) & (model.IsRequest == True)
435
+ ) # noqa: E712
427
436
  .scalar()
428
437
  or 0
429
438
  )
@@ -544,24 +553,29 @@ class WebUI:
544
553
  }
545
554
  page = max(page, 0)
546
555
  page_size = max(page_size, 1)
556
+ arr_instance = getattr(arr, "_name", "")
547
557
 
548
558
  # Quality profiles are now stored in the database
549
559
  # No need to fetch from API
550
560
 
551
561
  with db.connection_context():
552
- base_query = model.select()
562
+ # Filter by ArrInstance
563
+ base_query = model.select().where(model.ArrInstance == arr_instance)
553
564
 
554
565
  # Calculate counts
555
566
  monitored_count = (
556
567
  model.select(fn.COUNT(model.EntryId))
557
- .where(model.Monitored == True) # noqa: E712
568
+ .where(
569
+ (model.ArrInstance == arr_instance) & (model.Monitored == True)
570
+ ) # noqa: E712
558
571
  .scalar()
559
572
  or 0
560
573
  )
561
574
  available_count = (
562
575
  model.select(fn.COUNT(model.EntryId))
563
576
  .where(
564
- (model.Monitored == True) # noqa: E712
577
+ (model.ArrInstance == arr_instance)
578
+ & (model.Monitored == True) # noqa: E712
565
579
  & (model.AlbumFileId.is_null(False))
566
580
  & (model.AlbumFileId != 0)
567
581
  )
@@ -571,13 +585,17 @@ class WebUI:
571
585
  missing_count = max(monitored_count - available_count, 0)
572
586
  quality_met_count = (
573
587
  model.select(fn.COUNT(model.EntryId))
574
- .where(model.QualityMet == True) # noqa: E712
588
+ .where(
589
+ (model.ArrInstance == arr_instance) & (model.QualityMet == True)
590
+ ) # noqa: E712
575
591
  .scalar()
576
592
  or 0
577
593
  )
578
594
  request_count = (
579
595
  model.select(fn.COUNT(model.EntryId))
580
- .where(model.IsRequest == True) # noqa: E712
596
+ .where(
597
+ (model.ArrInstance == arr_instance) & (model.IsRequest == True)
598
+ ) # noqa: E712
581
599
  .scalar()
582
600
  or 0
583
601
  )
@@ -772,8 +790,11 @@ class WebUI:
772
790
  "tracks": [],
773
791
  }
774
792
 
793
+ arr_instance = getattr(arr, "_name", "")
794
+
775
795
  try:
776
796
  # Join tracks with albums to get artist/album info
797
+ # Filter by ArrInstance on both models
777
798
  query = (
778
799
  track_model.select(
779
800
  track_model,
@@ -782,7 +803,10 @@ class WebUI:
782
803
  album_model.ArtistId,
783
804
  )
784
805
  .join(album_model, on=(track_model.AlbumId == album_model.EntryId))
785
- .where(True)
806
+ .where(
807
+ (track_model.ArrInstance == arr_instance)
808
+ & (album_model.ArrInstance == arr_instance)
809
+ )
786
810
  )
787
811
 
788
812
  # Apply filters
@@ -797,17 +821,25 @@ class WebUI:
797
821
  | (album_model.ArtistTitle.contains(search))
798
822
  )
799
823
 
800
- # Get counts
824
+ # Get counts with ArrInstance filter
801
825
  available_count = (
802
826
  track_model.select()
803
827
  .join(album_model, on=(track_model.AlbumId == album_model.EntryId))
804
- .where(track_model.HasFile == True)
828
+ .where(
829
+ (track_model.ArrInstance == arr_instance)
830
+ & (album_model.ArrInstance == arr_instance)
831
+ & (track_model.HasFile == True)
832
+ )
805
833
  .count()
806
834
  )
807
835
  monitored_count = (
808
836
  track_model.select()
809
837
  .join(album_model, on=(track_model.AlbumId == album_model.EntryId))
810
- .where(track_model.Monitored == True)
838
+ .where(
839
+ (track_model.ArrInstance == arr_instance)
840
+ & (album_model.ArrInstance == arr_instance)
841
+ & (track_model.Monitored == True)
842
+ )
811
843
  .count()
812
844
  )
813
845
  missing_count = (
@@ -894,6 +926,7 @@ class WebUI:
894
926
  page = max(page, 0)
895
927
  page_size = max(page_size, 1)
896
928
  resolved_page = page
929
+ arr_instance = getattr(arr, "_name", "")
897
930
  missing_condition = episodes_model.EpisodeFileId.is_null(True) | (
898
931
  episodes_model.EpisodeFileId == 0
899
932
  )
@@ -901,14 +934,18 @@ class WebUI:
901
934
  with db.connection_context():
902
935
  monitored_count = (
903
936
  episodes_model.select(fn.COUNT(episodes_model.EntryId))
904
- .where(episodes_model.Monitored == True) # noqa: E712
937
+ .where(
938
+ (episodes_model.ArrInstance == arr_instance)
939
+ & (episodes_model.Monitored == True) # noqa: E712
940
+ )
905
941
  .scalar()
906
942
  or 0
907
943
  )
908
944
  available_count = (
909
945
  episodes_model.select(fn.COUNT(episodes_model.EntryId))
910
946
  .where(
911
- (episodes_model.Monitored == True) # noqa: E712
947
+ (episodes_model.ArrInstance == arr_instance)
948
+ & (episodes_model.Monitored == True) # noqa: E712
912
949
  & (episodes_model.EpisodeFileId.is_null(False))
913
950
  & (episodes_model.EpisodeFileId != 0)
914
951
  )
@@ -921,7 +958,11 @@ class WebUI:
921
958
  missing_series_ids = [
922
959
  row.SeriesId
923
960
  for row in episodes_model.select(episodes_model.SeriesId)
924
- .where((episodes_model.Monitored == True) & missing_condition) # noqa: E712
961
+ .where(
962
+ (episodes_model.ArrInstance == arr_instance)
963
+ & (episodes_model.Monitored == True) # noqa: E712
964
+ & missing_condition
965
+ )
925
966
  .distinct()
926
967
  if getattr(row, "SeriesId", None) is not None
927
968
  ]
@@ -941,7 +982,9 @@ class WebUI:
941
982
  total_series = 0
942
983
 
943
984
  if series_model is not None:
944
- series_query = series_model.select()
985
+ series_query = series_model.select().where(
986
+ series_model.ArrInstance == arr_instance
987
+ )
945
988
  if search:
946
989
  series_query = series_query.where(series_model.Title.contains(search))
947
990
  if missing_only and missing_series_ids:
@@ -959,7 +1002,8 @@ class WebUI:
959
1002
  )
960
1003
  for series in series_rows:
961
1004
  episodes_query = episodes_model.select().where(
962
- episodes_model.SeriesId == series.EntryId
1005
+ (episodes_model.ArrInstance == arr_instance)
1006
+ & (episodes_model.SeriesId == series.EntryId)
963
1007
  )
964
1008
  if missing_only:
965
1009
  episodes_query = episodes_query.where(missing_condition)
@@ -1060,7 +1104,9 @@ class WebUI:
1060
1104
 
1061
1105
  if not payload:
1062
1106
  # Fallback: construct series payload from episode data (episode mode)
1063
- base_episode_query = episodes_model.select()
1107
+ base_episode_query = episodes_model.select().where(
1108
+ episodes_model.ArrInstance == arr_instance
1109
+ )
1064
1110
  if search:
1065
1111
  search_filters = []
1066
1112
  if hasattr(episodes_model, "SeriesTitle"):
@@ -1129,7 +1175,9 @@ class WebUI:
1129
1175
  episode_conditions.append(episodes_model.SeriesId == series_id)
1130
1176
  if series_title is not None:
1131
1177
  episode_conditions.append(episodes_model.SeriesTitle == series_title)
1132
- episodes_query = episodes_model.select()
1178
+ episodes_query = episodes_model.select().where(
1179
+ episodes_model.ArrInstance == arr_instance
1180
+ )
1133
1181
  if episode_conditions:
1134
1182
  condition = episode_conditions[0]
1135
1183
  for extra in episode_conditions[1:]:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qBitrr2
3
- Version: 5.8.1
3
+ Version: 5.8.3
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
@@ -169,24 +169,6 @@ services:
169
169
 
170
170
  Access the WebUI at `http://<host>:6969/ui` after startup.
171
171
 
172
- ## 🆕 What's New in v5.8.0
173
-
174
- ### Single Consolidated Database
175
- qBitrr now uses a **single `qbitrr.db` file** for all Arr instances, replacing the previous per-instance database approach.
176
-
177
- **Benefits:**
178
- - ✅ Single file to backup instead of 9+ separate databases
179
- - ✅ 78% code reduction in database initialization
180
- - ✅ Better performance with shared connection pool
181
- - ✅ Simplified database management
182
-
183
- **Migration:**
184
- - Automatic on first upgrade (5-30 minutes re-sync from Arr APIs)
185
- - Old databases deleted automatically
186
- - No manual intervention required
187
-
188
- [Full Migration Guide →](https://feramance.github.io/qBitrr/getting-started/migration/)
189
-
190
172
  ## ✨ Key Features
191
173
 
192
174
  - **🚀 Multi-qBittorrent Support (v3.0+)** – Manage torrents across multiple qBittorrent instances for load balancing, redundancy, and VPN isolation
@@ -254,8 +236,8 @@ See [Configuration Guide](https://feramance.github.io/qBitrr/configuration/) and
254
236
  - **PyPI Package:** https://pypi.org/project/qBitrr2/
255
237
  - **Docker Hub:** https://hub.docker.com/r/feramance/qbitrr
256
238
  - **Example Config:** [config.example.toml](config.example.toml)
257
- - **API Documentation:** [API_DOCUMENTATION.md](API_DOCUMENTATION.md)
258
- - **Systemd Setup:** [SYSTEMD_SERVICE.md](SYSTEMD_SERVICE.md)
239
+ - **API Documentation:** [docs/reference/api.md](docs/reference/api.md)
240
+ - **Systemd Setup:** [docs/getting-started/installation/systemd.md](docs/getting-started/installation/systemd.md)
259
241
 
260
242
  ## 🐛 Issues & Support
261
243
 
@@ -266,7 +248,7 @@ See [Configuration Guide](https://feramance.github.io/qBitrr/configuration/) and
266
248
 
267
249
  ## 🤝 Contributing
268
250
 
269
- Contributions welcome! See [CONTRIBUTION.md](CONTRIBUTION.md) for coding guidelines and development setup.
251
+ Contributions welcome! See [docs/development/contributing.md](docs/development/contributing.md) for coding guidelines and development setup.
270
252
 
271
253
  **Development setup:**
272
254
  ```bash
@@ -1,10 +1,10 @@
1
1
  qBitrr/__init__.py,sha256=smiPIV7d2lMJ_KTtFdAVlxLEBobFTheILdgry1iqpjQ,405
2
- qBitrr/arss.py,sha256=nf3qH_0Z0V2oY4RLwxjaoShKK85bMsqIrObptUwzz-0,356696
2
+ qBitrr/arss.py,sha256=rWrqtjQfCz09pGFdo8tBHOYRzn1pHyDydV0O_jWadIQ,357538
3
3
  qBitrr/auto_update.py,sha256=3mqlKKGnaWR5dNI58LN5WbHOMFRDWBsOs0zIC79QzQk,13359
4
- qBitrr/bundled_data.py,sha256=tAGiTLu95EdYYBsHg5ge6No77uRhXbgoXC3lboyR4lg,221
4
+ qBitrr/bundled_data.py,sha256=G7QREoL2e5gHVcEkuyVunMRPL_wCYvGSakV_LpC6ui8,221
5
5
  qBitrr/config.py,sha256=BtvzQCQnRHEGzNykEa-WsiWKPjwXCb7wMx994z3rWMs,6306
6
6
  qBitrr/config_version.py,sha256=eWfc7DuthsDGwv2WJAZ7uB7srSqxaUD3Oj9kac3HbFE,4208
7
- qBitrr/database.py,sha256=cXMNsunJYj094TRAe1zNmGkqNFNdnuKb8tmSuAS4-0o,1952
7
+ qBitrr/database.py,sha256=DgPiIxT1MRAhZ5anM5IzjvzEMB5fGDQmktsLEf2dN28,4602
8
8
  qBitrr/db_lock.py,sha256=ZM6TQagBOkcS7h9BDGsdxhCo5aJ5SMvtKSM_X7HLu8M,15375
9
9
  qBitrr/db_recovery.py,sha256=4kS9mWKrBYE9135m7cxvCOriSxz6lz7Dw4MT6gz81SM,6438
10
10
  qBitrr/env_config.py,sha256=299u_uEoyxlM_ceTD0Z_i41JdYjSHmqO6FKe7qGFgTM,2866
@@ -18,7 +18,7 @@ qBitrr/search_activity_store.py,sha256=JuJ0PQxSPBguacyqus2I4_g3qEYReOhZbghOjJOoE
18
18
  qBitrr/tables.py,sha256=hAHYmpSjdbXyOXABUDXmQKFgf_TQLrgYlCQPZEZWN8o,6187
19
19
  qBitrr/utils.py,sha256=T10win016yHwMMJlJ4yuPTRUI9m-AS_a_MouiAJAtC8,8190
20
20
  qBitrr/versioning.py,sha256=vjQ55rMInuEte9PXQo29FLxF0ff643Ttm3_ri5ghXPM,4542
21
- qBitrr/webui.py,sha256=lkfQ3uY_yvrm5aL97H8ZEAP0hZIJWzlXoFgNFkyvSX8,135964
21
+ qBitrr/webui.py,sha256=c-L-cSzYxoZomZllchR4zg4j6vebPsSUdyRSCdrOTR4,138111
22
22
  qBitrr/static/favicon-16x16.png,sha256=LrsZjRNNIivd0M-6OEghkY0bCYQNz_88kh-A6DDUpC4,1063
23
23
  qBitrr/static/favicon-32x32.png,sha256=n3S3d7McOUokBxHEItYH2lEPmrgU7z0z652jeRrFwVQ,3398
24
24
  qBitrr/static/favicon-48x48.png,sha256=r-co_lnPpXOLIptGm8FNZ4kM7QQkanwz_7vRxUAeqi0,6808
@@ -65,9 +65,9 @@ qBitrr/static/assets/useInterval.js.map,sha256=3KvsE2Do5LepkgpP-0XBHeGOprIQiDIdK
65
65
  qBitrr/static/assets/vendor.js,sha256=uDL8OA1Nbl4ZlnDVLXOmaKPBVqK6pBsoDiRriXdDk04,11357
66
66
  qBitrr/static/assets/vendor.js.map,sha256=Nj3zAKcjMhDma3lqUKGqQvwozZmbx4SEMBKBLXTi9io,42253
67
67
  qBitrr/static/assets/visibility.svg,sha256=258DiSuUKs2SH9dhhDDU88JQfLAlNQMvOGewc9uaTK4,9767
68
- qbitrr2-5.8.1.dist-info/licenses/LICENSE,sha256=P978aVGi7dPbKz8lfvdiryOS5IjTAU7AA47XhBhVBlI,1066
69
- qbitrr2-5.8.1.dist-info/METADATA,sha256=sRdUVl7tY2LTSZARSnSHffBxTV6Pu-AAhXgBdEywMhI,12112
70
- qbitrr2-5.8.1.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
71
- qbitrr2-5.8.1.dist-info/entry_points.txt,sha256=MIR-l5s31VBs9qlv3HiAaMdpOOyy0MNGfM7Ib1-fKeQ,43
72
- qbitrr2-5.8.1.dist-info/top_level.txt,sha256=jIINodarzsPcQeTf-vvK8-_g7cQ8CvxEg41ms14K97g,7
73
- qbitrr2-5.8.1.dist-info/RECORD,,
68
+ qbitrr2-5.8.3.dist-info/licenses/LICENSE,sha256=P978aVGi7dPbKz8lfvdiryOS5IjTAU7AA47XhBhVBlI,1066
69
+ qbitrr2-5.8.3.dist-info/METADATA,sha256=E7JvBBMLGpqpN8zv0ayLCbYrLlEduqydZd7RgnPHfEg,11549
70
+ qbitrr2-5.8.3.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
71
+ qbitrr2-5.8.3.dist-info/entry_points.txt,sha256=MIR-l5s31VBs9qlv3HiAaMdpOOyy0MNGfM7Ib1-fKeQ,43
72
+ qbitrr2-5.8.3.dist-info/top_level.txt,sha256=jIINodarzsPcQeTf-vvK8-_g7cQ8CvxEg41ms14K97g,7
73
+ qbitrr2-5.8.3.dist-info/RECORD,,