quasarr 1.24.1__tar.gz → 1.26.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-1.24.1 → quasarr-1.26.0}/PKG-INFO +3 -3
- {quasarr-1.24.1 → quasarr-1.26.0}/README.md +2 -2
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/captcha/__init__.py +181 -63
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/__init__.py +2 -1
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/linkcrypters/hide.py +22 -8
- quasarr-1.26.0/quasarr/providers/html_images.py +22 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/html_templates.py +48 -1
- quasarr-1.26.0/quasarr/providers/obfuscated.py +104 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/version.py +1 -1
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/web_server.py +8 -1
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/PKG-INFO +3 -3
- quasarr-1.24.1/quasarr/providers/html_images.py +0 -22
- quasarr-1.24.1/quasarr/providers/obfuscated.py +0 -86
- {quasarr-1.24.1 → quasarr-1.26.0}/LICENSE +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/arr/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/config/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/sponsors_helper/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/api/statistics/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/linkcrypters/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/linkcrypters/al.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/linkcrypters/filecrypt.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/packages/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/al.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/by.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/dd.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/dj.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/dl.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/dt.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/dw.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/he.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/mb.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/nk.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/nx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/sf.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/sj.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/sl.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/wd.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/downloads/sources/wx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/cloudflare.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/imdb_metadata.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/log.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/myjd_api.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/notifications.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/sessions/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/sessions/al.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/sessions/dd.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/sessions/dl.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/sessions/nx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/shared_state.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/providers/statistics.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/al.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/by.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/dd.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/dj.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/dl.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/dt.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/dw.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/fx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/he.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/mb.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/nk.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/nx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/sf.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/sj.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/sl.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/wd.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/search/sources/wx.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/storage/__init__.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/storage/config.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/storage/setup.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr/storage/sqlite_database.py +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/SOURCES.txt +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/dependency_links.txt +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/entry_points.txt +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/not-zip-safe +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/requires.txt +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/quasarr.egg-info/top_level.txt +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/setup.cfg +0 -0
- {quasarr-1.24.1 → quasarr-1.26.0}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: quasarr
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.26.0
|
|
4
4
|
Summary: Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decrypts links protected by CAPTCHAs.
|
|
5
5
|
Home-page: https://github.com/rix1337/Quasarr
|
|
6
6
|
Author: rix1337
|
|
@@ -36,12 +36,12 @@ Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decr
|
|
|
36
36
|
[](https://github.com/users/rix1337/sponsorship)
|
|
37
37
|
|
|
38
38
|
Quasarr pretends to be both `Newznab Indexer` and `SABnzbd client`. Therefore, do not try to use it with real usenet
|
|
39
|
-
indexers
|
|
39
|
+
indexers. It simply does not know what NZB files are.
|
|
40
40
|
|
|
41
41
|
Quasarr includes a solution to quickly and easily decrypt protected links.
|
|
42
42
|
[Active monthly Sponsors get access to SponsorsHelper to do so automatically.](https://github.com/rix1337/Quasarr?tab=readme-ov-file#sponsorshelper)
|
|
43
43
|
Alternatively, follow the link from the console output (or discord notification) to solve CAPTCHAs manually.
|
|
44
|
-
Quasarr will confidently handle the rest.
|
|
44
|
+
Quasarr will confidently handle the rest. Some CAPTCHA types require [Tampermonkey](https://www.tampermonkey.net/) to be installed in your browser.
|
|
45
45
|
|
|
46
46
|
# Instructions
|
|
47
47
|
1. Set up and run [FlareSolverr 3](https://github.com/FlareSolverr/FlareSolverr).
|
|
@@ -9,12 +9,12 @@ Quasarr connects JDownloader with Radarr, Sonarr and LazyLibrarian. It also decr
|
|
|
9
9
|
[](https://github.com/users/rix1337/sponsorship)
|
|
10
10
|
|
|
11
11
|
Quasarr pretends to be both `Newznab Indexer` and `SABnzbd client`. Therefore, do not try to use it with real usenet
|
|
12
|
-
indexers
|
|
12
|
+
indexers. It simply does not know what NZB files are.
|
|
13
13
|
|
|
14
14
|
Quasarr includes a solution to quickly and easily decrypt protected links.
|
|
15
15
|
[Active monthly Sponsors get access to SponsorsHelper to do so automatically.](https://github.com/rix1337/Quasarr?tab=readme-ov-file#sponsorshelper)
|
|
16
16
|
Alternatively, follow the link from the console output (or discord notification) to solve CAPTCHAs manually.
|
|
17
|
-
Quasarr will confidently handle the rest.
|
|
17
|
+
Quasarr will confidently handle the rest. Some CAPTCHA types require [Tampermonkey](https://www.tampermonkey.net/) to be installed in your browser.
|
|
18
18
|
|
|
19
19
|
# Instructions
|
|
20
20
|
1. Set up and run [FlareSolverr 3](https://github.com/FlareSolverr/FlareSolverr).
|
|
@@ -108,6 +108,12 @@ def setup_captcha_routes(app):
|
|
|
108
108
|
|
|
109
109
|
has_junkies_links = any(is_junkies_link(link) for link in prioritized_links)
|
|
110
110
|
|
|
111
|
+
# Hide uses nested arrays like FileCrypt: [["url", "mirror"]]
|
|
112
|
+
has_hide_links = any(
|
|
113
|
+
("hide." in link[0] if isinstance(link, (list, tuple)) else "hide." in link)
|
|
114
|
+
for link in prioritized_links
|
|
115
|
+
)
|
|
116
|
+
|
|
111
117
|
# KeepLinks uses nested arrays like FileCrypt: [["url", "mirror"]]
|
|
112
118
|
has_keeplinks_links = any(
|
|
113
119
|
("keeplinks." in link[0] if isinstance(link, (list, tuple)) else "keeplinks." in link)
|
|
@@ -120,7 +126,10 @@ def setup_captcha_routes(app):
|
|
|
120
126
|
for link in prioritized_links
|
|
121
127
|
)
|
|
122
128
|
|
|
123
|
-
if
|
|
129
|
+
if has_hide_links:
|
|
130
|
+
debug("Redirecting to Hide page")
|
|
131
|
+
redirect(f"/captcha/hide?data={quote(encoded_payload)}")
|
|
132
|
+
elif has_junkies_links:
|
|
124
133
|
debug("Redirecting to Junkies CAPTCHA")
|
|
125
134
|
redirect(f"/captcha/junkies?data={quote(encoded_payload)}")
|
|
126
135
|
elif has_keeplinks_links:
|
|
@@ -151,7 +160,7 @@ def setup_captcha_routes(app):
|
|
|
151
160
|
return {"error": f"Failed to decode payload: {str(e)}"}
|
|
152
161
|
|
|
153
162
|
def render_userscript_section(url, package_id, title, password, provider_type="junkies"):
|
|
154
|
-
"""Render the userscript UI section for Junkies, KeepLinks, or
|
|
163
|
+
"""Render the userscript UI section for Junkies, KeepLinks, ToLink, or Hide pages
|
|
155
164
|
|
|
156
165
|
This is the MAIN solution for these providers (not a bypass/fallback).
|
|
157
166
|
|
|
@@ -160,10 +169,10 @@ def setup_captcha_routes(app):
|
|
|
160
169
|
package_id: Package identifier
|
|
161
170
|
title: Package title
|
|
162
171
|
password: Package password
|
|
163
|
-
provider_type: Either "junkies", "keeplinks", or "tolink"
|
|
172
|
+
provider_type: Either "hide", "junkies", "keeplinks", or "tolink"
|
|
164
173
|
"""
|
|
165
174
|
|
|
166
|
-
provider_names = {"junkies": "Junkies", "keeplinks": "KeepLinks", "tolink": "ToLink"}
|
|
175
|
+
provider_names = {"hide": "Hide", "junkies": "Junkies", "keeplinks": "KeepLinks", "tolink": "ToLink"}
|
|
167
176
|
provider_name = provider_names.get(provider_type, "Provider")
|
|
168
177
|
userscript_url = f"/captcha/{provider_type}.user.js"
|
|
169
178
|
storage_key = f"hide{provider_name}SetupInstructions"
|
|
@@ -182,45 +191,89 @@ def setup_captcha_routes(app):
|
|
|
182
191
|
|
|
183
192
|
return f'''
|
|
184
193
|
<div>
|
|
194
|
+
<!-- Info section explaining the process -->
|
|
195
|
+
<div class="info-box">
|
|
196
|
+
<h3>ℹ️ How This Works:</h3>
|
|
197
|
+
<p style="margin-bottom: 8px;">
|
|
198
|
+
1. Click the link below to open {provider_name}
|
|
199
|
+
</p>
|
|
200
|
+
<p style="margin-top: 0; margin-bottom: 8px;">
|
|
201
|
+
2. Solve any CAPTCHAs on their site to reveal the download links
|
|
202
|
+
</p>
|
|
203
|
+
<p style="margin-top: 0; margin-bottom: 0;">
|
|
204
|
+
3. <b>With the userscript installed</b>, links are automatically sent back to Quasarr!
|
|
205
|
+
</p>
|
|
206
|
+
</div>
|
|
207
|
+
|
|
185
208
|
<!-- One-time setup section - visually separated -->
|
|
186
|
-
<div id="setup-instructions"
|
|
187
|
-
<h3
|
|
209
|
+
<div id="setup-instructions" class="setup-box">
|
|
210
|
+
<h3>📦 First Time Setup:</h3>
|
|
188
211
|
<p style="margin-bottom: 8px;">
|
|
189
212
|
<a href="https://www.tampermonkey.net/" target="_blank" rel="noopener noreferrer">1. Install Tampermonkey</a>
|
|
190
213
|
</p>
|
|
191
214
|
<p style="margin-top: 0; margin-bottom: 12px;">
|
|
192
|
-
<a href="{userscript_url}" target="_blank">2. Install
|
|
215
|
+
<a href="{userscript_url}" target="_blank">2. Install the {provider_name} userscript</a>
|
|
193
216
|
</p>
|
|
194
217
|
<p style="margin-top: 0;">
|
|
195
|
-
<button id="hide-setup-btn" type="button"
|
|
218
|
+
<button id="hide-setup-btn" type="button" class="btn-subtle">
|
|
196
219
|
✅ Don't show this again
|
|
197
220
|
</button>
|
|
198
221
|
</p>
|
|
199
222
|
</div>
|
|
200
223
|
|
|
201
|
-
<!-- Hidden "show instructions"
|
|
224
|
+
<!-- Hidden "show instructions" button -->
|
|
202
225
|
<div id="show-instructions-link" style="display: none; margin-bottom: 16px;">
|
|
203
|
-
<
|
|
226
|
+
<button id="show-setup-btn" type="button" class="btn-subtle">
|
|
227
|
+
ℹ️ Show setup instructions
|
|
228
|
+
</button>
|
|
204
229
|
</div>
|
|
205
230
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
<input type="hidden" name="title" value="{title}" />
|
|
211
|
-
<input type="hidden" name="password" value="{password}" />
|
|
212
|
-
|
|
213
|
-
<div>
|
|
214
|
-
<strong>Paste the download links (one per line):</strong>
|
|
215
|
-
<textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
|
|
216
|
-
</div>
|
|
231
|
+
<!-- Primary action - the quick transfer link -->
|
|
232
|
+
<p>
|
|
233
|
+
{render_button(f"Open {provider_name} & Get Download Links", "primary", {"onclick": f"location.href='{url_with_quick_transfer_params}'"})}
|
|
234
|
+
</p>
|
|
217
235
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
236
|
+
<!-- Manual submission - collapsible -->
|
|
237
|
+
<div class="section-divider">
|
|
238
|
+
<details id="manualSubmitDetails">
|
|
239
|
+
<summary id="manualSubmitSummary" style="cursor: pointer;">Show Manual Submission</summary>
|
|
240
|
+
<div style="margin-top: 16px;">
|
|
241
|
+
<p style="font-size: 0.9em;">
|
|
242
|
+
If the userscript doesn't work, you can manually paste the links below:
|
|
243
|
+
</p>
|
|
244
|
+
<form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
|
|
245
|
+
<input type="hidden" name="package_id" value="{package_id}" />
|
|
246
|
+
<input type="hidden" name="title" value="{title}" />
|
|
247
|
+
<input type="hidden" name="password" value="{password}" />
|
|
248
|
+
|
|
249
|
+
<div>
|
|
250
|
+
<strong>Paste the download links (one per line):</strong>
|
|
251
|
+
<textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
|
|
252
|
+
</div>
|
|
253
|
+
|
|
254
|
+
<div>
|
|
255
|
+
{render_button("Submit", "primary", {"type": "submit"})}
|
|
256
|
+
</div>
|
|
257
|
+
</form>
|
|
258
|
+
</div>
|
|
259
|
+
</details>
|
|
260
|
+
</div>
|
|
222
261
|
</div>
|
|
223
262
|
<script>
|
|
263
|
+
// Handle manual submission toggle text
|
|
264
|
+
const manualDetails = document.getElementById('manualSubmitDetails');
|
|
265
|
+
const manualSummary = document.getElementById('manualSubmitSummary');
|
|
266
|
+
|
|
267
|
+
if (manualDetails && manualSummary) {{
|
|
268
|
+
manualDetails.addEventListener('toggle', () => {{
|
|
269
|
+
if (manualDetails.open) {{
|
|
270
|
+
manualSummary.textContent = 'Hide Manual Submission';
|
|
271
|
+
}} else {{
|
|
272
|
+
manualSummary.textContent = 'Show Manual Submission';
|
|
273
|
+
}}
|
|
274
|
+
}});
|
|
275
|
+
}}
|
|
276
|
+
|
|
224
277
|
// Handle setup instructions hide/show
|
|
225
278
|
const hideSetup = localStorage.getItem('{storage_key}');
|
|
226
279
|
const setupBox = document.getElementById('setup-instructions');
|
|
@@ -239,8 +292,7 @@ def setup_captcha_routes(app):
|
|
|
239
292
|
}});
|
|
240
293
|
|
|
241
294
|
// Show setup instructions again
|
|
242
|
-
document.getElementById('show-setup-btn').addEventListener('click', function(
|
|
243
|
-
e.preventDefault();
|
|
295
|
+
document.getElementById('show-setup-btn').addEventListener('click', function() {{
|
|
244
296
|
localStorage.setItem('{storage_key}', 'false');
|
|
245
297
|
setupBox.style.display = 'block';
|
|
246
298
|
showLink.style.display = 'none';
|
|
@@ -248,6 +300,42 @@ def setup_captcha_routes(app):
|
|
|
248
300
|
</script>
|
|
249
301
|
'''
|
|
250
302
|
|
|
303
|
+
@app.get("/captcha/hide")
|
|
304
|
+
def serve_hide_captcha():
|
|
305
|
+
payload = decode_payload()
|
|
306
|
+
|
|
307
|
+
if "error" in payload:
|
|
308
|
+
return render_centered_html(f'''<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
309
|
+
<p>{payload["error"]}</p>
|
|
310
|
+
<p>
|
|
311
|
+
{render_button("Back", "secondary", {"onclick": "location.href='/'"})}
|
|
312
|
+
</p>''')
|
|
313
|
+
|
|
314
|
+
package_id = payload.get("package_id")
|
|
315
|
+
title = payload.get("title")
|
|
316
|
+
password = payload.get("password")
|
|
317
|
+
urls = payload.get("links")
|
|
318
|
+
url = urls[0][0] if isinstance(urls[0], (list, tuple)) else urls[0]
|
|
319
|
+
|
|
320
|
+
check_package_exists(package_id)
|
|
321
|
+
|
|
322
|
+
return render_centered_html(f"""
|
|
323
|
+
<!DOCTYPE html>
|
|
324
|
+
<html>
|
|
325
|
+
<body>
|
|
326
|
+
<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
327
|
+
<p><b>Package:</b> {title}</p>
|
|
328
|
+
{render_userscript_section(url, package_id, title, password, "hide")}
|
|
329
|
+
<p>
|
|
330
|
+
{render_button("Delete Package", "secondary", {"onclick": f"location.href='/captcha/delete/{package_id}'"})}
|
|
331
|
+
</p>
|
|
332
|
+
<p>
|
|
333
|
+
{render_button("Back", "secondary", {"onclick": "location.href='/'"})}
|
|
334
|
+
</p>
|
|
335
|
+
|
|
336
|
+
</body>
|
|
337
|
+
</html>""")
|
|
338
|
+
|
|
251
339
|
@app.get("/captcha/junkies")
|
|
252
340
|
def serve_junkies_captcha():
|
|
253
341
|
payload = decode_payload()
|
|
@@ -358,6 +446,18 @@ def setup_captcha_routes(app):
|
|
|
358
446
|
</body>
|
|
359
447
|
</html>""")
|
|
360
448
|
|
|
449
|
+
@app.get('/captcha/filecrypt.user.js')
|
|
450
|
+
def serve_filecrypt_user_js():
|
|
451
|
+
content = obfuscated.filecrypt_user_js()
|
|
452
|
+
response.content_type = 'application/javascript'
|
|
453
|
+
return content
|
|
454
|
+
|
|
455
|
+
@app.get('/captcha/hide.user.js')
|
|
456
|
+
def serve_hide_user_js():
|
|
457
|
+
content = obfuscated.hide_user_js()
|
|
458
|
+
response.content_type = 'application/javascript'
|
|
459
|
+
return content
|
|
460
|
+
|
|
361
461
|
@app.get('/captcha/junkies.user.js')
|
|
362
462
|
def serve_junkies_user_js():
|
|
363
463
|
sj = shared_state.values["config"]("Hostnames").get("sj")
|
|
@@ -379,12 +479,6 @@ def setup_captcha_routes(app):
|
|
|
379
479
|
response.content_type = 'application/javascript'
|
|
380
480
|
return content
|
|
381
481
|
|
|
382
|
-
@app.get('/captcha/filecrypt.user.js')
|
|
383
|
-
def serve_filecrypt_user_js():
|
|
384
|
-
content = obfuscated.filecrypt_user_js()
|
|
385
|
-
response.content_type = 'application/javascript'
|
|
386
|
-
return content
|
|
387
|
-
|
|
388
482
|
def render_filecrypt_bypass_section(url, package_id, title, password):
|
|
389
483
|
"""Render the bypass UI section for both cutcaptcha and circle captcha pages"""
|
|
390
484
|
|
|
@@ -402,52 +496,77 @@ def setup_captcha_routes(app):
|
|
|
402
496
|
)
|
|
403
497
|
|
|
404
498
|
return f'''
|
|
405
|
-
<div style="
|
|
499
|
+
<div class="section-divider" style="max-width: 370px; margin-left: auto; margin-right: auto;">
|
|
406
500
|
<details id="bypassDetails">
|
|
407
501
|
<summary id="bypassSummary">Show CAPTCHA Bypass</summary><br>
|
|
408
502
|
|
|
503
|
+
<!-- Info section explaining the process -->
|
|
504
|
+
<div class="info-box">
|
|
505
|
+
<h3>ℹ️ How This Works:</h3>
|
|
506
|
+
<p style="margin-bottom: 8px;">
|
|
507
|
+
1. Click the button below to open FileCrypt directly
|
|
508
|
+
</p>
|
|
509
|
+
<p style="margin-top: 0; margin-bottom: 8px;">
|
|
510
|
+
2. Solve any CAPTCHAs on their site to reveal the download links
|
|
511
|
+
</p>
|
|
512
|
+
<p style="margin-top: 0; margin-bottom: 0;">
|
|
513
|
+
3. <b>With the userscript installed</b>, links are automatically sent back to Quasarr!
|
|
514
|
+
</p>
|
|
515
|
+
</div>
|
|
516
|
+
|
|
409
517
|
<!-- One-time setup section - visually separated -->
|
|
410
|
-
<div id="setup-instructions"
|
|
411
|
-
<h3
|
|
518
|
+
<div id="setup-instructions" class="setup-box">
|
|
519
|
+
<h3>📦 First Time Setup:</h3>
|
|
412
520
|
<p style="margin-bottom: 8px;">
|
|
413
521
|
<a href="https://www.tampermonkey.net/" target="_blank" rel="noopener noreferrer">1. Install Tampermonkey</a>
|
|
414
522
|
</p>
|
|
415
523
|
<p style="margin-top: 0; margin-bottom: 12px;">
|
|
416
|
-
<a href="/captcha/filecrypt.user.js" target="_blank">2. Install
|
|
524
|
+
<a href="/captcha/filecrypt.user.js" target="_blank">2. Install the FileCrypt userscript</a>
|
|
417
525
|
</p>
|
|
418
526
|
<p style="margin-top: 0;">
|
|
419
|
-
<button id="hide-setup-btn" type="button"
|
|
527
|
+
<button id="hide-setup-btn" type="button" class="btn-subtle">
|
|
420
528
|
✅ Don't show this again
|
|
421
529
|
</button>
|
|
422
530
|
</p>
|
|
423
531
|
</div>
|
|
424
532
|
|
|
425
|
-
<!-- Hidden "show instructions"
|
|
533
|
+
<!-- Hidden "show instructions" button -->
|
|
426
534
|
<div id="show-instructions-link" style="display: none; margin-bottom: 16px;">
|
|
427
|
-
<
|
|
535
|
+
<button id="show-setup-btn" type="button" class="btn-subtle">
|
|
536
|
+
ℹ️ Show setup instructions
|
|
537
|
+
</button>
|
|
428
538
|
</div>
|
|
429
539
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
<input type="hidden" name="title" value="{title}" />
|
|
435
|
-
<input type="hidden" name="password" value="{password}" />
|
|
436
|
-
|
|
437
|
-
<div>
|
|
438
|
-
<strong>Paste the download links (one per line):</strong>
|
|
439
|
-
<textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
|
|
440
|
-
</div>
|
|
441
|
-
|
|
442
|
-
<div>
|
|
443
|
-
<strong>Or upload DLC file:</strong><br>
|
|
444
|
-
<input type="file" id="dlc-file" name="dlc_file" accept=".dlc" />
|
|
445
|
-
</div>
|
|
540
|
+
<!-- Primary action button -->
|
|
541
|
+
<p>
|
|
542
|
+
{render_button("Open FileCrypt & Get Download Links", "primary", {"onclick": f"location.href='{url_with_quick_transfer_params}'"})}
|
|
543
|
+
</p>
|
|
446
544
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
545
|
+
<!-- Manual submission section -->
|
|
546
|
+
<div class="section-divider">
|
|
547
|
+
<p style="font-size: 0.9em; margin-bottom: 16px;">
|
|
548
|
+
If the userscript doesn't work, you can manually paste the links or upload a DLC file:
|
|
549
|
+
</p>
|
|
550
|
+
<form id="bypass-form" action="/captcha/bypass-submit" method="post" enctype="multipart/form-data">
|
|
551
|
+
<input type="hidden" name="package_id" value="{package_id}" />
|
|
552
|
+
<input type="hidden" name="title" value="{title}" />
|
|
553
|
+
<input type="hidden" name="password" value="{password}" />
|
|
554
|
+
|
|
555
|
+
<div>
|
|
556
|
+
<strong>Paste the download links (one per line):</strong>
|
|
557
|
+
<textarea id="links-input" name="links" rows="5" style="width: 100%; padding: 8px; font-family: monospace; resize: vertical;"></textarea>
|
|
558
|
+
</div>
|
|
559
|
+
|
|
560
|
+
<div>
|
|
561
|
+
<strong>Or upload DLC file:</strong><br>
|
|
562
|
+
<input type="file" id="dlc-file" name="dlc_file" accept=".dlc" />
|
|
563
|
+
</div>
|
|
564
|
+
|
|
565
|
+
<div>
|
|
566
|
+
{render_button("Submit", "primary", {"type": "submit"})}
|
|
567
|
+
</div>
|
|
568
|
+
</form>
|
|
569
|
+
</div>
|
|
451
570
|
</details>
|
|
452
571
|
</div>
|
|
453
572
|
<script>
|
|
@@ -483,8 +602,7 @@ def setup_captcha_routes(app):
|
|
|
483
602
|
}});
|
|
484
603
|
|
|
485
604
|
// Show setup instructions again
|
|
486
|
-
document.getElementById('show-setup-btn').addEventListener('click', function(
|
|
487
|
-
e.preventDefault();
|
|
605
|
+
document.getElementById('show-setup-btn').addEventListener('click', function() {{
|
|
488
606
|
localStorage.setItem('hideFileCryptSetupInstructions', 'false');
|
|
489
607
|
setupBox.style.display = 'block';
|
|
490
608
|
showLink.style.display = 'none';
|
|
@@ -764,7 +882,7 @@ def setup_captcha_routes(app):
|
|
|
764
882
|
reloadSection.style.display = "block";
|
|
765
883
|
});
|
|
766
884
|
}
|
|
767
|
-
''' + obfuscated.
|
|
885
|
+
''' + obfuscated.cutcaptcha_custom_js() + f'''</script>
|
|
768
886
|
<div>
|
|
769
887
|
<h1><img src="{images.logo}" type="image/png" alt="Quasarr logo" class="logo"/>Quasarr</h1>
|
|
770
888
|
<p id="package-title" style="max-width: 370px; word-wrap: break-word; overflow-wrap: break-word;"><b>Package:</b> {title}</p>
|
|
@@ -202,7 +202,8 @@ def process_links(shared_state, source_result, title, password, package_id, imdb
|
|
|
202
202
|
if result["success"]:
|
|
203
203
|
send_discord_message(shared_state, title=title, case="unprotected", imdb_id=imdb_id, source=source_url)
|
|
204
204
|
return {"success": True, "title": title}
|
|
205
|
-
info(f"Auto-decrypt failed for {title},
|
|
205
|
+
info(f"Auto-decrypt failed for {title}, falling back to manual CAPTCHA...")
|
|
206
|
+
classified['protected'].extend(classified['auto'])
|
|
206
207
|
|
|
207
208
|
# PRIORITY 3: Protected (filecrypt, tolink, keeplinks, junkies)
|
|
208
209
|
if classified['protected']:
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
# Project by https://github.com/rix1337
|
|
4
4
|
|
|
5
5
|
import re
|
|
6
|
+
from concurrent.futures import ThreadPoolExecutor, as_completed
|
|
6
7
|
from typing import List, Dict, Any
|
|
7
8
|
|
|
8
9
|
import requests
|
|
@@ -29,18 +30,31 @@ def unhide_links(shared_state, url):
|
|
|
29
30
|
response = requests.get(container_url, headers=headers)
|
|
30
31
|
data = response.json()
|
|
31
32
|
|
|
32
|
-
for link in data.get("links", [])
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
link_ids = [link.get("id") for link in data.get("links", []) if link.get("id")]
|
|
34
|
+
|
|
35
|
+
if not link_ids:
|
|
36
|
+
debug(f"No link IDs found in container {container_id}")
|
|
37
|
+
return []
|
|
36
38
|
|
|
39
|
+
def fetch_link(link_id):
|
|
37
40
|
debug(f"Fetching hide.cx link with ID: {link_id}")
|
|
38
41
|
link_url = f"https://api.hide.cx/containers/{container_id}/links/{link_id}"
|
|
39
42
|
link_data = requests.get(link_url, headers=headers).json()
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
43
|
+
return link_data.get("url")
|
|
44
|
+
|
|
45
|
+
# Process links in batches of 10
|
|
46
|
+
batch_size = 10
|
|
47
|
+
for i in range(0, len(link_ids), batch_size):
|
|
48
|
+
batch = link_ids[i:i + batch_size]
|
|
49
|
+
with ThreadPoolExecutor(max_workers=batch_size) as executor:
|
|
50
|
+
futures = [executor.submit(fetch_link, link_id) for link_id in batch]
|
|
51
|
+
for future in as_completed(futures):
|
|
52
|
+
try:
|
|
53
|
+
final_url = future.result()
|
|
54
|
+
if final_url and final_url not in links:
|
|
55
|
+
links.append(final_url)
|
|
56
|
+
except Exception as e:
|
|
57
|
+
info(f"Error fetching link: {e}")
|
|
44
58
|
|
|
45
59
|
success = bool(links)
|
|
46
60
|
if success:
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Quasarr
|
|
3
|
+
# Project by https://github.com/rix1337
|
|
4
|
+
|
|
5
|
+
logo = 'data:image/webp;base64,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'
|
|
6
|
+
al = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA9UlEQVR4nBXBv0rDQADA4d8ld8EQ2yJiGxAchOqgQSFEEEGfQV18DgcHwYcQ36GDg07+wUlwcBApCnUrbYcKIrRIa0qTy534fSI+vbMCi7GSUe7zr6QmOEJjEUhhDcZReHLEQXiLNoKn4S66CHBMjjTKJ0+nHPZPOJrtEPguc+17GuE5fjCD9H57rHYuCT/H3HxUmaYp5aDPRnZBd2kfp9d6I15fYe/qmdryJiVvge3GI1tRnW7rHbF2fG0rXy9E5QFJnoFSNF1Jc1jhp5YgkrMHm2kYtF9R+TdYS6aqzNdjPBek0RolYDHaoSgsWHClQE/GGA1/SzpdtJMWu3cAAAAASUVORK5CYII='
|
|
7
|
+
by = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAATlBMVEX///8crf/29fQDo//J7f/u7u7w+v/2/P/8/PyytLWenp6IhoWTwNfPz8+mpaVYxP94eHhryf+75fyB0f+oxNPl5eW4yNGrr68xsfmUlJQWKuGqAAAAQklEQVQI1yWLSRKAIBADMzOAsgiC+/8/aiwvSR+6AUB15mJyZ42ev8ldclI4MWvXuvwQCaGblPxQCmNP9fgyqGf+AkFFAeZ3L10cAAAAAElFTkSuQmCC'
|
|
8
|
+
dd = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABCElEQVR4nAXBP0sCYRzA8e89d6eQ4SRkdNKQOEVSvQQbegdB4dAgLY1tLS1NvYFoDIIIGtqKXPq3JJGWEQkaDQliGJnaPXf6e/p8rGrt4/CxUl777fZQylYGg4iReHyMxez8kXN1c5c/Pj1D7AhKQqKujQgqCDSrK35evTca/InD+sYmyXSWdqeLFvCHhka9bpyvdgsdCpl0msRkin1/xMLcLKXbIs3mp6UG/R5vL2VKzzV29g4oFAokkh7XxQuGgcbxtTYy6Fr97xaZ6QmeHu55rVYIf9poHeAMR8ZCNLvbW8TGY5x0OrgK7KhLEIY4U6nUeS63tBwGWowR5dgziME4bsTyPO/yH3LufRKlNxKMAAAAAElFTkSuQmCC'
|
|
9
|
+
dj = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAC9UExURY2NjYWGhoeIiYiIiIiIiYWFhoODg4mKillZWYSEhFBMS3x7e0xIR3Bsa0E+PldWVi4wMT4/Px0eHiQkJA8PDwoMDAsMDAsMDAsLCw0NDWxqaHZtZnBrZ2dnZ25qZ21oZJ94XtWNWr6DXG9mYpp2X6p5V6JwVNJ9TsN4UXBgWZhtVaxuTZBbR6xiRMpoQKlgQ6JfRZ5cQHFGN6dOMqFOM5lMM6tPMmZBNCYlJS8mIywlJCglJC8mJCMhIf////64+awAAAAadFJOU1SosLCwokSyl7ugup+6n7ugr5RLlJmYmZA8Hg7dEgAAAAFiS0dEPklkAOMAAAAHdElNRQfpDBESHCL8f1a2AAAAUElEQVQI12NgYGRiYmZhZWNgl5KWkZWT52DgVFBUUlZR5WLgVlPX0NTS5mHg1dHV0zcw5GPgNzI2MTUzF2AQtLC0sraxFWIQFhEVExOXkAQA4WIHfGNBCckAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjUtMTItMTdUMTg6Mjg6MjgrMDA6MDDR5B2HAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDI1LTEyLTE3VDE4OjI4OjI4KzAwOjAwoLmlOwAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyNS0xMi0xN1QxODoyODozNCswMDowMPym7g4AAAAASUVORK5CYII='
|
|
10
|
+
dl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAACKADAAQAAAABAAAACAAAAACVhHtSAAAAw0lEQVQYGV2PMQrCQBBF/+6OSUy1aYQgSI7gCSR4Bhs78RKCtQfxAnqGVLYewE6ENELSqHFJdt0hCOIvhtl9zPw/Al55voqCNikFoPntgNpQlRbFvhEMwzZ5MfjXm6oh8aQigdZZ+A2QfpxlJcCMiISeqgwRxYgfGuflHLjfMLuMcbzuND3JYGPXiE2IMjAYHU6YIIMNFKzoQEEzqBdqqzu/21nX20hvZgRkp2ritBxSdr33b/UhU8mncFo+7Qu55z9mH8f7S3Ax+Zg1AAAAAElFTkSuQmCC'
|
|
11
|
+
dt = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA4ElEQVR4nD2PsWrCUBSGv3ubBoq+QevQUhAXV6dMRcyTZBV8CCfxCTq4ZOmSJwg+giB4t16p1NCpSFECyY2n5EL7LeeD8/PDr5qmEa01+XrNz35PaAxFUXCrNQ/DIVophbWW19WKt+WSp16PYLvlvtNBHY8ESZLg6ppPaxmMRgymUz4WC577fR5nM3SapryMx0RRxPf5jDjHXRi21bQEWZZhjCGeTIiDgOvpxM3hQLXb+QAiImVZSlVV0tS1XEXkPY7laz5vX0K74h/n/KnyXNxm41351B+tKoVcLt5Vt8svgsSBPKnRQSAAAAAASUVORK5CYII='
|
|
12
|
+
dw = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA70lEQVR4nAXBTUrDQBiA4febmfjbpqZUsFkJxS6UIq4EvYS46CUExRPkBL2HFM/gIdxIFq4Ff2JNia3JzBefR+bzuZ1Op+E+y/q6Fd/GSe8qijZH1lpfN00uADdZNt5NDh7GJ8dng2HKxvYOBtB6jctms/5S3ePpxeWklw69tZE1IqKqrIxT81U1d4PReCJJ338HXBVURCCokhelMZW467YTt9pi1rUntPCHYJ0ljiyubMJh0yJFuZSk26ENjufPFV0CCeAUfLEo8V7pRBHWOMJvBc5Q+xpnIf8pl+fvi1Lztw9zlO6T7sWw9jy9vPIPUL1kPErau3YAAAAASUVORK5CYII='
|
|
13
|
+
fx = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABB0lEQVR4nB2LP0sCcQBA3/2Uzugu8E4IoT9cSYhUENFWYSA1FFTQ4hK5SENNDW19hoYcImhvaGgLguYgcIk0haLOE7wrNGzo5A4v9K3vPWknmwt0LYrrunieTygkAAm300EIQTg5nWB3e5O39w9s54t4fISEYfBZq/H4VETIsoxp1ftyJpWkR7lSZXFhnsFIhLBtOxR9n1KliqZFeX4po+saZ4VLTMtC9M61TJrTk2OarR9WV5bIpJfZ2ljH8zxEw3EovVaZm01xd//AsKpwfXNLLKaTmDSQ9vJHwWE+x3ezRbv9i6oqTBkTmLU65xdXSNn9g0CWB2jYDuNjo/y5Lqoy1A+63S7/GeVj+5KBt3UAAAAASUVORK5CYII='
|
|
14
|
+
nk = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAHYYAAB2GAV2iE4EAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAADrmlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4NCjx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NTc3MiwgMjAxNC8wMS8xMy0xOTo0NDowMCAgICAgICAgIj4NCgk8cmRmOlJERiB4bWxuczpyZGY9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkvMDIvMjItcmRmLXN5bnRheC1ucyMiPg0KCQk8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtbG5zOnhtcE1NPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvbW0vIiB4bWxuczpzdFJlZj0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL3NUeXBlL1Jlc291cmNlUmVmIyIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ0MgMjAxNCAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo4RUJCOThFRkQ5RTcxMUU1QTcyN0EzQzFGN0YzNjcwNCIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo4RUJCOThGMEQ5RTcxMUU1QTcyN0EzQzFGN0YzNjcwNCI+DQoJCQk8eG1wTU06RGVyaXZlZEZyb20gc3RSZWY6aW5zdGFuY2VJRD0ieG1wLmlpZDo4RUJCOThFREQ5RTcxMUU1QTcyN0EzQzFGN0YzNjcwNCIgc3RSZWY6ZG9jdW1lbnRJRD0ieG1wLmRpZDo4RUJCOThFRUQ5RTcxMUU1QTcyN0EzQzFGN0YzNjcwNCIvPg0KCQk8L3JkZjpEZXNjcmlwdGlvbj4NCgkJPHJkZjpEZXNjcmlwdGlvbiB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyI+PHRpZmY6T3JpZW50YXRpb24+MTwvdGlmZjpPcmllbnRhdGlvbj48L3JkZjpEZXNjcmlwdGlvbj48L3JkZjpSREY+DQo8L3g6eG1wbWV0YT4NCjw/eHBhY2tldCBlbmQ9J3cnPz7hg4LgAAAA3UlEQVQoU2NgIAAYGRgYGP7//8/4cHak44//jJfY//3T+S0vdpz/zXvZZ8+/yTIzMDAwhP490ir479ecx89/H2X69nH123vvn/1592HVy6+/rjNeyrPR+/jz927mf3+5v7Pz+vH8/DSXm51Z7NW3v8ec5p11Zfr44fOSv5+/MDB+/fqP4dOnoJ9fvjN++/TtE/P376IMDAwMzL5qYt8Y/v5+ws383+ndb8ajLP9+2T36xZ7O/f9HTIyhFCMjzLVLIw28Hv8ROarA8sL64Ve+wyocX+R//mOQQfIQdgAAAghnscY2ZXIAAAAASUVORK5CYII='
|
|
15
|
+
he = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAHYYAAB2GAV2iE4EAAACsSURBVChTY2CAgv///zPC2DA+uhh28IiBxZ5FQTWdS8tUgktOLZlHTq2eR05tAoeschxYwTsGpnpRVq6bDMxscxhYue4xsPM8ZBIULWVg57nAwM6uyPCPg0N+DwPD4zgGhnMyDAz32BgY7jAwMJQxMDCeMmdgCAeb8oeBIeEfA4PjMgaG3FQGhnlODIzHHBgY18UzMARjur6+numfuDj3f0lJLogA1DvoCmEAAJVNNF84URktAAAAAElFTkSuQmCC'
|
|
16
|
+
mb = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAABE0lEQVR4nAEIAff+AQAAAACHttAxAQ0Kjd7o7ToDAQH/GREOxcDT4HK+cErSAYy70DHs/AG6tNjoFNzn6gD5+fwAQjElAIE/JuqWxdZEBBwVD5RSIhsUnsTV/JBRNwT9/v4AjcDU/DsgOxbW6RqUArra5zf39vb/KRwTBKPN3gBMKhwA3unyBJHE2P/i7/U6Auvz+ACkzt4AaTkmAN/u9AARCQYAQysdALXW5ADl8fYAAi4bEMbD5vQBMxoR/CwYEACVxtkAfUMr/PoECAEZDwrFAiAPCmwpEAjq/gcKBAUDAQCQwtcAMSIZBDkbDukIBAJtAmU5KNIP//1F1ePrvScWD/hSLR/4uNXkvAHz9kZ+RS/T0LpzUht5tWAAAAAASUVORK5CYII='
|
|
17
|
+
nx = 'data:image/png;base64,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'
|
|
18
|
+
sf = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA8ElEQVR4nBXBv0rDQADA4d/lz1lqmlREECUIFTq4FBeHDA6uPkRfwwfxBRx19gmk4GZBBAcjCAUrWEkaTUzucjnx+0R6kzQboZDCb7AWdNmiMo3KLHUmlCcDR/Z2DujvJXRth6kNqqgoXufo6kk6lpzwcEr7fUrx7POTugh9xPZkilE5jh9MsJ2mreaUi0eKdIa7CUIogjjB8wcnyOiM0rmkH+8ih8dY1gTxOeHoA69eLRCOxBvsE21JOmVo8gy3N6T+fMNbPdwiwzG6XFJ/vWC1xY9GvN9dsZxdI+4vxo3rtxLH8q/TFvPbYhqL0Z76AydWbEnTqqOqAAAAAElFTkSuQmCC'
|
|
19
|
+
sj = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAMAAADz0U65AAAAIGNIUk0AAHomAACAhAAA+gAAAIDoAAB1MAAA6mAAADqYAAAXcJy6UTwAAAC9UExURY2NjYWGhoeIiYiIiIiIiYWFhoODg4mKillZWYSEhFBMS3x7e0xIR3Bsa0E+PldWVi4wMT4/Px0eHiQkJA8PDwoMDAsMDAsMDAsLCw0NDWxqaHZtZnBrZ2dnZ25qZ21oZJ94XtWNWr6DXG9mYpp2X6p5V6JwVNJ9TsN4UXBgWZhtVaxuTZBbR6xiRMpoQKlgQ6JfRZ5cQHFGN6dOMqFOM5lMM6tPMmZBNCYlJS8mIywlJCglJC8mJCMhIf////64+awAAAAadFJOU1SosLCwokSyl7ugup+6n7ugr5RLlJmYmZA8Hg7dEgAAAAFiS0dEPklkAOMAAAAHdElNRQfpDBESHCL8f1a2AAAAUElEQVQI12NgYGRiYmZhZWNgl5KWkZWT52DgVFBUUlZR5WLgVlPX0NTS5mHg1dHV0zcw5GPgNzI2MTUzF2AQtLC0sraxFWIQFhEVExOXkAQA4WIHfGNBCckAAAAldEVYdGRhdGU6Y3JlYXRlADIwMjUtMTItMTdUMTg6Mjg6MjgrMDA6MDDR5B2HAAAAJXRFWHRkYXRlOm1vZGlmeQAyMDI1LTEyLTE3VDE4OjI4OjI4KzAwOjAwoLmlOwAAACh0RVh0ZGF0ZTp0aW1lc3RhbXAAMjAyNS0xMi0xN1QxODoyODozNCswMDowMPym7g4AAAAASUVORK5CYII='
|
|
20
|
+
sl = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA/ElEQVR4nE3PrUpDYRzH8d/z5tnRozugImIYgjAwGY5egGUG64JRkxgWvIFV0zCIwVsQLLYhWgSDLizJiowVFUHZdJ7zvP7Ftu8NfPgybOwvImcFet0C6FhMtrYTSQg1Ru/id3W7sfTxmc3rQpeE4gk8BZJiigF1kWYLe9rSGZEvR4o/AvRAxBLB8SObzXVqXb/tBjFdJjOCtliJI/U6fDo/CQSwf4ozIM2OGrm2xyGEClQCReO76tZmTabZYcsHmnHOfSvJ+8axCiNtlJDtztdNkLmxbViyEIx7669YxPPlZG44uD99wXs9ltqNbvF8aSbvBgBH9WAWMZX+AJIYacQLryqFAAAAAElFTkSuQmCC'
|
|
21
|
+
wd = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAA90lEQVR4nC3OsS5DUQAG4P8/Pb2kiS4mliaEkMYgTBiQiMVk6C6RsHmAxuoFbHTzCmIR9QSWLko6kIiQCnqHq+fec84vEt8TfMS/5s3jniFf36uD9sTH6Fg9rQ8aDQY2r7trhJmFUY1kW9I4gF0I9wGuZUOM04x+B4o9EvMSZ0D1EVWYkklsnn51TFIOhJ2DwgaN6QiqgsbRh00rseu9J1WsUngGOBmhSvaZnZwdbA1MkWfrwQ2PvXMvwbk7n7taLPKppFpe+cvb8DN8gi09RGmkbEv9GHQLqQZi+bB19WZDdN+WlYskRe/0aNsBaO+fXy4ZxEWKC7/R+XkmFbstdAAAAABJRU5ErkJggg=='
|
|
22
|
+
wx = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAACKADAAQAAAABAAAACAAAAACVhHtSAAAAcUlEQVQYGWNgYGD4B8S4wD+mf7y2jEDZ/0CsiKRKEiT2j9cGLMQGJH8DMUwhyEQQGyTGBcRg3T+hNMgkGP4EYsN0AdlgAHMPE0wARMN0XEASBLHB4ixQQUGgg94xMjCCBMEyTJ8PiwKZr0F8kDW4ACMASI8hUcBfWMAAAAAASUVORK5CYII='
|
|
@@ -24,6 +24,11 @@ def render_centered_html(inner_content):
|
|
|
24
24
|
--secondary: #6c757d;
|
|
25
25
|
--code-bg: #f8f9fa;
|
|
26
26
|
--spacing: 1rem;
|
|
27
|
+
--info-border: #2d5a2d;
|
|
28
|
+
--setup-border: var(--primary);
|
|
29
|
+
--divider-color: #dee2e6;
|
|
30
|
+
--btn-subtle-bg: #e9ecef;
|
|
31
|
+
--btn-subtle-border: #ced4da;
|
|
27
32
|
}
|
|
28
33
|
@media (prefers-color-scheme: dark) {
|
|
29
34
|
:root {
|
|
@@ -32,8 +37,50 @@ def render_centered_html(inner_content):
|
|
|
32
37
|
--card-bg: #242526;
|
|
33
38
|
--card-shadow: rgba(0, 0, 0, 0.5);
|
|
34
39
|
--code-bg: #2c2f33;
|
|
40
|
+
--info-border: #4a8c4a;
|
|
41
|
+
--setup-border: var(--primary);
|
|
42
|
+
--divider-color: #444;
|
|
43
|
+
--btn-subtle-bg: #444;
|
|
44
|
+
--btn-subtle-border: #666;
|
|
35
45
|
}
|
|
36
46
|
}
|
|
47
|
+
/* Info box styling */
|
|
48
|
+
.info-box {
|
|
49
|
+
border: 1px solid var(--info-border);
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
padding: 16px;
|
|
52
|
+
margin-bottom: 24px;
|
|
53
|
+
}
|
|
54
|
+
.info-box h3 {
|
|
55
|
+
margin-top: 0;
|
|
56
|
+
color: var(--info-border);
|
|
57
|
+
}
|
|
58
|
+
/* Setup box styling */
|
|
59
|
+
.setup-box {
|
|
60
|
+
border: 1px solid var(--setup-border);
|
|
61
|
+
border-radius: 8px;
|
|
62
|
+
padding: 16px;
|
|
63
|
+
margin-bottom: 24px;
|
|
64
|
+
}
|
|
65
|
+
.setup-box h3 {
|
|
66
|
+
margin-top: 0;
|
|
67
|
+
color: var(--setup-border);
|
|
68
|
+
}
|
|
69
|
+
/* Subtle button styling */
|
|
70
|
+
.btn-subtle {
|
|
71
|
+
background: var(--btn-subtle-bg);
|
|
72
|
+
color: var(--fg-color);
|
|
73
|
+
border: 1px solid var(--btn-subtle-border);
|
|
74
|
+
padding: 6px 12px;
|
|
75
|
+
border-radius: 4px;
|
|
76
|
+
cursor: pointer;
|
|
77
|
+
}
|
|
78
|
+
/* Divider styling */
|
|
79
|
+
.section-divider {
|
|
80
|
+
margin-top: 20px;
|
|
81
|
+
padding-top: 20px;
|
|
82
|
+
border-top: 1px solid var(--divider-color);
|
|
83
|
+
}
|
|
37
84
|
/* Logo and heading alignment */
|
|
38
85
|
h1 {
|
|
39
86
|
display: inline-flex;
|
|
@@ -159,7 +206,7 @@ def render_centered_html(inner_content):
|
|
|
159
206
|
text-decoration: none;
|
|
160
207
|
}
|
|
161
208
|
a:hover {
|
|
162
|
-
|
|
209
|
+
|
|
163
210
|
}
|
|
164
211
|
/* footer styling */
|
|
165
212
|
footer {
|