quasarr 2.6.1__tar.gz → 2.7.0__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.
Potentially problematic release.
This version of quasarr might be problematic. Click here for more details.
- quasarr-2.7.0/.env.example +54 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/workflows/HostnameRedaction.yml +1 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/workflows/PullRequests.yml +12 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/workflows/Release.yml +12 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.gitignore +1 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.pre-commit-config.yaml +1 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/PKG-INFO +4 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/docker/Dockerfile +1 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/pre-commit.py +24 -33
- {quasarr-2.6.1 → quasarr-2.7.0}/pyproject.toml +8 -2
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/__init__.py +71 -61
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/__init__.py +1 -2
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/arr/__init__.py +159 -56
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/captcha/__init__.py +203 -154
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/__init__.py +12 -8
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/linkcrypters/al.py +3 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/linkcrypters/filecrypt.py +1 -2
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/packages/__init__.py +62 -88
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/al.py +3 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/by.py +3 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/he.py +8 -9
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/nk.py +3 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/sl.py +6 -1
- quasarr-2.7.0/quasarr/downloads/sources/wd.py +225 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/wx.py +11 -17
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/auth.py +9 -13
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/cloudflare.py +4 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/imdb_metadata.py +0 -2
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/jd_cache.py +64 -90
- quasarr-2.7.0/quasarr/providers/log.py +237 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/myjd_api.py +116 -94
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/sessions/al.py +20 -22
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/sessions/dd.py +1 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/sessions/dl.py +8 -10
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/sessions/nx.py +1 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/shared_state.py +26 -15
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/utils.py +15 -6
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/version.py +1 -1
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/__init__.py +91 -78
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/al.py +19 -23
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/by.py +6 -6
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/dd.py +8 -10
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/dj.py +15 -18
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/dl.py +25 -37
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/dt.py +13 -15
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/dw.py +24 -16
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/fx.py +25 -11
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/he.py +16 -14
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/hs.py +7 -7
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/mb.py +7 -7
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/nk.py +24 -25
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/nx.py +22 -15
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/sf.py +18 -9
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/sj.py +7 -7
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/sl.py +26 -14
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/wd.py +61 -31
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/wx.py +33 -47
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/storage/config.py +1 -3
- {quasarr-2.6.1 → quasarr-2.7.0}/uv.lock +55 -0
- quasarr-2.6.1/quasarr/downloads/sources/wd.py +0 -169
- quasarr-2.6.1/quasarr/providers/log.py +0 -19
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/FUNDING.yml +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/CONTRIBUTING.md +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/LICENSE +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/Quasarr.png +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/Quasarr.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/README.md +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/docker/dev-services-compose.yml +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/docker/docker-compose.yml +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/config/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/jdownloader/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/packages/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/sponsors_helper/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/api/statistics/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/linkcrypters/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/linkcrypters/hide.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/dd.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/dj.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/dl.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/dt.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/dw.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/hs.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/mb.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/nx.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/sf.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/downloads/sources/sj.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/hostname_issues.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/html_images.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/html_templates.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/notifications.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/obfuscated.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/sessions/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/statistics.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/providers/web_server.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/search/sources/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/storage/__init__.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/storage/setup.py +0 -0
- {quasarr-2.6.1 → quasarr-2.7.0}/quasarr/storage/sqlite_database.py +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Copy this file to .env and set your environment variables
|
|
2
|
+
|
|
3
|
+
# Available log levels:
|
|
4
|
+
# CRIT 50
|
|
5
|
+
# ERROR 40
|
|
6
|
+
# WARN 30
|
|
7
|
+
# INFO 20 (default)
|
|
8
|
+
# DEBUG 10
|
|
9
|
+
# TRACE 5
|
|
10
|
+
#
|
|
11
|
+
# Each log line can have multiple contexts, each context can have its own log level.
|
|
12
|
+
# The most verbose/lowest log level among the contexts will decide whether to log that line.
|
|
13
|
+
|
|
14
|
+
# Base log level
|
|
15
|
+
LOG=INFO
|
|
16
|
+
|
|
17
|
+
# Enable/disable colored log output
|
|
18
|
+
LOG_COLOR=1
|
|
19
|
+
|
|
20
|
+
# Maximum width of log lines (in characters)
|
|
21
|
+
#LOG_MAX_WIDTH=160
|
|
22
|
+
|
|
23
|
+
# Log levels per action:
|
|
24
|
+
#LOG_SEARCH = DEBUG
|
|
25
|
+
#LOG_SOURCES = DEBUG
|
|
26
|
+
#LOG_PROVIDERS = DEBUG
|
|
27
|
+
#LOG_DOWNLOADS = DEBUG
|
|
28
|
+
#LOG_PACKAGES = DEBUG
|
|
29
|
+
#LOG_SHARED_STATE = DEBUG
|
|
30
|
+
#LOG_API = DEBUG
|
|
31
|
+
#LOG_SESSIONS = DEBUG
|
|
32
|
+
#LOG_JD_CACHE = DEBUG
|
|
33
|
+
#LOG_JDPACKAGECACHE = DEBUG
|
|
34
|
+
#LOG_GET_PACKAGES = DEBUG
|
|
35
|
+
|
|
36
|
+
# Log levels per source:
|
|
37
|
+
#LOG_AL = DEBUG
|
|
38
|
+
#LOG_BY = DEBUG
|
|
39
|
+
#LOG_DD = DEBUG
|
|
40
|
+
#LOG_DJ = DEBUG
|
|
41
|
+
#LOG_DD = DEBUG
|
|
42
|
+
#LOG_DT = DEBUG
|
|
43
|
+
#LOG_DW = DEBUG
|
|
44
|
+
#LOG_FX = DEBUG
|
|
45
|
+
#LOG_HE = DEBUG
|
|
46
|
+
#LOG_HS = DEBUG
|
|
47
|
+
#LOG_MB = DEBUG
|
|
48
|
+
#LOG_NK = DEBUG
|
|
49
|
+
#LOG_NX = DEBUG
|
|
50
|
+
#LOG_SF = DEBUG
|
|
51
|
+
#LOG_SJ = DEBUG
|
|
52
|
+
#LOG_SL = DEBUG
|
|
53
|
+
#LOG_WD = DEBUG
|
|
54
|
+
#LOG_WX = DEBUG
|
|
@@ -16,6 +16,7 @@ jobs:
|
|
|
16
16
|
quality-check:
|
|
17
17
|
name: Check & Auto-Fix
|
|
18
18
|
runs-on: ubuntu-latest
|
|
19
|
+
timeout-minutes: 1
|
|
19
20
|
permissions:
|
|
20
21
|
contents: write
|
|
21
22
|
pull-requests: write
|
|
@@ -55,6 +56,7 @@ jobs:
|
|
|
55
56
|
needs: [ quality-check ]
|
|
56
57
|
if: needs.quality-check.outputs.changes_pushed != 'true' && ((github.head_ref == 'dev' && github.base_ref == 'main') || (github.event_name == 'workflow_dispatch' && github.ref_name == 'dev'))
|
|
57
58
|
runs-on: ubuntu-latest
|
|
59
|
+
timeout-minutes: 1
|
|
58
60
|
outputs:
|
|
59
61
|
version: ${{ steps.version.outputs.version }}
|
|
60
62
|
epoch: ${{ steps.version.outputs.epoch }}
|
|
@@ -78,6 +80,7 @@ jobs:
|
|
|
78
80
|
needs: [ quality-check, version ]
|
|
79
81
|
if: needs.quality-check.outputs.changes_pushed != 'true' && ((github.head_ref == 'dev' && github.base_ref == 'main') || (github.event_name == 'workflow_dispatch' && github.ref_name == 'dev'))
|
|
80
82
|
runs-on: ubuntu-latest
|
|
83
|
+
timeout-minutes: 3
|
|
81
84
|
outputs:
|
|
82
85
|
attestation-id: ${{ steps.attest.outputs.attestation-id }}
|
|
83
86
|
permissions:
|
|
@@ -108,9 +111,11 @@ jobs:
|
|
|
108
111
|
needs: [ quality-check, version ]
|
|
109
112
|
if: needs.quality-check.outputs.changes_pushed != 'true' && ((github.head_ref == 'dev' && github.base_ref == 'main') || (github.event_name == 'workflow_dispatch' && github.ref_name == 'dev'))
|
|
110
113
|
runs-on: windows-latest
|
|
114
|
+
timeout-minutes: 3
|
|
111
115
|
env:
|
|
112
116
|
TMP: "D:\\a\\temp"
|
|
113
117
|
TEMP: "D:\\a\\temp"
|
|
118
|
+
PYINSTALLER_CONFIG_DIR: ".pyinstaller-cache"
|
|
114
119
|
steps:
|
|
115
120
|
- run: mkdir D:\a\temp -Force
|
|
116
121
|
- uses: actions/checkout@v6
|
|
@@ -126,7 +131,7 @@ jobs:
|
|
|
126
131
|
with:
|
|
127
132
|
path: |
|
|
128
133
|
build
|
|
129
|
-
|
|
134
|
+
.pyinstaller-cache
|
|
130
135
|
key: pyinstaller-analysis-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
131
136
|
restore-keys: |
|
|
132
137
|
pyinstaller-analysis-${{ runner.os }}-
|
|
@@ -151,6 +156,7 @@ jobs:
|
|
|
151
156
|
beta-release:
|
|
152
157
|
needs: [ version, build-wheel, build-exe ]
|
|
153
158
|
runs-on: ubuntu-latest
|
|
159
|
+
timeout-minutes: 1
|
|
154
160
|
permissions: { contents: write }
|
|
155
161
|
steps:
|
|
156
162
|
- uses: actions/checkout@v6
|
|
@@ -196,6 +202,7 @@ jobs:
|
|
|
196
202
|
needs: [ quality-check, version, build-wheel ]
|
|
197
203
|
if: needs.quality-check.outputs.changes_pushed != 'true' && ((github.head_ref == 'dev' && github.base_ref == 'main') || (github.event_name == 'workflow_dispatch' && github.ref_name == 'dev'))
|
|
198
204
|
runs-on: ubuntu-latest
|
|
205
|
+
timeout-minutes: 3
|
|
199
206
|
steps:
|
|
200
207
|
- uses: actions/checkout@v6
|
|
201
208
|
- uses: actions/download-artifact@v4
|
|
@@ -228,6 +235,7 @@ jobs:
|
|
|
228
235
|
needs: [ quality-check, version, build-wheel ]
|
|
229
236
|
if: needs.quality-check.outputs.changes_pushed != 'true' && ((github.head_ref == 'dev' && github.base_ref == 'main') || (github.event_name == 'workflow_dispatch' && github.ref_name == 'dev'))
|
|
230
237
|
runs-on: ubuntu-24.04-arm
|
|
238
|
+
timeout-minutes: 3
|
|
231
239
|
steps:
|
|
232
240
|
- uses: actions/checkout@v6
|
|
233
241
|
- uses: actions/download-artifact@v4
|
|
@@ -259,6 +267,7 @@ jobs:
|
|
|
259
267
|
merge-docker-manifest:
|
|
260
268
|
needs: [ version, build-docker-amd64, build-docker-arm64 ]
|
|
261
269
|
runs-on: ubuntu-latest
|
|
270
|
+
timeout-minutes: 1
|
|
262
271
|
steps:
|
|
263
272
|
- uses: docker/setup-buildx-action@v3
|
|
264
273
|
- uses: docker/login-action@v3
|
|
@@ -287,6 +296,7 @@ jobs:
|
|
|
287
296
|
needs: [ quality-check, version, beta-release, merge-docker-manifest ]
|
|
288
297
|
if: needs.quality-check.outputs.changes_pushed != 'true' && needs.beta-release.result == 'success'
|
|
289
298
|
runs-on: ubuntu-latest
|
|
299
|
+
timeout-minutes: 1
|
|
290
300
|
permissions:
|
|
291
301
|
pull-requests: write
|
|
292
302
|
contents: read
|
|
@@ -316,6 +326,7 @@ jobs:
|
|
|
316
326
|
job-summary:
|
|
317
327
|
name: 📊 Beta Summary
|
|
318
328
|
runs-on: ubuntu-latest
|
|
329
|
+
timeout-minutes: 1
|
|
319
330
|
needs: [ quality-check, version, beta-release ]
|
|
320
331
|
if: always()
|
|
321
332
|
steps:
|
|
@@ -23,6 +23,7 @@ jobs:
|
|
|
23
23
|
version:
|
|
24
24
|
name: Get Version
|
|
25
25
|
runs-on: ubuntu-latest
|
|
26
|
+
timeout-minutes: 1
|
|
26
27
|
outputs:
|
|
27
28
|
version: ${{ steps.version.outputs.version }}
|
|
28
29
|
steps:
|
|
@@ -44,6 +45,7 @@ jobs:
|
|
|
44
45
|
build-wheel:
|
|
45
46
|
name: Build Wheel
|
|
46
47
|
runs-on: ubuntu-latest
|
|
48
|
+
timeout-minutes: 3
|
|
47
49
|
outputs:
|
|
48
50
|
attestation-id: ${{ steps.attest.outputs.attestation-id }}
|
|
49
51
|
permissions:
|
|
@@ -76,7 +78,10 @@ jobs:
|
|
|
76
78
|
build-exe:
|
|
77
79
|
name: Build Exe (Windows)
|
|
78
80
|
runs-on: windows-latest
|
|
81
|
+
timeout-minutes: 3
|
|
79
82
|
needs: version
|
|
83
|
+
outputs:
|
|
84
|
+
cache-hit: ${{ steps.pyinstaller-cache.outputs.cache-hit }}
|
|
80
85
|
env:
|
|
81
86
|
BUILD_PATH: "build"
|
|
82
87
|
steps:
|
|
@@ -121,6 +126,7 @@ jobs:
|
|
|
121
126
|
build-docker-amd64:
|
|
122
127
|
name: Build Docker (AMD64)
|
|
123
128
|
runs-on: ubuntu-latest
|
|
129
|
+
timeout-minutes: 3
|
|
124
130
|
needs: [ version, build-wheel ]
|
|
125
131
|
steps:
|
|
126
132
|
- uses: actions/checkout@v6
|
|
@@ -160,6 +166,7 @@ jobs:
|
|
|
160
166
|
build-docker-arm64:
|
|
161
167
|
name: Build Docker (ARM64)
|
|
162
168
|
runs-on: ubuntu-24.04-arm
|
|
169
|
+
timeout-minutes: 3
|
|
163
170
|
needs: [ version, build-wheel ]
|
|
164
171
|
steps:
|
|
165
172
|
- uses: actions/checkout@v6
|
|
@@ -199,6 +206,7 @@ jobs:
|
|
|
199
206
|
merge-docker-manifest:
|
|
200
207
|
name: Merge Docker Manifests
|
|
201
208
|
runs-on: ubuntu-latest
|
|
209
|
+
timeout-minutes: 1
|
|
202
210
|
needs: [ version, build-docker-amd64, build-docker-arm64 ]
|
|
203
211
|
steps:
|
|
204
212
|
- uses: docker/setup-buildx-action@v3
|
|
@@ -225,6 +233,7 @@ jobs:
|
|
|
225
233
|
release:
|
|
226
234
|
name: Create Release
|
|
227
235
|
runs-on: ubuntu-latest
|
|
236
|
+
timeout-minutes: 1
|
|
228
237
|
needs: [ version, build-wheel, build-exe, build-docker-amd64, build-docker-arm64 ]
|
|
229
238
|
permissions:
|
|
230
239
|
contents: write
|
|
@@ -269,6 +278,7 @@ jobs:
|
|
|
269
278
|
echo "### Python:" >> release_body.md
|
|
270
279
|
echo "\`uv tool upgrade quasarr\`" >> release_body.md
|
|
271
280
|
if [ -f pr_body.txt ]; then
|
|
281
|
+
echo "" >> release_body.md
|
|
272
282
|
cat pr_body.txt >> release_body.md
|
|
273
283
|
echo "" >> release_body.md
|
|
274
284
|
fi
|
|
@@ -288,6 +298,7 @@ jobs:
|
|
|
288
298
|
needs: [ version, release, merge-docker-manifest ]
|
|
289
299
|
if: always() && needs.release.result == 'success'
|
|
290
300
|
runs-on: ubuntu-latest
|
|
301
|
+
timeout-minutes: 1
|
|
291
302
|
steps:
|
|
292
303
|
- uses: actions/checkout@v6
|
|
293
304
|
- name: Send Discord Webhook
|
|
@@ -313,6 +324,7 @@ jobs:
|
|
|
313
324
|
job-summary:
|
|
314
325
|
name: 📈 Build Report
|
|
315
326
|
runs-on: ubuntu-latest
|
|
327
|
+
timeout-minutes: 1
|
|
316
328
|
needs: [ version, build-wheel, build-exe, build-docker-amd64, build-docker-arm64, release ]
|
|
317
329
|
if: always()
|
|
318
330
|
steps:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quasarr
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.7.0
|
|
4
4
|
Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
|
|
5
5
|
Author-email: rix1337 <rix1337@users.noreply.github.com>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -11,9 +11,12 @@ Requires-Python: >=3.12
|
|
|
11
11
|
Requires-Dist: beautifulsoup4>=4.14.3
|
|
12
12
|
Requires-Dist: bottle>=0.13.4
|
|
13
13
|
Requires-Dist: dukpy>=0.5.0
|
|
14
|
+
Requires-Dist: loguru>=0.7.3
|
|
14
15
|
Requires-Dist: pillow>=12.1.0
|
|
15
16
|
Requires-Dist: pycryptodomex>=3.23.0
|
|
17
|
+
Requires-Dist: python-dotenv>=1.2.1
|
|
16
18
|
Requires-Dist: requests>=2.32.5
|
|
19
|
+
Requires-Dist: wcwidth>=0.5.3
|
|
17
20
|
Description-Content-Type: text/markdown
|
|
18
21
|
|
|
19
22
|
#
|
|
@@ -33,6 +33,7 @@ ENV INTERNAL_ADDRESS=""
|
|
|
33
33
|
ENV EXTERNAL_ADDRESS=""
|
|
34
34
|
ENV DISCORD=""
|
|
35
35
|
ENV HOSTNAMES=""
|
|
36
|
+
ENV LOG_MAX_WIDTH="130"
|
|
36
37
|
|
|
37
38
|
# Restart loop: exit 0 = restart, exit non-zero = stop container
|
|
38
39
|
ENTRYPOINT ["sh", "-c", "while true; do quasarr --port=8080 --internal_address=$INTERNAL_ADDRESS --external_address=$EXTERNAL_ADDRESS --discord=$DISCORD --hostnames=$HOSTNAMES; ret=$?; if [ $ret -ne 0 ]; then echo \"Quasarr exited with error $ret, stopping...\"; exit $ret; fi; echo \"Quasarr restarting...\"; sleep 2; done"]
|
|
@@ -11,16 +11,9 @@ VERSION_FILE = Path("quasarr/providers/version.py")
|
|
|
11
11
|
PYPROJECT_FILE = Path("pyproject.toml")
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def safe_print(msg):
|
|
15
|
-
try:
|
|
16
|
-
print(msg)
|
|
17
|
-
except Exception:
|
|
18
|
-
print(msg.encode("ascii", errors="replace").decode("ascii"))
|
|
19
|
-
|
|
20
|
-
|
|
21
14
|
def run(cmd, check=True, capture=False, text=True):
|
|
22
15
|
"""Helper to run shell commands comfortably."""
|
|
23
|
-
|
|
16
|
+
print(f"⚙️ Exec: {' '.join(cmd)}")
|
|
24
17
|
return subprocess.run(cmd, check=check, capture_output=capture, text=text)
|
|
25
18
|
|
|
26
19
|
|
|
@@ -36,31 +29,29 @@ def git_status_has_changes():
|
|
|
36
29
|
|
|
37
30
|
|
|
38
31
|
def task_format():
|
|
39
|
-
|
|
32
|
+
print("\n🔍 --- 1. FORMATTING & SYNTAX CHECK ---")
|
|
40
33
|
|
|
41
34
|
# Runs Ruff using the rules defined in pyproject.toml
|
|
42
35
|
result = run(["uv", "run", "ruff", "check", "--fix", "."], check=False)
|
|
43
36
|
|
|
44
37
|
if result.returncode != 0:
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
)
|
|
48
|
-
return False
|
|
38
|
+
print("❌ Critical errors or syntax issues found. Fix them before staging.")
|
|
39
|
+
sys.exit(1)
|
|
49
40
|
|
|
50
41
|
# Standard formatting (indentation/spacing)
|
|
51
42
|
run(["uv", "run", "ruff", "format", "."], check=False)
|
|
52
43
|
|
|
53
44
|
if git_status_has_changes():
|
|
54
|
-
|
|
45
|
+
print("✅ Linting fixes applied and staged.")
|
|
55
46
|
run(["git", "add", "."])
|
|
56
47
|
return True
|
|
57
48
|
|
|
58
|
-
|
|
49
|
+
print("✨ Code style is already perfect.")
|
|
59
50
|
return False
|
|
60
51
|
|
|
61
52
|
|
|
62
53
|
def task_upgrade_deps():
|
|
63
|
-
|
|
54
|
+
print("\n📦 --- 2. DEPENDENCIES ---")
|
|
64
55
|
try:
|
|
65
56
|
with open(PYPROJECT_FILE, "rb") as f:
|
|
66
57
|
pyproj = tomllib.load(f)
|
|
@@ -74,7 +65,7 @@ def task_upgrade_deps():
|
|
|
74
65
|
if deps:
|
|
75
66
|
pkgs = [get_pkg_name(d) for d in deps if get_pkg_name(d)]
|
|
76
67
|
if pkgs:
|
|
77
|
-
|
|
68
|
+
print(f"⬆️ Upgrading main: {pkgs}")
|
|
78
69
|
run(["uv", "add", "--upgrade"] + pkgs, check=False)
|
|
79
70
|
|
|
80
71
|
# Groups
|
|
@@ -83,27 +74,27 @@ def task_upgrade_deps():
|
|
|
83
74
|
if g_deps:
|
|
84
75
|
pkgs = [get_pkg_name(d) for d in g_deps if get_pkg_name(d)]
|
|
85
76
|
if pkgs:
|
|
86
|
-
|
|
77
|
+
print(f"🏗️ Upgrading group '{group}': {pkgs}")
|
|
87
78
|
run(
|
|
88
79
|
["uv", "add", "--group", group, "--upgrade"] + pkgs, check=False
|
|
89
80
|
)
|
|
90
81
|
|
|
91
82
|
# Lock file
|
|
92
|
-
|
|
83
|
+
print("🔒 Refreshing lockfile...")
|
|
93
84
|
run(["uv", "lock", "--upgrade"], check=False)
|
|
94
85
|
|
|
95
86
|
except Exception as e:
|
|
96
|
-
|
|
87
|
+
print(f"⚠️ Dependency upgrade failed: {e}")
|
|
97
88
|
|
|
98
89
|
if git_status_has_changes():
|
|
99
|
-
|
|
90
|
+
print("✅ Dependencies updated.")
|
|
100
91
|
run(["git", "add", "."])
|
|
101
92
|
return True
|
|
102
93
|
return False
|
|
103
94
|
|
|
104
95
|
|
|
105
96
|
def task_version_bump():
|
|
106
|
-
|
|
97
|
+
print("\n🏷️ --- 3. VERSION CHECK ---")
|
|
107
98
|
new_v = ""
|
|
108
99
|
|
|
109
100
|
def get_ver(content):
|
|
@@ -127,7 +118,7 @@ def task_version_bump():
|
|
|
127
118
|
return (0, 0, 0)
|
|
128
119
|
|
|
129
120
|
try:
|
|
130
|
-
|
|
121
|
+
print("🌐 Fetching remote to compare versions...")
|
|
131
122
|
run(["git", "fetch", "origin", "main"], check=False)
|
|
132
123
|
try:
|
|
133
124
|
base = subprocess.check_output(
|
|
@@ -148,11 +139,11 @@ def task_version_bump():
|
|
|
148
139
|
# Read Current Version
|
|
149
140
|
curr_v = get_ver(VERSION_FILE.read_text())
|
|
150
141
|
|
|
151
|
-
|
|
142
|
+
print(f"📊 Main: {main_v} | Current: {curr_v}")
|
|
152
143
|
|
|
153
144
|
if main_v and curr_v and ver_tuple(curr_v) <= ver_tuple(main_v):
|
|
154
145
|
new_v = bump(main_v)
|
|
155
|
-
|
|
146
|
+
print(f"🚀 Bumping version to: {new_v}")
|
|
156
147
|
content = VERSION_FILE.read_text().replace(f'"{curr_v}"', f'"{new_v}"')
|
|
157
148
|
VERSION_FILE.write_text(content)
|
|
158
149
|
|
|
@@ -160,7 +151,7 @@ def task_version_bump():
|
|
|
160
151
|
return True, new_v
|
|
161
152
|
|
|
162
153
|
except Exception as e:
|
|
163
|
-
|
|
154
|
+
print(f"⚠️ Version check warning (non-fatal): {e}")
|
|
164
155
|
|
|
165
156
|
return False, new_v
|
|
166
157
|
|
|
@@ -179,7 +170,7 @@ def main():
|
|
|
179
170
|
|
|
180
171
|
# --- CI Specific Logic ---
|
|
181
172
|
if is_ci and (fixed_format or fixed_deps or fixed_version):
|
|
182
|
-
|
|
173
|
+
print("\n📤 --- 4. PUSH & REPORT ---")
|
|
183
174
|
|
|
184
175
|
run(["git", "config", "--global", "user.name", "github-actions[bot]"])
|
|
185
176
|
run(
|
|
@@ -208,7 +199,7 @@ def main():
|
|
|
208
199
|
try:
|
|
209
200
|
run(["git", "commit", "-m", msg])
|
|
210
201
|
target_ref = get_env("TARGET_REF")
|
|
211
|
-
|
|
202
|
+
print(f"🔄 Rebase and pushing to {target_ref}...")
|
|
212
203
|
run(["git", "pull", "--rebase", "origin", target_ref], check=False)
|
|
213
204
|
run(["git", "push", "origin", f"HEAD:{target_ref}"])
|
|
214
205
|
|
|
@@ -216,7 +207,7 @@ def main():
|
|
|
216
207
|
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
217
208
|
f.write("changes_pushed=true\n")
|
|
218
209
|
except subprocess.CalledProcessError as e:
|
|
219
|
-
|
|
210
|
+
print(f"❌ ::error::Failed to push fixes. ({e})")
|
|
220
211
|
sys.exit(1)
|
|
221
212
|
|
|
222
213
|
repo = get_env("GITHUB_REPO")
|
|
@@ -236,7 +227,7 @@ def main():
|
|
|
236
227
|
pass
|
|
237
228
|
|
|
238
229
|
if pr_num:
|
|
239
|
-
|
|
230
|
+
print(f"💬 Posting status update to PR #{pr_num}...")
|
|
240
231
|
fixes_list = ""
|
|
241
232
|
if fixed_format:
|
|
242
233
|
fixes_list += "- ✅ **Formatted Code**\n"
|
|
@@ -265,18 +256,18 @@ def main():
|
|
|
265
256
|
check=False,
|
|
266
257
|
)
|
|
267
258
|
|
|
268
|
-
|
|
259
|
+
print(f"⚡ Triggering workflow: {workflow_name}...")
|
|
269
260
|
ret = run(
|
|
270
261
|
["gh", "workflow", "run", workflow_name, "--ref", target_ref], check=False
|
|
271
262
|
)
|
|
272
263
|
|
|
273
264
|
if ret.returncode != 0:
|
|
274
|
-
|
|
265
|
+
print("⚠️ ::warning::Could not auto-trigger next run.")
|
|
275
266
|
|
|
276
267
|
sys.exit(0)
|
|
277
268
|
|
|
278
269
|
else:
|
|
279
|
-
|
|
270
|
+
print("\n✨ Clean run. No changes needed.")
|
|
280
271
|
if "GITHUB_OUTPUT" in os.environ:
|
|
281
272
|
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
|
|
282
273
|
f.write("changes_pushed=false\n")
|
|
@@ -8,9 +8,12 @@ dependencies = [
|
|
|
8
8
|
"beautifulsoup4>=4.14.3",
|
|
9
9
|
"bottle>=0.13.4",
|
|
10
10
|
"dukpy>=0.5.0",
|
|
11
|
+
"loguru>=0.7.3",
|
|
11
12
|
"pillow>=12.1.0",
|
|
12
13
|
"pycryptodomex>=3.23.0",
|
|
14
|
+
"python-dotenv>=1.2.1",
|
|
13
15
|
"requests>=2.32.5",
|
|
16
|
+
"wcwidth>=0.5.3",
|
|
14
17
|
]
|
|
15
18
|
authors = [
|
|
16
19
|
{ name = "rix1337", email = "rix1337@users.noreply.github.com" }
|
|
@@ -45,8 +48,11 @@ build = [
|
|
|
45
48
|
]
|
|
46
49
|
|
|
47
50
|
[tool.ruff]
|
|
48
|
-
#
|
|
49
|
-
|
|
51
|
+
# F = Pyflakes (Critical: F821 catches undefined names)
|
|
52
|
+
# I = Isort (Import sorting)
|
|
53
|
+
# PLE = Pylint Errors (Catches robust logic errors like used-before-assignment)
|
|
54
|
+
# B = Bugbear (Catches common runtime crash bugs and potential logical errors)
|
|
55
|
+
lint.select = ["F", "I", "PLE", "B"]
|
|
50
56
|
lint.fixable = ["F", "I"]
|
|
51
57
|
lint.ignore = ["E"]
|
|
52
58
|
|