quasarr 2.4.9__tar.gz → 2.4.11__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.4.11/.github/workflows/PullRequests.yml +341 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/.github/workflows/Release.yml +55 -67
- {quasarr-2.4.9 → quasarr-2.4.11}/.gitignore +4 -0
- quasarr-2.4.11/.pre-commit-config.yaml +9 -0
- quasarr-2.4.9/docker/dev-setup.md → quasarr-2.4.11/CONTRIBUTING.md +10 -17
- {quasarr-2.4.9 → quasarr-2.4.11}/PKG-INFO +3 -2
- {quasarr-2.4.9 → quasarr-2.4.11}/README.md +2 -1
- quasarr-2.4.11/pre-commit.py +273 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/pyproject.toml +5 -2
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/__init__.py +3 -3
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/__init__.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/captcha/__init__.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/config/__init__.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/sponsors_helper/__init__.py +2 -2
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/hide.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/packages/__init__.py +5 -5
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/al.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/dw.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/sf.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/notifications.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/shared_state.py +0 -6
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/version.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/al.py +0 -5
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/he.py +1 -2
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/storage/sqlite_database.py +1 -1
- {quasarr-2.4.9 → quasarr-2.4.11}/uv.lock +135 -1
- quasarr-2.4.9/.github/workflows/PullRequests.yml +0 -434
- {quasarr-2.4.9 → quasarr-2.4.11}/.github/FUNDING.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/.github/ISSUE_TEMPLATE/config.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/.github/workflows/HostnameRedaction.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/LICENSE +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/Quasarr.png +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/Quasarr.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/docker/Dockerfile +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/docker/dev-services-compose.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/docker/docker-compose.yml +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/arr/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/packages/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/api/statistics/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/al.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/by.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/dd.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/dj.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/dl.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/dt.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/he.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/mb.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/nk.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/nx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/sj.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/sl.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/wd.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/downloads/sources/wx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/auth.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/cloudflare.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/hostname_issues.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/html_images.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/html_templates.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/imdb_metadata.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/jd_cache.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/log.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/myjd_api.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/obfuscated.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/sessions/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/sessions/al.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/sessions/dd.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/sessions/dl.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/sessions/nx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/statistics.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/utils.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/providers/web_server.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/by.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/dd.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/dj.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/dl.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/dt.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/dw.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/fx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/mb.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/nk.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/nx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/sf.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/sj.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/sl.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/wd.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/search/sources/wx.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/storage/__init__.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/storage/config.py +0 -0
- {quasarr-2.4.9 → quasarr-2.4.11}/quasarr/storage/setup.py +0 -0
|
@@ -0,0 +1,341 @@
|
|
|
1
|
+
name: Pull Requests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
workflow_dispatch:
|
|
5
|
+
pull_request:
|
|
6
|
+
|
|
7
|
+
concurrency:
|
|
8
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
9
|
+
cancel-in-progress: true
|
|
10
|
+
|
|
11
|
+
env:
|
|
12
|
+
GHCR_ENDPOINT: "ghcr.io/rix1337/quasarr"
|
|
13
|
+
DESCRIPTION: "Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian."
|
|
14
|
+
|
|
15
|
+
jobs:
|
|
16
|
+
quality-check:
|
|
17
|
+
name: Check & Auto-Fix
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
permissions:
|
|
20
|
+
contents: write
|
|
21
|
+
pull-requests: write
|
|
22
|
+
actions: write
|
|
23
|
+
outputs:
|
|
24
|
+
changes_pushed: ${{ steps.manager.outputs.changes_pushed }}
|
|
25
|
+
steps:
|
|
26
|
+
- uses: actions/checkout@v6
|
|
27
|
+
with:
|
|
28
|
+
repository: ${{ github.event.pull_request.head.repo.full_name || github.repository }}
|
|
29
|
+
ref: ${{ github.head_ref || github.ref_name }}
|
|
30
|
+
fetch-depth: 0
|
|
31
|
+
|
|
32
|
+
- name: Install uv
|
|
33
|
+
uses: astral-sh/setup-uv@v5
|
|
34
|
+
with:
|
|
35
|
+
enable-cache: true
|
|
36
|
+
|
|
37
|
+
- run: |
|
|
38
|
+
echo "🐍 Installing Python 3.12..."
|
|
39
|
+
uv python install 3.12
|
|
40
|
+
|
|
41
|
+
- name: Run Maintenance
|
|
42
|
+
id: manager
|
|
43
|
+
env:
|
|
44
|
+
GH_TOKEN: ${{ github.token }}
|
|
45
|
+
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
46
|
+
TARGET_REF: ${{ github.head_ref || github.ref_name }}
|
|
47
|
+
GITHUB_REPO: ${{ github.repository }}
|
|
48
|
+
WORKFLOW_NAME: ${{ github.workflow }}
|
|
49
|
+
run: |
|
|
50
|
+
echo "🛠️ Running pre-commit.py..."
|
|
51
|
+
uv run pre-commit.py --ci
|
|
52
|
+
echo "✨ Maintenance complete."
|
|
53
|
+
|
|
54
|
+
version:
|
|
55
|
+
needs: [ quality-check ]
|
|
56
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && (github.head_ref || github.ref_name) == 'dev'
|
|
57
|
+
runs-on: ubuntu-latest
|
|
58
|
+
outputs:
|
|
59
|
+
version: ${{ steps.version.outputs.version }}
|
|
60
|
+
steps:
|
|
61
|
+
- uses: actions/checkout@v6
|
|
62
|
+
- uses: actions/setup-python@v5
|
|
63
|
+
with:
|
|
64
|
+
python-version: '3.12'
|
|
65
|
+
- uses: astral-sh/setup-uv@v5
|
|
66
|
+
with:
|
|
67
|
+
enable-cache: true
|
|
68
|
+
- id: version
|
|
69
|
+
run: |
|
|
70
|
+
VERSION=$(uv run python quasarr/providers/version.py)
|
|
71
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
72
|
+
echo "🏷️ Detected version: $VERSION"
|
|
73
|
+
|
|
74
|
+
build-wheel:
|
|
75
|
+
needs: [ quality-check, version ]
|
|
76
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && (github.head_ref || github.ref_name) == 'dev'
|
|
77
|
+
runs-on: ubuntu-latest
|
|
78
|
+
outputs:
|
|
79
|
+
attestation-id: ${{ steps.attest.outputs.attestation-id }}
|
|
80
|
+
permissions:
|
|
81
|
+
contents: read
|
|
82
|
+
id-token: write
|
|
83
|
+
attestations: write
|
|
84
|
+
steps:
|
|
85
|
+
- uses: actions/checkout@v6
|
|
86
|
+
- uses: actions/setup-python@v5
|
|
87
|
+
with:
|
|
88
|
+
python-version: '3.12'
|
|
89
|
+
- uses: astral-sh/setup-uv@v5
|
|
90
|
+
with:
|
|
91
|
+
enable-cache: true
|
|
92
|
+
- run: |
|
|
93
|
+
echo "📦 Building Python Wheel..."
|
|
94
|
+
uv build
|
|
95
|
+
- id: attest
|
|
96
|
+
uses: actions/attest-build-provenance@v2
|
|
97
|
+
with:
|
|
98
|
+
subject-path: "dist/*.whl"
|
|
99
|
+
- uses: actions/upload-artifact@v4
|
|
100
|
+
with:
|
|
101
|
+
name: wheel
|
|
102
|
+
path: ./dist/*
|
|
103
|
+
|
|
104
|
+
build-exe:
|
|
105
|
+
needs: [ quality-check, version ]
|
|
106
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && (github.head_ref || github.ref_name) == 'dev'
|
|
107
|
+
runs-on: windows-latest
|
|
108
|
+
env:
|
|
109
|
+
TMP: "D:\\a\\temp"
|
|
110
|
+
TEMP: "D:\\a\\temp"
|
|
111
|
+
steps:
|
|
112
|
+
- run: mkdir D:\a\temp -Force
|
|
113
|
+
- uses: actions/checkout@v6
|
|
114
|
+
- uses: actions/setup-python@v5
|
|
115
|
+
with:
|
|
116
|
+
python-version: '3.12'
|
|
117
|
+
- uses: astral-sh/setup-uv@v5
|
|
118
|
+
with:
|
|
119
|
+
enable-cache: true
|
|
120
|
+
cache-suffix: "win-build"
|
|
121
|
+
- name: Cache PyInstaller Analysis
|
|
122
|
+
uses: actions/cache@v4
|
|
123
|
+
with:
|
|
124
|
+
path: |
|
|
125
|
+
build
|
|
126
|
+
~\AppData\Local\pyinstaller
|
|
127
|
+
key: pyinstaller-analysis-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
128
|
+
restore-keys: |
|
|
129
|
+
pyinstaller-analysis-${{ runner.os }}-
|
|
130
|
+
- shell: powershell
|
|
131
|
+
run: |
|
|
132
|
+
echo "🛡️ Disabling Real-time Monitoring..."
|
|
133
|
+
Set-MpPreference -DisableRealtimeMonitoring $true
|
|
134
|
+
- run: |
|
|
135
|
+
echo "📥 Syncing dependencies..."
|
|
136
|
+
uv sync --group build
|
|
137
|
+
- run: |
|
|
138
|
+
echo "🪟 Starting PyInstaller build..."
|
|
139
|
+
uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
|
|
140
|
+
uv run python quasarr/providers/version.py --create-version-file
|
|
141
|
+
uv run pyinstaller --onefile -y --version-file "file_version_info.txt" --workpath "build" --distpath "dist" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
|
|
142
|
+
echo "✅ EXE build finished."
|
|
143
|
+
- uses: actions/upload-artifact@v4
|
|
144
|
+
with:
|
|
145
|
+
name: exe-amd64
|
|
146
|
+
path: ./dist/*.exe
|
|
147
|
+
|
|
148
|
+
beta-release:
|
|
149
|
+
needs: [ version, build-wheel, build-exe ]
|
|
150
|
+
runs-on: ubuntu-latest
|
|
151
|
+
permissions: { contents: write }
|
|
152
|
+
steps:
|
|
153
|
+
- uses: actions/checkout@v6
|
|
154
|
+
with:
|
|
155
|
+
fetch-depth: 0
|
|
156
|
+
- uses: actions/download-artifact@v4
|
|
157
|
+
with:
|
|
158
|
+
name: wheel
|
|
159
|
+
path: ./wheel
|
|
160
|
+
- uses: actions/download-artifact@v4
|
|
161
|
+
with:
|
|
162
|
+
name: exe-amd64
|
|
163
|
+
path: ./exe-amd64
|
|
164
|
+
- id: changelog
|
|
165
|
+
uses: metcalfc/changelog-generator@v4.6.2
|
|
166
|
+
with:
|
|
167
|
+
myToken: ${{ secrets.GITHUB_TOKEN }}
|
|
168
|
+
- name: Create Release Body
|
|
169
|
+
run: |
|
|
170
|
+
echo "📝 Generating Release Body..."
|
|
171
|
+
echo "### Docker:" > release_body.md
|
|
172
|
+
echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:beta\`" >> release_body.md
|
|
173
|
+
echo "### Python:" >> release_body.md
|
|
174
|
+
echo "\`uv tool upgrade quasarr\`" >> release_body.md
|
|
175
|
+
echo "### Changelog:" >> release_body.md
|
|
176
|
+
echo "${{ steps.changelog.outputs.changelog }}" >> release_body.md
|
|
177
|
+
echo "[Attestation](https://github.com/${{ github.repository }}/attestations/${{ needs.build-wheel.outputs.attestation-id }})" >> release_body.md
|
|
178
|
+
- uses: ncipollo/release-action@v1
|
|
179
|
+
with:
|
|
180
|
+
artifacts: "./wheel/*.whl,./exe-amd64/*.exe"
|
|
181
|
+
allowUpdates: true
|
|
182
|
+
removeArtifacts: true
|
|
183
|
+
replacesArtifacts: true
|
|
184
|
+
tag: beta
|
|
185
|
+
name: Beta Build
|
|
186
|
+
bodyFile: "release_body.md"
|
|
187
|
+
prerelease: true
|
|
188
|
+
token: ${{ secrets.GITHUB_TOKEN }}
|
|
189
|
+
|
|
190
|
+
build-docker-amd64:
|
|
191
|
+
needs: [ quality-check, version, build-wheel ]
|
|
192
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && (github.head_ref || github.ref_name) == 'dev'
|
|
193
|
+
runs-on: ubuntu-latest
|
|
194
|
+
steps:
|
|
195
|
+
- uses: actions/checkout@v6
|
|
196
|
+
- uses: actions/download-artifact@v4
|
|
197
|
+
with:
|
|
198
|
+
name: wheel
|
|
199
|
+
path: ./docker/dist
|
|
200
|
+
- uses: docker/setup-buildx-action@v3
|
|
201
|
+
- uses: docker/login-action@v3
|
|
202
|
+
with:
|
|
203
|
+
registry: ghcr.io
|
|
204
|
+
username: ${{ github.actor }}
|
|
205
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
206
|
+
- name: Build and Push
|
|
207
|
+
uses: docker/build-push-action@v6
|
|
208
|
+
with:
|
|
209
|
+
context: ./docker
|
|
210
|
+
platforms: linux/amd64
|
|
211
|
+
push: true
|
|
212
|
+
provenance: false
|
|
213
|
+
sbom: false
|
|
214
|
+
annotations: org.opencontainers.image.description=${{ env.DESCRIPTION }}
|
|
215
|
+
tags: |
|
|
216
|
+
${{ env.GHCR_ENDPOINT }}:beta-amd64
|
|
217
|
+
${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }}-beta-amd64
|
|
218
|
+
build-args: VS=${{ needs.version.outputs.version }}
|
|
219
|
+
cache-from: type=gha,scope=beta-amd64
|
|
220
|
+
cache-to: type=gha,mode=max,scope=beta-amd64
|
|
221
|
+
|
|
222
|
+
build-docker-arm64:
|
|
223
|
+
needs: [ quality-check, version, build-wheel ]
|
|
224
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && (github.head_ref || github.ref_name) == 'dev'
|
|
225
|
+
runs-on: ubuntu-24.04-arm
|
|
226
|
+
steps:
|
|
227
|
+
- uses: actions/checkout@v6
|
|
228
|
+
- uses: actions/download-artifact@v4
|
|
229
|
+
with:
|
|
230
|
+
name: wheel
|
|
231
|
+
path: ./docker/dist
|
|
232
|
+
- uses: docker/setup-buildx-action@v3
|
|
233
|
+
- uses: docker/login-action@v3
|
|
234
|
+
with:
|
|
235
|
+
registry: ghcr.io
|
|
236
|
+
username: ${{ github.actor }}
|
|
237
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
238
|
+
- name: Build and Push
|
|
239
|
+
uses: docker/build-push-action@v6
|
|
240
|
+
with:
|
|
241
|
+
context: ./docker
|
|
242
|
+
platforms: linux/arm64
|
|
243
|
+
push: true
|
|
244
|
+
provenance: false
|
|
245
|
+
sbom: false
|
|
246
|
+
annotations: org.opencontainers.image.description=${{ env.DESCRIPTION }}
|
|
247
|
+
tags: |
|
|
248
|
+
${{ env.GHCR_ENDPOINT }}:beta-arm64
|
|
249
|
+
${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }}-beta-arm64
|
|
250
|
+
build-args: VS=${{ needs.version.outputs.version }}
|
|
251
|
+
cache-from: type=gha,scope=beta-arm64
|
|
252
|
+
cache-to: type=gha,mode=max,scope=beta-arm64
|
|
253
|
+
|
|
254
|
+
merge-docker-manifest:
|
|
255
|
+
needs: [ version, build-docker-amd64, build-docker-arm64 ]
|
|
256
|
+
runs-on: ubuntu-latest
|
|
257
|
+
steps:
|
|
258
|
+
- uses: docker/setup-buildx-action@v3
|
|
259
|
+
- uses: docker/login-action@v3
|
|
260
|
+
with:
|
|
261
|
+
registry: ghcr.io
|
|
262
|
+
username: ${{ github.actor }}
|
|
263
|
+
password: ${{ secrets.GITHUB_TOKEN }}
|
|
264
|
+
- run: |
|
|
265
|
+
echo "🔗 Merging Docker manifests..."
|
|
266
|
+
TAG_AMD64="${{ needs.version.outputs.version }}-beta-amd64"
|
|
267
|
+
TAG_ARM64="${{ needs.version.outputs.version }}-beta-arm64"
|
|
268
|
+
ANNOTATION="index:org.opencontainers.image.description=$DESCRIPTION"
|
|
269
|
+
|
|
270
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:beta \
|
|
271
|
+
--annotation "$ANNOTATION" \
|
|
272
|
+
${{ env.GHCR_ENDPOINT }}:beta-amd64 \
|
|
273
|
+
${{ env.GHCR_ENDPOINT }}:beta-arm64
|
|
274
|
+
|
|
275
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }}-beta \
|
|
276
|
+
--annotation "$ANNOTATION" \
|
|
277
|
+
${{ env.GHCR_ENDPOINT }}:${TAG_AMD64} \
|
|
278
|
+
${{ env.GHCR_ENDPOINT }}:${TAG_ARM64}
|
|
279
|
+
|
|
280
|
+
notify:
|
|
281
|
+
name: Notify Discord & PR
|
|
282
|
+
needs: [ quality-check, version, beta-release, merge-docker-manifest ]
|
|
283
|
+
if: needs.quality-check.outputs.changes_pushed != 'true' && needs.beta-release.result == 'success'
|
|
284
|
+
runs-on: ubuntu-latest
|
|
285
|
+
permissions:
|
|
286
|
+
pull-requests: write
|
|
287
|
+
contents: read
|
|
288
|
+
steps:
|
|
289
|
+
- uses: actions/checkout@v6
|
|
290
|
+
- name: Send Notifications
|
|
291
|
+
env:
|
|
292
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
293
|
+
DISCORD_WEBHOOK: ${{ secrets.DISCORD_WEBHOOK }}
|
|
294
|
+
VERSION: ${{ needs.version.outputs.version }}
|
|
295
|
+
REPO: ${{ github.repository }}
|
|
296
|
+
run: |
|
|
297
|
+
echo "📢 Notifying stakeholders..."
|
|
298
|
+
RELEASE_BODY=$(gh release view beta --json body --jq .body)
|
|
299
|
+
if [ -n "$DISCORD_WEBHOOK" ]; then
|
|
300
|
+
jq -n --arg title "🚀 New Beta Build: $VERSION" --arg desc "$RELEASE_BODY" --arg url "https://github.com/$REPO/releases/tag/beta" '{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5814783}]}' > discord_payload.json
|
|
301
|
+
curl -H "Content-Type: application/json" -d @discord_payload.json "$DISCORD_WEBHOOK"
|
|
302
|
+
fi
|
|
303
|
+
PR_NUMBER=$(gh pr list --search "${{ github.sha }}" --state merged --json number --jq '.[0].number')
|
|
304
|
+
if [ -n "$PR_NUMBER" ]; then
|
|
305
|
+
echo "## 🚀 Beta Release $VERSION is Live!" > pr_comment.md
|
|
306
|
+
echo "$RELEASE_BODY" >> pr_comment.md
|
|
307
|
+
gh pr comment "$PR_NUMBER" --body-file pr_comment.md
|
|
308
|
+
fi
|
|
309
|
+
|
|
310
|
+
job-summary:
|
|
311
|
+
name: 📊 Beta Summary
|
|
312
|
+
runs-on: ubuntu-latest
|
|
313
|
+
needs: [ quality-check, version, beta-release ]
|
|
314
|
+
if: always()
|
|
315
|
+
steps:
|
|
316
|
+
- name: Generate Summary
|
|
317
|
+
run: |
|
|
318
|
+
echo "## 🧪 Beta Build Summary" >> $GITHUB_STEP_SUMMARY
|
|
319
|
+
|
|
320
|
+
# Maintenance Outcome
|
|
321
|
+
if [[ "${{ needs.quality-check.outputs.changes_pushed }}" == "true" ]]; then
|
|
322
|
+
echo "### 🛠️ Maintenance Status: **Auto-Fixed**" >> $GITHUB_STEP_SUMMARY
|
|
323
|
+
echo "The script found formatting or dependency issues and pushed fixes directly. The current build was skipped to allow the new commit to run." >> $GITHUB_STEP_SUMMARY
|
|
324
|
+
else
|
|
325
|
+
echo "### ✨ Maintenance Status: **Clean**" >> $GITHUB_STEP_SUMMARY
|
|
326
|
+
echo "No formatting or maintenance issues were detected." >> $GITHUB_STEP_SUMMARY
|
|
327
|
+
fi
|
|
328
|
+
|
|
329
|
+
# Decision Logic
|
|
330
|
+
echo "### 🚦 Workflow Decision" >> $GITHUB_STEP_SUMMARY
|
|
331
|
+
if [[ "${{ needs.version.result }}" == "success" ]]; then
|
|
332
|
+
echo "✅ **Proceeded:** The build moved to beta release (Dev branch detected)." >> $GITHUB_STEP_SUMMARY
|
|
333
|
+
else
|
|
334
|
+
echo "🛑 **Stopped:** Build did not proceed to release (Not on dev or quality-check failed)." >> $GITHUB_STEP_SUMMARY
|
|
335
|
+
fi
|
|
336
|
+
|
|
337
|
+
echo "### 📦 Artifact Details" >> $GITHUB_STEP_SUMMARY
|
|
338
|
+
echo "| Metric | Value |" >> $GITHUB_STEP_SUMMARY
|
|
339
|
+
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
|
340
|
+
echo "| **Version** | \`${{ needs.version.outputs.version || 'N/A' }}\` |" >> $GITHUB_STEP_SUMMARY
|
|
341
|
+
echo "| **Release Job** | ${{ needs.beta-release.result || 'Skipped' }} |" >> $GITHUB_STEP_SUMMARY
|
|
@@ -37,7 +37,9 @@ jobs:
|
|
|
37
37
|
- name: Get Version
|
|
38
38
|
id: version
|
|
39
39
|
run: |
|
|
40
|
-
|
|
40
|
+
VERSION=$(uv run python quasarr/providers/version.py)
|
|
41
|
+
echo "version=$VERSION" >> $GITHUB_OUTPUT
|
|
42
|
+
echo "🏷️ Version: $VERSION"
|
|
41
43
|
|
|
42
44
|
build-wheel:
|
|
43
45
|
name: Build Wheel
|
|
@@ -58,7 +60,9 @@ jobs:
|
|
|
58
60
|
with:
|
|
59
61
|
enable-cache: true
|
|
60
62
|
- name: Build wheel
|
|
61
|
-
run:
|
|
63
|
+
run: |
|
|
64
|
+
echo "📦 Starting Wheel build..."
|
|
65
|
+
uv build
|
|
62
66
|
- name: Generate artifact attestation
|
|
63
67
|
id: attest
|
|
64
68
|
uses: actions/attest-build-provenance@v2
|
|
@@ -74,35 +78,41 @@ jobs:
|
|
|
74
78
|
runs-on: windows-latest
|
|
75
79
|
needs: version
|
|
76
80
|
env:
|
|
77
|
-
|
|
78
|
-
TEMP: D:\a\temp
|
|
81
|
+
BUILD_PATH: "build"
|
|
79
82
|
steps:
|
|
80
|
-
- name: Create Temp Dir
|
|
81
|
-
run: mkdir D:\a\temp -Force
|
|
82
83
|
- uses: actions/checkout@v6
|
|
83
84
|
- uses: actions/setup-python@v5
|
|
84
85
|
with:
|
|
85
86
|
python-version: '3.12'
|
|
86
|
-
|
|
87
87
|
- name: Install uv
|
|
88
88
|
uses: astral-sh/setup-uv@v5
|
|
89
89
|
with:
|
|
90
90
|
enable-cache: true
|
|
91
|
-
|
|
91
|
+
cache-suffix: "win-build"
|
|
92
|
+
- name: Cache PyInstaller Analysis
|
|
93
|
+
uses: actions/cache@v4
|
|
94
|
+
id: pyinstaller-cache
|
|
95
|
+
with:
|
|
96
|
+
path: |
|
|
97
|
+
build
|
|
98
|
+
~\AppData\Local\pyinstaller
|
|
99
|
+
key: pyinstaller-analysis-${{ runner.os }}-${{ hashFiles('uv.lock') }}
|
|
100
|
+
restore-keys: |
|
|
101
|
+
pyinstaller-analysis-${{ runner.os }}-
|
|
92
102
|
- name: Disable Windows Defender
|
|
93
103
|
shell: powershell
|
|
94
104
|
run: Set-MpPreference -DisableRealtimeMonitoring $true
|
|
95
|
-
|
|
96
105
|
- name: Install dependencies
|
|
97
106
|
run: |
|
|
107
|
+
echo "📥 Installing build dependencies..."
|
|
98
108
|
uv sync --group build
|
|
99
|
-
|
|
100
109
|
- name: Build exe
|
|
101
110
|
run: |
|
|
111
|
+
echo "🪟 Building Windows Binary..."
|
|
102
112
|
uv run python -c "from PIL import Image; Image.open('Quasarr.png').save('Quasarr.ico')"
|
|
103
113
|
uv run python quasarr/providers/version.py --create-version-file
|
|
104
|
-
uv run pyinstaller --
|
|
105
|
-
|
|
114
|
+
uv run pyinstaller --onefile -y --version-file "file_version_info.txt" --workpath "build" --distpath "dist" --icon "Quasarr.ico" "Quasarr.py" -n "quasarr-${{ needs.version.outputs.version }}-standalone-win64"
|
|
115
|
+
echo "✨ Windows binary created."
|
|
106
116
|
- uses: actions/upload-artifact@v4
|
|
107
117
|
with:
|
|
108
118
|
name: exe-amd64
|
|
@@ -203,27 +213,14 @@ jobs:
|
|
|
203
213
|
password: ${{ secrets.GITHUB_TOKEN }}
|
|
204
214
|
- name: Create and Push Manifests
|
|
205
215
|
run: |
|
|
216
|
+
echo "🔗 Linking Multi-arch images..."
|
|
206
217
|
TAG_AMD64="${{ needs.version.outputs.version }}-amd64"
|
|
207
218
|
TAG_ARM64="${{ needs.version.outputs.version }}-arm64"
|
|
208
219
|
ANNOTATION="index:org.opencontainers.image.description=$DESCRIPTION"
|
|
209
|
-
|
|
210
|
-
docker buildx imagetools create -t ${{ env.ENDPOINT }}
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
docker buildx imagetools create -t ${{ env.ENDPOINT }}:${{ needs.version.outputs.version }} \
|
|
215
|
-
${{ env.ENDPOINT }}:${TAG_AMD64} \
|
|
216
|
-
${{ env.ENDPOINT }}:${TAG_ARM64}
|
|
217
|
-
|
|
218
|
-
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:latest \
|
|
219
|
-
--annotation "$ANNOTATION" \
|
|
220
|
-
${{ env.GHCR_ENDPOINT }}:latest-amd64 \
|
|
221
|
-
${{ env.GHCR_ENDPOINT }}:latest-arm64
|
|
222
|
-
|
|
223
|
-
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }} \
|
|
224
|
-
--annotation "$ANNOTATION" \
|
|
225
|
-
${{ env.GHCR_ENDPOINT }}:${TAG_AMD64} \
|
|
226
|
-
${{ env.GHCR_ENDPOINT }}:${TAG_ARM64}
|
|
220
|
+
docker buildx imagetools create -t ${{ env.ENDPOINT }}:latest ${{ env.ENDPOINT }}:latest-amd64 ${{ env.ENDPOINT }}:latest-arm64
|
|
221
|
+
docker buildx imagetools create -t ${{ env.ENDPOINT }}:${{ needs.version.outputs.version }} ${{ env.ENDPOINT }}:${TAG_AMD64} ${{ env.ENDPOINT }}:${TAG_ARM64}
|
|
222
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:latest --annotation "$ANNOTATION" ${{ env.GHCR_ENDPOINT }}:latest-amd64 ${{ env.GHCR_ENDPOINT }}:latest-arm64
|
|
223
|
+
docker buildx imagetools create -t ${{ env.GHCR_ENDPOINT }}:${{ needs.version.outputs.version }} --annotation "$ANNOTATION" ${{ env.GHCR_ENDPOINT }}:${TAG_AMD64} ${{ env.GHCR_ENDPOINT }}:${TAG_ARM64}
|
|
227
224
|
|
|
228
225
|
release:
|
|
229
226
|
name: Create Release
|
|
@@ -235,7 +232,6 @@ jobs:
|
|
|
235
232
|
- uses: actions/checkout@v6
|
|
236
233
|
with:
|
|
237
234
|
fetch-depth: 0
|
|
238
|
-
|
|
239
235
|
- uses: actions/download-artifact@v4
|
|
240
236
|
with:
|
|
241
237
|
name: wheel
|
|
@@ -244,16 +240,15 @@ jobs:
|
|
|
244
240
|
with:
|
|
245
241
|
name: exe-amd64
|
|
246
242
|
path: ./exe-amd64
|
|
247
|
-
|
|
248
243
|
- name: Install uv
|
|
249
244
|
uses: astral-sh/setup-uv@v5
|
|
250
245
|
with:
|
|
251
246
|
enable-cache: true
|
|
252
|
-
|
|
253
247
|
- name: Publish to PyPI
|
|
254
248
|
if: ${{ !inputs.skip_pypi }}
|
|
255
|
-
run:
|
|
256
|
-
|
|
249
|
+
run: |
|
|
250
|
+
echo "🚀 Publishing to PyPI..."
|
|
251
|
+
uv publish ./wheel/* --token ${{ secrets.PYPI_TOKEN }}
|
|
257
252
|
- name: Generate changelog
|
|
258
253
|
id: changelog
|
|
259
254
|
uses: metcalfc/changelog-generator@v4.6.2
|
|
@@ -264,25 +259,16 @@ jobs:
|
|
|
264
259
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
265
260
|
run: |
|
|
266
261
|
PR_BODY=$(gh pr list --search "${{ github.sha }}" --state merged --json body --jq '.[0].body // empty')
|
|
267
|
-
if [ -n "$PR_BODY" ]; then
|
|
268
|
-
echo -e "\n$PR_BODY" >> .github/Changelog.md
|
|
269
|
-
fi
|
|
262
|
+
if [ -n "$PR_BODY" ]; then echo -e "\n$PR_BODY" >> .github/Changelog.md; fi
|
|
270
263
|
- name: Create Release Body
|
|
271
264
|
run: |
|
|
272
265
|
echo "### Docker:" > release_body.md
|
|
273
|
-
echo "" >> release_body.md
|
|
274
266
|
echo "\`docker pull ${{ env.GHCR_ENDPOINT }}:latest\`" >> release_body.md
|
|
275
|
-
echo "" >> release_body.md
|
|
276
267
|
echo "### Python:" >> release_body.md
|
|
277
|
-
echo "" >> release_body.md
|
|
278
268
|
echo "\`uv tool upgrade quasarr\`" >> release_body.md
|
|
279
|
-
echo "" >> release_body.md
|
|
280
269
|
echo "### Changelog:" >> release_body.md
|
|
281
|
-
echo "" >> release_body.md
|
|
282
270
|
echo "${{ steps.changelog.outputs.changelog }}" >> release_body.md
|
|
283
|
-
echo "" >> release_body.md
|
|
284
271
|
echo "[Attestation](https://github.com/${{ github.repository }}/attestations/${{ needs.build-wheel.outputs.attestation-id }})" >> release_body.md
|
|
285
|
-
|
|
286
272
|
- name: Create Release
|
|
287
273
|
uses: ncipollo/release-action@v1
|
|
288
274
|
with:
|
|
@@ -298,7 +284,6 @@ jobs:
|
|
|
298
284
|
runs-on: ubuntu-latest
|
|
299
285
|
steps:
|
|
300
286
|
- uses: actions/checkout@v6
|
|
301
|
-
|
|
302
287
|
- name: Send Discord Webhook
|
|
303
288
|
env:
|
|
304
289
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -306,28 +291,31 @@ jobs:
|
|
|
306
291
|
VERSION: ${{ needs.version.outputs.version }}
|
|
307
292
|
REPO: ${{ github.repository }}
|
|
308
293
|
run: |
|
|
309
|
-
# Use the exact tag format defined in the release job (v.X.X.X)
|
|
310
294
|
TAG="v.$VERSION"
|
|
311
|
-
echo "Fetching release details for $TAG..."
|
|
312
|
-
|
|
313
|
-
# Fetch the body from the release we just created
|
|
314
295
|
RELEASE_BODY=$(gh release view "$TAG" --json body --jq .body)
|
|
315
|
-
|
|
316
296
|
if [ -n "$DISCORD_WEBHOOK" ]; then
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
# Construct JSON payload using jq
|
|
320
|
-
# Color 5763719 is 'Green'
|
|
321
|
-
jq -n \
|
|
322
|
-
--arg title "🚀 New Release: $TAG" \
|
|
323
|
-
--arg desc "$RELEASE_BODY" \
|
|
324
|
-
--arg url "https://github.com/$REPO/releases/tag/$TAG" \
|
|
325
|
-
'{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5763719}]}' \
|
|
326
|
-
> discord_payload.json
|
|
327
|
-
|
|
328
|
-
curl -H "Content-Type: application/json" \
|
|
329
|
-
-d @discord_payload.json \
|
|
330
|
-
"$DISCORD_WEBHOOK"
|
|
331
|
-
else
|
|
332
|
-
echo "::warning::Skipping Discord notification (DISCORD_WEBHOOK secret not set)"
|
|
297
|
+
jq -n --arg title "🚀 New Release: $TAG" --arg desc "$RELEASE_BODY" --arg url "https://github.com/$REPO/releases/tag/$TAG" '{content: null, embeds: [{title: $title, description: $desc, url: $url, color: 5763719}]}' > discord_payload.json
|
|
298
|
+
curl -H "Content-Type: application/json" -d @discord_payload.json "$DISCORD_WEBHOOK"
|
|
333
299
|
fi
|
|
300
|
+
|
|
301
|
+
job-summary:
|
|
302
|
+
name: 📈 Build Report
|
|
303
|
+
runs-on: ubuntu-latest
|
|
304
|
+
needs: [ version, build-wheel, build-exe, build-docker-amd64, build-docker-arm64, release ]
|
|
305
|
+
if: always()
|
|
306
|
+
steps:
|
|
307
|
+
- name: Generate Job Summary
|
|
308
|
+
run: |
|
|
309
|
+
echo "## 📊 Release Production Report" >> $GITHUB_STEP_SUMMARY
|
|
310
|
+
echo "| Artifact | Status |" >> $GITHUB_STEP_SUMMARY
|
|
311
|
+
echo "| --- | --- |" >> $GITHUB_STEP_SUMMARY
|
|
312
|
+
echo "| **Python Wheel** | ${{ needs.build-wheel.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
313
|
+
echo "| **Windows Standalone** | ${{ needs.build-exe.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
314
|
+
echo "| **Docker AMD64** | ${{ needs.build-docker-amd64.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
315
|
+
echo "| **Docker ARM64** | ${{ needs.build-docker-arm64.result == 'success' && '✅' || '❌' }} |" >> $GITHUB_STEP_SUMMARY
|
|
316
|
+
echo "| **GitHub Release** | ${{ needs.release.result == 'success' && '🚀 Published' || '⚠️ Failed' }} |" >> $GITHUB_STEP_SUMMARY
|
|
317
|
+
|
|
318
|
+
echo "### ⚡ Cache Performance" >> $GITHUB_STEP_SUMMARY
|
|
319
|
+
# This assumes you use the default GITHUB_TOKEN permissions to read cache API if you wanted complex stats,
|
|
320
|
+
# but for simplicity we report on the PyInstaller cache key match.
|
|
321
|
+
echo "* **PyInstaller Cache:** ${{ needs.build-exe.outputs.cache-hit == 'true' && 'Hit (Fast 🚀)' || 'Miss (Full Build 🐢)' }}" >> $GITHUB_STEP_SUMMARY
|
|
@@ -10,6 +10,12 @@ Ensure you have the development tools (like `ruff`) installed and your environme
|
|
|
10
10
|
uv sync --group dev
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
+
Install the pre-commit hook that ensures linting, formatting and version upgrades through pre-commit.py
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv run pre-commit install
|
|
17
|
+
```
|
|
18
|
+
|
|
13
19
|
**2. Run Quasarr with the `--internal_address` parameter**
|
|
14
20
|
|
|
15
21
|
```bash
|
|
@@ -32,24 +38,11 @@ The `CONFIG_VOLUMES` environment variable is **mandatory**.
|
|
|
32
38
|
|
|
33
39
|
### Code Quality & Maintenance
|
|
34
40
|
|
|
35
|
-
The CI pipeline enforces strict code styling and import optimization. Please run
|
|
36
|
-
changes
|
|
41
|
+
The CI pipeline enforces strict code styling and import optimization. Please run this commands before pushing your
|
|
42
|
+
changes. Alternatively, you should just set up the pre-commit hook as described above.
|
|
37
43
|
|
|
38
|
-
**
|
|
44
|
+
**Format code AND upgrade dependencie manually:**
|
|
39
45
|
|
|
40
46
|
```bash
|
|
41
|
-
uv run
|
|
47
|
+
uv run pre-commit.py --upgrade
|
|
42
48
|
```
|
|
43
|
-
|
|
44
|
-
**Format Code Layout:**
|
|
45
|
-
|
|
46
|
-
```bash
|
|
47
|
-
uv run ruff format .
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
**Update Dependencies:**
|
|
51
|
-
To update the project lockfile to the latest versions of all packages without manually editing `pyproject.toml`:
|
|
52
|
-
|
|
53
|
-
```bash
|
|
54
|
-
uv lock --upgrade
|
|
55
|
-
```
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quasarr
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.11
|
|
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
|
|
@@ -243,11 +243,12 @@ Most feature requests can be satisfied by:
|
|
|
243
243
|
[here](https://github.com/rix1337/Quasarr/pulls).
|
|
244
244
|
- **Pull requests are welcome!** Especially for popular hostnames.
|
|
245
245
|
- A short guide to set up required dev services is found
|
|
246
|
-
|
|
246
|
+
[here](https://github.com/rix1337/Quasarr/blob/main/CONTRIBUTING.md).
|
|
247
247
|
- Always reach out on Discord before starting work on a new feature to prevent waste of time.
|
|
248
248
|
- Please follow the existing code style and project structure.
|
|
249
249
|
- Anti-bot measures must be circumvented fully by Quasarr. Thus, you will need to provide a working solution for new
|
|
250
250
|
CAPTCHA types by integrating it in the Quasarr Web UI.
|
|
251
|
+
The simplest CAPTCHA bypass involves creating a Tampermonkey user script.
|
|
251
252
|
- Please provide proof of functionality (screenshots/examples) when submitting your pull request.
|
|
252
253
|
|
|
253
254
|
# SponsorsHelper
|
|
@@ -225,11 +225,12 @@ Most feature requests can be satisfied by:
|
|
|
225
225
|
[here](https://github.com/rix1337/Quasarr/pulls).
|
|
226
226
|
- **Pull requests are welcome!** Especially for popular hostnames.
|
|
227
227
|
- A short guide to set up required dev services is found
|
|
228
|
-
|
|
228
|
+
[here](https://github.com/rix1337/Quasarr/blob/main/CONTRIBUTING.md).
|
|
229
229
|
- Always reach out on Discord before starting work on a new feature to prevent waste of time.
|
|
230
230
|
- Please follow the existing code style and project structure.
|
|
231
231
|
- Anti-bot measures must be circumvented fully by Quasarr. Thus, you will need to provide a working solution for new
|
|
232
232
|
CAPTCHA types by integrating it in the Quasarr Web UI.
|
|
233
|
+
The simplest CAPTCHA bypass involves creating a Tampermonkey user script.
|
|
233
234
|
- Please provide proof of functionality (screenshots/examples) when submitting your pull request.
|
|
234
235
|
|
|
235
236
|
# SponsorsHelper
|