qBitrr2 5.4.3__py3-none-any.whl → 5.4.4__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/versioning.py CHANGED
@@ -24,18 +24,26 @@ def normalize_version(raw: str | None) -> str | None:
24
24
  def is_newer_version(candidate: str | None, current: str | None = None) -> bool:
25
25
  if not candidate:
26
26
  return False
27
+ normalized_candidate = normalize_version(candidate)
27
28
  normalized_current = normalize_version(current or patched_version)
28
29
  if not normalized_current:
29
30
  return True
31
+ if not normalized_candidate:
32
+ return False
30
33
  try:
31
- latest_version = version_parser.parse(candidate)
34
+ latest_version = version_parser.parse(normalized_candidate)
32
35
  current_version = version_parser.parse(normalized_current)
33
36
  return latest_version > current_version
34
37
  except Exception:
35
- return candidate != normalized_current
38
+ return normalized_candidate != normalized_current
36
39
 
37
40
 
38
41
  def fetch_latest_release(repo: str = DEFAULT_REPOSITORY, *, timeout: int = 10) -> dict[str, Any]:
42
+ """Fetch latest non-draft, non-prerelease from GitHub.
43
+
44
+ Note: The /releases/latest endpoint excludes drafts by default, but we
45
+ explicitly check to be defensive and provide clear error messages.
46
+ """
39
47
  url = f"https://api.github.com/repos/{repo}/releases/latest"
40
48
  headers = {"Accept": "application/vnd.github+json"}
41
49
  try:
@@ -55,6 +63,31 @@ def fetch_latest_release(repo: str = DEFAULT_REPOSITORY, *, timeout: int = 10) -
55
63
  "error": message,
56
64
  }
57
65
 
66
+ # Validate release is not draft/prerelease
67
+ is_draft = payload.get("draft", False)
68
+ is_prerelease = payload.get("prerelease", False)
69
+
70
+ if is_draft:
71
+ return {
72
+ "raw_tag": None,
73
+ "normalized": None,
74
+ "changelog": "",
75
+ "changelog_url": f"https://github.com/{repo}/releases",
76
+ "update_available": False,
77
+ "error": "Latest release is a draft (not yet published)",
78
+ }
79
+
80
+ if is_prerelease:
81
+ # Could make this configurable via settings in the future
82
+ return {
83
+ "raw_tag": None,
84
+ "normalized": None,
85
+ "changelog": "",
86
+ "changelog_url": f"https://github.com/{repo}/releases",
87
+ "update_available": False,
88
+ "error": "Latest release is a prerelease (beta/rc)",
89
+ }
90
+
58
91
  raw_tag = (payload.get("tag_name") or payload.get("name") or "").strip()
59
92
  normalized = normalize_version(raw_tag)
60
93
  changelog = payload.get("body") or ""
qBitrr/webui.py CHANGED
@@ -124,6 +124,11 @@ class WebUI:
124
124
  "update_available": False,
125
125
  "last_checked": None,
126
126
  "error": None,
127
+ "installation_type": "unknown",
128
+ "binary_download_url": None,
129
+ "binary_download_name": None,
130
+ "binary_download_size": None,
131
+ "binary_download_error": None,
127
132
  }
128
133
  self._version_cache_expiry = datetime.utcnow() - timedelta(seconds=1)
129
134
  self._update_state = {
@@ -223,6 +228,24 @@ class WebUI:
223
228
 
224
229
  self._version_cache["current_version"] = patched_version
225
230
  self._version_cache["last_checked"] = now.isoformat()
231
+
232
+ # Add installation type and binary download info
233
+ from qBitrr.auto_update import get_binary_download_url, get_installation_type
234
+
235
+ install_type = get_installation_type()
236
+ self._version_cache["installation_type"] = install_type
237
+
238
+ # If binary and update available, get download URL
239
+ if install_type == "binary" and self._version_cache.get("update_available"):
240
+ latest_version = self._version_cache.get("latest_version")
241
+ if latest_version:
242
+ binary_info = get_binary_download_url(latest_version, self.logger)
243
+ self._version_cache["binary_download_url"] = binary_info.get("url")
244
+ self._version_cache["binary_download_name"] = binary_info.get("name")
245
+ self._version_cache["binary_download_size"] = binary_info.get("size")
246
+ if binary_info.get("error"):
247
+ self._version_cache["binary_download_error"] = binary_info["error"]
248
+
226
249
  # Extend cache validity if fetch succeeded; otherwise allow quick retry.
227
250
  if not latest_info or latest_info.get("error"):
228
251
  self._version_cache_expiry = now + timedelta(minutes=5)
@@ -1907,6 +1930,65 @@ class WebUI:
1907
1930
  return jsonify({"error": message}), 409
1908
1931
  return jsonify({"status": "started"})
1909
1932
 
1933
+ @app.get("/api/download-update")
1934
+ def api_download_update():
1935
+ """Redirect to binary download URL for current platform."""
1936
+ if (resp := require_token()) is not None:
1937
+ return resp
1938
+
1939
+ from qBitrr.auto_update import get_installation_type
1940
+
1941
+ install_type = get_installation_type()
1942
+
1943
+ if install_type != "binary":
1944
+ return jsonify({"error": "Download only available for binary installations"}), 400
1945
+
1946
+ # Get latest version info
1947
+ version_info = self._ensure_version_info()
1948
+
1949
+ if not version_info.get("update_available"):
1950
+ return jsonify({"error": "No update available"}), 404
1951
+
1952
+ download_url = version_info.get("binary_download_url")
1953
+ if not download_url:
1954
+ error = version_info.get(
1955
+ "binary_download_error", "No binary available for your platform"
1956
+ )
1957
+ return jsonify({"error": error}), 404
1958
+
1959
+ # Redirect to GitHub download URL
1960
+ from flask import redirect
1961
+
1962
+ return redirect(download_url)
1963
+
1964
+ @app.get("/web/download-update")
1965
+ def web_download_update():
1966
+ """Redirect to binary download URL for current platform."""
1967
+ from qBitrr.auto_update import get_installation_type
1968
+
1969
+ install_type = get_installation_type()
1970
+
1971
+ if install_type != "binary":
1972
+ return jsonify({"error": "Download only available for binary installations"}), 400
1973
+
1974
+ # Get latest version info
1975
+ version_info = self._ensure_version_info()
1976
+
1977
+ if not version_info.get("update_available"):
1978
+ return jsonify({"error": "No update available"}), 404
1979
+
1980
+ download_url = version_info.get("binary_download_url")
1981
+ if not download_url:
1982
+ error = version_info.get(
1983
+ "binary_download_error", "No binary available for your platform"
1984
+ )
1985
+ return jsonify({"error": error}), 404
1986
+
1987
+ # Redirect to GitHub download URL
1988
+ from flask import redirect
1989
+
1990
+ return redirect(download_url)
1991
+
1910
1992
  def _status_payload() -> dict[str, Any]:
1911
1993
  qb = {
1912
1994
  "alive": bool(self.manager.is_alive),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: qBitrr2
3
- Version: 5.4.3
3
+ Version: 5.4.4
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
@@ -160,8 +160,11 @@ qBitrr is the intelligent glue between qBittorrent and the *Arr ecosystem (Radar
160
160
  - **Path-specific monitoring** – watch specific directories for space issues
161
161
 
162
162
  ### 🔄 Auto-Updates & Self-Healing
163
+ - **GitHub release-based updates** – automatically checks for published (non-draft) releases via GitHub API
163
164
  - **Scheduled auto-updates** – update qBitrr on a cron schedule (default: weekly Sunday 3 AM)
164
165
  - **Manual update trigger** – one-click updates from WebUI
166
+ - **Installation-aware updates** – detects git/pip/binary installs and uses appropriate update method
167
+ - **Version verification** – confirms installed version matches target before restart
165
168
  - **Smart restart mechanism** – uses `os.execv()` for true in-place restarts (no supervisor needed)
166
169
  - **Cross-platform compatibility** – works in Docker, systemd, native installs, Windows, Linux, macOS
167
170
  - **Graceful shutdown** – cleanly closes databases, flushes logs, terminates child processes
@@ -204,6 +207,8 @@ AutoUpdateEnabled = true
204
207
  AutoUpdateCron = "0 3 * * 0" # Weekly on Sunday at 3 AM
205
208
  ```
206
209
 
210
+ > 📝 **Note:** Auto-updates check GitHub releases for new versions. Only published (non-draft) releases trigger updates. Binary installations receive update notifications but require manual download.
211
+
207
212
  ### 🐳 Run with Docker
208
213
  **Minimal setup:**
209
214
  ```bash
@@ -533,38 +538,238 @@ AutoPauseResume = true # Required for FreeSpace to work
533
538
  **Disable monitoring:**
534
539
  ```toml
535
540
  [Settings]
536
- FreeSpace = "-1" # Disables free space checking
537
- ```
541
+ ### 🔄 Auto-Updates & Restarts
542
+
543
+ qBitrr can automatically update itself by checking GitHub releases for new versions. The update behavior varies by installation type.
544
+
545
+ #### 🔍 How Updates Work
546
+
547
+ **Update Detection:**
548
+ 1. 📡 Queries GitHub API for latest **published** (non-draft) release
549
+ 2. 🔢 Compares release version with current version using semantic versioning
550
+ 3. ⏩ Skips prereleases (beta, rc, alpha) by default
551
+ 4. 📦 Only updates when a newer **stable** version is available
552
+
553
+ **Installation Types:**
554
+
555
+ | Type | Detection | Update Method | Version Control |
556
+ |------|-----------|---------------|-----------------|
557
+ | **Git** | `.git` directory exists | `git checkout <tag>` or `git pull` | Checks out specific release tag |
558
+ | **PyPI** | Installed via pip | `pip install qBitrr2==<version>` | Installs exact version from PyPI |
559
+ | **Binary** | PyInstaller executable | Notification only | Logs download URL for manual update |
560
+
561
+ **Why different methods?**
562
+ - **Git installations** can checkout specific tags for precise version control
563
+ - **PyPI installations** can pin to exact versions for reliability
564
+ - **Binary installations** cannot self-update (would require replacing running executable), so qBitrr logs the download URL and version info for manual update
538
565
 
539
566
  ---
540
567
 
541
- ### 🔄 Auto-Updates & Restarts
568
+ #### ⚙️ Configuration
542
569
 
543
- **Scheduled Updates:**
570
+ **Basic Setup:**
544
571
  ```toml
545
572
  [Settings]
546
573
  AutoUpdateEnabled = true
547
574
  AutoUpdateCron = "0 3 * * 0" # Cron expression (default: Sunday 3 AM)
548
575
  ```
549
576
 
550
- **Manual Updates:**
551
- - Click "Update Now" in WebUI Config tab
552
- - Automatically downloads latest version
553
- - Performs graceful restart
577
+ **Cron Expression Examples:**
578
+ ```toml
579
+ "0 3 * * 0" # Every Sunday at 3:00 AM
580
+ "0 */6 * * *" # Every 6 hours
581
+ "0 0 * * *" # Daily at midnight
582
+ "0 2 * * 1-5" # Weekdays at 2:00 AM
583
+ ```
584
+
585
+ ---
586
+
587
+ #### 📋 Update Process Flow
588
+
589
+ **For Git & PyPI Installations:**
590
+
591
+ 1. **Check Phase:**
592
+ - Fetch latest release from GitHub API
593
+ - Validate release is not draft or prerelease
594
+ - Compare versions (semantic versioning)
595
+ - Skip if already on latest version
596
+
597
+ 2. **Download Phase:**
598
+ - **Git:** `git fetch --tags && git checkout v<version>`
599
+ - **PyPI:** `pip install --upgrade qBitrr2==<version>`
600
+
601
+ 3. **Verification Phase:**
602
+ - Reload version information
603
+ - Verify installed version matches target
604
+ - Log warning if mismatch
605
+
606
+ 4. **Restart Phase:**
607
+ - Gracefully shutdown (close DBs, flush logs)
608
+ - Terminate child processes
609
+ - Execute in-place restart via `os.execv()`
610
+ - Maintain same PID (systemd-friendly)
611
+
612
+ **For Binary Installations:**
613
+
614
+ 1. **Check Phase:** Same as above
615
+ 2. **Notification:** Logs message with download URL and instructions
616
+ 3. **Manual Update:** User downloads new binary from GitHub releases
617
+ 4. **No Auto-Restart:** User manually restarts after replacing binary
618
+
619
+ Example binary update log:
620
+ ```
621
+ [INFO] Update available: v5.4.2 -> v5.4.3
622
+ [INFO] Binary installation detected - manual update required
623
+ [INFO] Download: https://github.com/Feramance/qBitrr/releases/latest
624
+ [INFO] Instructions:
625
+ 1. Download the binary for your platform
626
+ 2. Extract the archive
627
+ 3. Replace current executable with new binary
628
+ 4. Restart qBitrr
629
+ ```
630
+
631
+ ---
632
+
633
+ #### 🔧 Manual Updates
634
+
635
+ **Via WebUI:**
636
+ - Navigate to **Config tab**
637
+ - Click **"Check for Updates"** to see available version
638
+ - Click **"Update Now"** button
639
+ - Confirm when prompted
640
+ - Application restarts automatically (git/pip only)
641
+
642
+ **Via Command Line:**
643
+
644
+ ```bash
645
+ # Git installation
646
+ cd /path/to/qBitrr
647
+ git fetch --tags
648
+ git checkout v5.4.3 # or: git pull
649
+ qbitrr # restart
650
+
651
+ # PyPI installation
652
+ pip install --upgrade qBitrr2
653
+ # or: pip install qBitrr2==5.4.3 # specific version
654
+ qbitrr # restart
655
+
656
+ # Binary installation
657
+ # Download from: https://github.com/Feramance/qBitrr/releases/latest
658
+ # Extract and replace binary, then restart
659
+
660
+ # Docker installation
661
+ docker pull feramance/qbitrr:latest
662
+ docker restart qbitrr
663
+ # or: docker-compose pull && docker-compose up -d
664
+ ```
665
+
666
+ ---
667
+
668
+ #### 🔐 Security & Reliability
669
+
670
+ **GitHub API Dependency:**
671
+ - Auto-update requires GitHub API access
672
+ - Rate limit: 60 requests/hour (unauthenticated)
673
+ - Cron schedule should account for rate limits
674
+ - Failures are logged but don't crash the application
675
+
676
+ **Version Verification:**
677
+ - After update, qBitrr verifies installed version
678
+ - Helps catch failed updates or PyPI lag issues
679
+ - Logs warning if version mismatch detected
680
+
681
+ **Draft & Prerelease Handling:**
682
+ - Draft releases are **always skipped** (unpublished)
683
+ - Prereleases (beta/rc/alpha) are skipped by default
684
+ - Useful for testing but not recommended for production
685
+
686
+ **Rollback:**
687
+ - Git installations: `git checkout <previous-tag>`
688
+ - PyPI installations: `pip install qBitrr2==<previous-version>`
689
+ - Binary installations: Keep backup of previous binary
690
+ - No automatic rollback (manual intervention required)
691
+
692
+ ---
693
+
694
+ #### 🚀 Restart Mechanism
695
+
696
+ **How it Works:**
697
+ ```python
698
+ os.execv(sys.executable, [sys.executable] + sys.argv)
699
+ ```
700
+
701
+ **Benefits:**
702
+ - ✅ **Same PID** – systemd doesn't detect a restart
703
+ - ✅ **No supervisor** – doesn't require external process manager
704
+ - ✅ **Clean state** – fresh Python interpreter, no memory leaks
705
+ - ✅ **Fast** – near-instant restart (< 1 second)
706
+
707
+ **Supported Environments:**
708
+ - 🐳 **Docker** – container stays running, process restarts
709
+ - ⚙️ **systemd** – service remains "active", no restart count increment
710
+ - 💻 **Native** – works on Linux, macOS, Windows
711
+ - 🪟 **Windows** – handles different executable extensions (.exe, .cmd)
712
+
713
+ **Graceful Shutdown:**
714
+ 1. Stop all Arr manager child processes
715
+ 2. Close database connections
716
+ 3. Flush log buffers to disk
717
+ 4. Release file locks
718
+ 5. Execute in-place restart
719
+
720
+ ---
554
721
 
555
- **Restart Mechanism:**
556
- - Uses `os.execv()` for in-place process replacement
557
- - Maintains same PID (systemd-friendly)
558
- - Works in Docker, systemd, native installs
559
- - Cross-platform: Linux, macOS, Windows
560
- - Graceful shutdown: closes databases, flushes logs, terminates child processes
722
+ #### 🛠️ Restart via API
561
723
 
562
- **Restart via API:**
724
+ **Restart entire application:**
563
725
  ```bash
564
- # Restart entire application
565
726
  curl -X POST http://localhost:6969/api/restart
566
727
 
567
- # Restart specific Arr manager
728
+ # With authentication
729
+ curl -X POST http://localhost:6969/api/restart \
730
+ -H "Authorization: Bearer your-token"
731
+ ```
732
+
733
+ **Restart specific Arr manager:**
734
+ ```bash
735
+ curl -X POST http://localhost:6969/api/arr/radarr-movies/restart
736
+ ```
737
+
738
+ ---
739
+
740
+ #### ⚠️ Troubleshooting Updates
741
+
742
+ **Update not triggering:**
743
+ - ✅ Check `AutoUpdateEnabled = true` in config
744
+ - ✅ Verify cron expression is valid (use [crontab.guru](https://crontab.guru))
745
+ - ✅ Check `Main.log` for GitHub API errors
746
+ - ✅ Ensure internet connectivity to api.github.com
747
+ - ✅ Check if already on latest version
748
+
749
+ **Version mismatch after update:**
750
+ - ✅ Review logs for pip/git errors
751
+ - ✅ Manually verify installation: `pip show qBitrr2` or `git describe`
752
+ - ✅ Check if PyPI is behind GitHub releases (can take hours)
753
+ - ✅ Try manual update to force correct version
754
+
755
+ **Binary updates not working:**
756
+ - ℹ️ **Expected behavior** – binaries cannot auto-update
757
+ - ✅ Check logs for download URL
758
+ - ✅ Download matching binary for your platform
759
+ - ✅ Extract and replace current executable
760
+ - ✅ Ensure new binary has execute permissions (Unix)
761
+
762
+ **Restart fails:**
763
+ - ✅ Check file permissions on qBitrr installation
764
+ - ✅ Review systemd journal if using systemd
765
+ - ✅ Verify no file locks preventing restart
766
+ - ✅ Check disk space for logs and databases
767
+ - ✅ Manual restart: Stop service, start again
768
+
769
+ **For systemd users:** See [SYSTEMD_SERVICE.md](SYSTEMD_SERVICE.md) for automatic restart configuration with `Restart=always`.
770
+
771
+ ---
772
+
568
773
  curl -X POST http://localhost:6969/api/arr/radarr-movies/restart
569
774
  ```
570
775
 
@@ -1,7 +1,7 @@
1
1
  qBitrr/__init__.py,sha256=smiPIV7d2lMJ_KTtFdAVlxLEBobFTheILdgry1iqpjQ,405
2
2
  qBitrr/arss.py,sha256=350czDlTAjNjOjmD3MwyGVyTTdtIkYWq9Op--pf_qyg,306059
3
- qBitrr/auto_update.py,sha256=hVAvAlKEdOHm6AJLlKvtkklbQhjotVcFOCH-MTigHQM,4419
4
- qBitrr/bundled_data.py,sha256=3TSviBtl6kCS07mHAxADtS9cFVYp0qM-dCKB_I1Oqhg,221
3
+ qBitrr/auto_update.py,sha256=3mqlKKGnaWR5dNI58LN5WbHOMFRDWBsOs0zIC79QzQk,13359
4
+ qBitrr/bundled_data.py,sha256=XwP9k46D_VP_hEj8ZUOi4kqdnmbqfJ2EC660o9_DqJM,221
5
5
  qBitrr/config.py,sha256=e_UL8Jjz2hWAhT53Du8XZpvyY4ULC5mpyus_7i2An18,6306
6
6
  qBitrr/db_lock.py,sha256=SRCDIoqg-AFLU-VDChAmGdfx8nhgLGETn6XKF3RdJT4,2449
7
7
  qBitrr/env_config.py,sha256=299u_uEoyxlM_ceTD0Z_i41JdYjSHmqO6FKe7qGFgTM,2866
@@ -10,12 +10,12 @@ qBitrr/ffprobe.py,sha256=2IM0iuPPTEb0xHmN1OetQoBd80-Nmv5Oq7P6o-mjBd0,4019
10
10
  qBitrr/gen_config.py,sha256=m14KIAgoXgJ3T2uQxErwz8AzEKLanndaxly85C4HZ1M,36903
11
11
  qBitrr/home_path.py,sha256=zvBheAR2xvr8LBZRk1FyqfnALE-eFzsY9CyqyZDjxiE,626
12
12
  qBitrr/logger.py,sha256=f3LNcvl4lizTxQMXjFzv5urpPbUYEkaSGVGFP39cNbk,9005
13
- qBitrr/main.py,sha256=xi-jzN7klPl_FkctqXA2g-_-qNy4px4ELNDDv9QscXo,21746
13
+ qBitrr/main.py,sha256=7aElBeQvfRd3jEpCup8dT3bmyJALCYEAxr1V-pflMyU,23089
14
14
  qBitrr/search_activity_store.py,sha256=_7MD7fFna4uTSo_pRT7DqoytSVz7tPoU9D2AV2mn-oc,2474
15
15
  qBitrr/tables.py,sha256=cumrb5aqJ0Uufu2biDPCIgu1_TP0hlHVi7dgAQKK_bM,3969
16
16
  qBitrr/utils.py,sha256=T10win016yHwMMJlJ4yuPTRUI9m-AS_a_MouiAJAtC8,8190
17
- qBitrr/versioning.py,sha256=00um_zKic8mMrNZ7IHEUPx4ju5Yi_TWCgZxl81IfMaM,3362
18
- qBitrr/webui.py,sha256=qilXSbLdzdWBCprkNbrHYcoLPbZ6ZUFJnMJLIaGEEdg,106980
17
+ qBitrr/versioning.py,sha256=vjQ55rMInuEte9PXQo29FLxF0ff643Ttm3_ri5ghXPM,4542
18
+ qBitrr/webui.py,sha256=Ye88FI1pQboe50RYC_eO4WhwDVe02z8qvT7GmX71m8k,110423
19
19
  qBitrr/static/index.html,sha256=DXgymiLYHct3ViBZq5U9zon_GFmGpZyQAn1ux8k4RjM,2177
20
20
  qBitrr/static/manifest.json,sha256=YusjbJHVB19c7hmETHJdWjrQO-wgujn_tQAwK9NY19s,478
21
21
  qBitrr/static/sw.js,sha256=GtcNS2a7zxoryfwFAvH6OjEkwaqt-qKHIOrys_8bBnU,3035
@@ -24,13 +24,13 @@ qBitrr/static/assets/ArrView.js,sha256=4s0DcHqs9oM6kzYXNV1CRgX-kx7DNnbZCFCJajoYt
24
24
  qBitrr/static/assets/ArrView.js.map,sha256=gh0qL1jRaH4xOIYd1Ta6x6YDp1BMDISzvlkjCUvjXFs,244967
25
25
  qBitrr/static/assets/ConfigView.js,sha256=dUFUJ4-ocIqSSHhWbqjpdplzEkrnkxFmaHUeChyTrDU,59420
26
26
  qBitrr/static/assets/ConfigView.js.map,sha256=4cxC9htmEtmevS8UgM0_B0s2-i3aNWJEEN2RKNwZTpI,236922
27
- qBitrr/static/assets/LogsView.js,sha256=MfLNkzGc6OY0gDQBLow4Tl-IGaOqzWiYwauYXeG20Bk,119895
28
- qBitrr/static/assets/LogsView.js.map,sha256=lByC3sO9MXmQf2SYcSc8bfS02BaMggU7ou_GpG767zc,478868
27
+ qBitrr/static/assets/LogsView.js,sha256=00MUvcG942mkFiY0WIji2G2Yi-fzaePmYY7KV-2Ez5Q,119870
28
+ qBitrr/static/assets/LogsView.js.map,sha256=jPg6_N-WBJJtXycHucdbjvtxTEldeTvxCoo5gmVbxq4,478768
29
29
  qBitrr/static/assets/ProcessesView.js,sha256=C7RX-Sc2NkYVI3TuVfCgvwGmK2Il__aZTT9tDOQWr5Q,8818
30
30
  qBitrr/static/assets/ProcessesView.js.map,sha256=iD2P_qlnCYTpiXcEcdPKrDXQMcDD1QmWLqJYAjpFo5o,31450
31
31
  qBitrr/static/assets/app.css,sha256=fmyeHTEMM2M6w_UwTnF4t8Zdl0SeXKBrXNc5wZtwV7U,53020
32
- qBitrr/static/assets/app.js,sha256=quBUHGs1sH5rvQ-3zc4Rmw9t2qpMI6AAS8g0tcO-u94,27547
33
- qBitrr/static/assets/app.js.map,sha256=BeQo2I2k2bA38J7YNPvKGo08bZJ-51B81eBnkpRLSLI,79806
32
+ qBitrr/static/assets/app.js,sha256=v8BM_seZxtGHmIzQpjorImlOBgdf3GsT8ReYmYAAnRg,28649
33
+ qBitrr/static/assets/app.js.map,sha256=eIA8t0t03NfoQmEuE7DjvczhOQd9ETj150brqsH2-ZM,82920
34
34
  qBitrr/static/assets/build.svg,sha256=27zJoFZFP0MMNjnviRKjOUbGLu2D-1EcIpiMAfOXnJA,46338
35
35
  qBitrr/static/assets/check-mark.svg,sha256=P4sn_w6VKsXjhqzeFYoQmaPtUFJ_QwPWq-aD_dPJJqU,9198
36
36
  qBitrr/static/assets/close.svg,sha256=au7m-xbkwpqz2ZLUi6kj4VzTqIX36eC3dKjPGMUVLnU,8697
@@ -53,9 +53,9 @@ qBitrr/static/assets/useInterval.js.map,sha256=3KvsE2Do5LepkgpP-0XBHeGOprIQiDIdK
53
53
  qBitrr/static/assets/vendor.js,sha256=8hrEIkW0Kqgkr-wYIBomtcyRi-tqq6j_-wAxALpovbM,141758
54
54
  qBitrr/static/assets/vendor.js.map,sha256=P3bGbPmCIVNCeLvUIKZcduGNdt50mpRKRUMsAvGA0R0,344954
55
55
  qBitrr/static/assets/visibility.svg,sha256=258DiSuUKs2SH9dhhDDU88JQfLAlNQMvOGewc9uaTK4,9767
56
- qbitrr2-5.4.3.dist-info/licenses/LICENSE,sha256=P978aVGi7dPbKz8lfvdiryOS5IjTAU7AA47XhBhVBlI,1066
57
- qbitrr2-5.4.3.dist-info/METADATA,sha256=d2jq_fOUVNNgNwlt-f5g1J8BhX5bJ9W69wafgQEguvc,33177
58
- qbitrr2-5.4.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
59
- qbitrr2-5.4.3.dist-info/entry_points.txt,sha256=MIR-l5s31VBs9qlv3HiAaMdpOOyy0MNGfM7Ib1-fKeQ,43
60
- qbitrr2-5.4.3.dist-info/top_level.txt,sha256=jIINodarzsPcQeTf-vvK8-_g7cQ8CvxEg41ms14K97g,7
61
- qbitrr2-5.4.3.dist-info/RECORD,,
56
+ qbitrr2-5.4.4.dist-info/licenses/LICENSE,sha256=P978aVGi7dPbKz8lfvdiryOS5IjTAU7AA47XhBhVBlI,1066
57
+ qbitrr2-5.4.4.dist-info/METADATA,sha256=b_LT87i04KuJltwpK6XAXICfX4NgId1dSHupg794PTw,40012
58
+ qbitrr2-5.4.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
59
+ qbitrr2-5.4.4.dist-info/entry_points.txt,sha256=MIR-l5s31VBs9qlv3HiAaMdpOOyy0MNGfM7Ib1-fKeQ,43
60
+ qbitrr2-5.4.4.dist-info/top_level.txt,sha256=jIINodarzsPcQeTf-vvK8-_g7cQ8CvxEg41ms14K97g,7
61
+ qbitrr2-5.4.4.dist-info/RECORD,,